2016-07-29 111 views
0

我正在寻找哪个ajax调用或jquery api从php libevent客户端接收流数据。ajax调用从php libevent客户端获取连续/流数据

的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

当在浏览器中运行时,它会等待localhost,直到它超时并出现504网关超时。虽然我不打算在浏览器中运行它。它只会被ajax调用调用。 –

回答

0

使用浏览器进行测试是了解发生的第一步。

我不熟悉PHP Thread类,但什么可能发生的情况是,当你调用

passthru('php Client.php'); 
在RunClient.php

,呼叫阻塞,等待php Client.php完成。

由于Client.php是一个长时间运行的服务器(它基本上永远不会结束),因此您在Client.php中使用flush()时永远不会得到一个答案,即使很难。

你可能想尝试

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

看到,如果你在浏览器中看到的结果(请确保您的服务器发出的数据)

之后,你提到要使用AJAX。您需要了解ajax调用有点像浏览器调用:它是一个请求 - >响应机制,而不是流式机制。

你可以用一个脚本标签也许尝试在HTML页面中

<script src='RunClient.php'/> 

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

和简单的DATAS修改Client.php,而不是

echo $data."\n"; 

没有引号。如果它有效,你将需要转义数据,以便发出的字符串是有效的JavaScript。

当然,这是一个原型。这完全取决于你想要做什么。

您可能还想使用websockets进行流式传输。该协议是为流媒体制作的。 cf https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API

+0

谢谢。我尝试了一切,但无法获得数据。你是对的,只要Client.php是一个长时间运行的服务器(它基本上不会结束),即使在Client.php中使用flush也不可能得到答案。我实际上想要提供一个长轮询服务器来更新一个包含新数据的网页。不知何故,不想使用Websockets,因为它不适用于某些浏览器。 Libevent或Socket.io将是最好的选择。请你可以建议我在这里使用这个解决方案的最佳解决方案? –

相关问题