2016-07-29 1 views
0

Я ищу, какой вызов ajax или jQuery api будет получать потоковые данные от клиента php libevent.ajax вызов для получения непрерывных/потоковых данных от php libevent client

Libevent Клиент будет получать данные из Libevent Server.c

Server.c

/* For socket functions */ 
#include <sys/socket.h> 
#include <event2/event.h> 
#include <event2/buffer.h> 
#include <event2/bufferevent.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/un.h> 
#include <event2/listener.h> 

#include <arpa/inet.h> 

#include <signal.h> 

#define MAX_LINE 16384 

void readcb(struct bufferevent *bev, void *ctx) 
{ 
    /* This callback is invoked when there is data to read on bev. */ 
    struct evbuffer *input = bufferevent_get_input(bev); 
    int len = evbuffer_get_length(input); 
    char *data; 
    data = malloc(len); 
    evbuffer_copyout(input, data, len); 
    free(data); 
} 

void writecb(struct bufferevent *bev, void *ctx) 
{ 
    //here i will be checking my database and memcache new updates 
    //it will wait randomly between 2 to 6 seconds to check again 

    char *message = "Continuous message from your Server"; 
    evbuffer_add(bufferevent_get_output(bev), message, strlen(message)); 
    sleep(2+rand()%4); 
} 

void errorcb(struct bufferevent *bev, short error, void *ctx) 
{ 
    if (error & BEV_EVENT_EOF) { 
    /* connection has been closed, do any clean up here */ 
    /* ... */ 
    } else if (error & BEV_EVENT_ERROR) { 
    /* check errno to see what error occurred */ 
    /* ... */ 
    } else if (error & BEV_EVENT_TIMEOUT) { 
    /* must be a timeout event handle, handle it */ 
    /* ... */ 
    } 
    bufferevent_free(bev); 
} 

void do_accept(evutil_socket_t listener, short event, void *arg) 
{ 
    struct event_base *base = arg; 
    struct sockaddr_storage ss; 
    socklen_t slen = sizeof(ss); 
    int fd = accept(listener, (struct sockaddr*)&ss, &slen); 
    if (fd < 0) { 
    perror("accept"); 
    } else if (fd > FD_SETSIZE) { 
    close(fd); 
    } else { 
    struct bufferevent *bev; 
    evutil_make_socket_nonblocking(fd); 
    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); 
    bufferevent_setcb(bev, readcb, writecb, errorcb, NULL); 
    bufferevent_setwatermark(bev, EV_READ, 0, MAX_LINE); 
    bufferevent_enable(bev, EV_READ|EV_WRITE); 
    } 
} 

void run(void) 
{ 
    evutil_socket_t listener; 
    struct sockaddr_un sun; 
    int len; 
    struct event_base *base; 
    struct event *listener_event; 
    base = event_base_new(); 

    if (!base) 
    return; /*XXXerr*/ 

    listener = socket(AF_UNIX, SOCK_STREAM, 0); 
    evutil_make_socket_nonblocking(listener); 

#ifndef WIN32 
{ 
    int one = 1; 
    setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); 
} 
#endif 

    memset(&sun, 0, sizeof(sun)); 

    sun.sun_family = AF_UNIX; 
    strcpy(sun.sun_path, "/tmp/influenzaunix.sock"); 

    unlink(sun.sun_path); 
    len = strlen(sun.sun_path) + sizeof(sun.sun_family); 
    if (bind(listener, (struct sockaddr *)&sun, len) < 0) { 
    perror("bind"); 
    return; 
    } 

    if (listen(listener, 16)<0) { 
    perror("listen"); 
    return; 
    } 

    listener_event = event_new(base, listener, EV_READ|EV_PERSIST, do_accept, (void*)base); 

    event_add(listener_event, NULL); 

    event_base_dispatch(base); 
} 

int main(int c, char **v) 
{ 
    setvbuf(stdout, NULL, _IONBF, 0); 

    run(); 
    return 0; 
} 

Составитель с

gcc -o Server Server.c -levent 

Затем Client.php является

<?php 
define('MAX_LINE', '16384'); 
define('CHUNK_SIZE', '128'); 

class Server extends Thread{ 
    public function run(){ 
     passthru('./Server'); 
    } 
} 

class Client extends Thread{ 

    public function readcb($bev, $ctx) 
    { 
     $tmp = array(); 

     while (1) { 
      $data = event_buffer_read($bev,CHUNK_SIZE); 
      $size = strlen($data); 
      if($size <= 0) 
       break; 
      $tmp[] = $data; 
     } 
     $data = implode($tmp); 
     echo $data."\n"; //display the data received from server 
     flush(); /*flush the data so that an ajax call will be receiving it*/ 
    } 

    public function eventcb($bev, $events, $ptr) 
    { 
    } 

    public function run() 
    { 
     $sockpath = '/tmp/influenzaunix.sock'; 
     $socket = stream_socket_client("unix://{$sockpath}",$errorNumber,$errorString,STREAM_CLIENT_CONNECT); 
     stream_set_blocking($socket, 0); //non-blocking mode 

     if (($socket) === FALSE){ 
      echo 'connect error'; 
     } 
     else{ 
      $message = "Send data about this topic"; //subscribing to get data about a topic 
      $bev = event_buffer_new($socket, array($this,"readcb"), NULL, array($this,"eventcb")); 

      $base = event_base_new(); 

      if($base !== FALSE) 
      { 
       event_buffer_base_set($bev,$base); 
       event_buffer_enable($bev, EV_READ|EV_WRITE); 
       event_buffer_write($bev, $message, strlen($message)); 
      } 

      event_base_loop($base); 
     } 
    } 
} 

$server = new Server(); 
$server->start(); 

sleep(3); /*let's wait for 3 seconds to make sure Server is ready to accept connection*/  

$client = new Client(); 
$client->start(); 
?> 

Client.php может выполняться только с помощью режима CLI с RunClient.php ниже

<?php 
passthru('php Client.php'); 
?> 

я с вызовом, чтобы придумать с вызовом AJAX или JQuery Ajax вызова будет получать данные из раскрасневшиеся Client.php , Вызов JQuery ajax или Ajax не может вызвать Client.php напрямую, вместо этого он вызовет RunClient.php. Пожалуйста, я очень признателен, если кто-то попытается предоставить вызов ajax или JQuery ajax, чтобы получать сброшенные данные.

+0

Что происходит, когда вы вызываете RunClient.php в браузере? он отвечает немедленно с пустой страницей или браузер ждет чего-то, что никогда не приходит в случае, если ваш сервер испускает события? –

+0

при запуске в браузере он ждет локального хоста, пока не истечет время ожидания, и появится 504 Gateway Timeout. Хотя я не намерен запускать его в браузере. Он будет вызван только вызовом ajax. –

ответ

0

Тестирование браузером - это первый шаг, чтобы понять, что происходит.

Я не знаком с классом PHP темы, но то, что может происходить в том, что при вызове

passthru('php Client.php'); 

в RunClient.php, вызов блокируется, ожидая php Client.php закончить.

С Client.php - это сервер с длительным сроком службы (он в принципе никогда не заканчивается), вы никогда не получите ответ, даже если вы использовали flush() внутри Client.php.

Вы можете попробовать

<?php 
$fp = fopen('php Client.php'); 
fpassthru($fp); 
?> 

, чтобы увидеть, если вы видите результаты в браузере (убедитесь, что ваш сервер выдает данные)

После этого вы говорите, что вы хотите использовать Ajax. Вам нужно понять, что вызов ajax немного похож на вызов браузера: это механизм request-> response, а не механизм потоковой передачи.

вы можете попробовать, может быть, с помощью тега сценария в вашей HTML странице

<script src='RunClient.php'/> 

и изменить ваш Client.php, вместо

echo $data."\n"; 

с

echo "document.write('<span>".$data."</span>');\n"; 

и простых DATAS без кавычек. Если он работает, вам нужно будет избежать данных, чтобы испущенная строка была действительной javascript.

Конечно, это прототип. Все зависит от того, что вы хотите сделать.

Возможно, вы также захотите использовать веб-порты для потоковой передачи. Протокол предназначен для потоковой передачи. cf https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API

+0

Спасибо. я пробовал все, но не мог получить данные. вы правы, если Client.php является долговременным сервером (он никогда не заканчивается), и невозможно получить ответ даже с использованием флеша внутри Client.php. Я действительно хочу предоставить длинный сервер опроса для обновления веб-страницы с новыми данными. Как-то не хотят использовать Websockets, поскольку он не будет работать в некоторых браузерах. Libevent или Socket.io были бы лучшим вариантом. Можете ли вы предложить лучший взлом с этим решением, которое у меня есть? –

Смежные вопросы