如何绑定ZeroMQ套接字与棘轮网络套接字库做的PHP应用程序的实时应用程序? [英] How to bind ZeroMQ socket with Ratchet web-socket library to make real time application for php application?

查看:138
本文介绍了如何绑定ZeroMQ套接字与棘轮网络套接字库做的PHP应用程序的实时应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这个涉及的WebSocket,瑞奇和ZeroMQ全区只是一个初学者。

I am just a beginner in this whole area involving websocket, Ratchet and ZeroMQ.

要我基本的了解:

的WebSocket 的东西,有助于创建服务器和客户机之间的连接断开。

websocket is something that helps to create open connection between server and client.

棘轮是一个基于PHP库,使用PHP的核心的Socket函数创建一个PHP接口框架,使我们能够缓解PHP套接字编程。

Ratchet is a PHP based library which uses PHP's core Socket functions to create a PHP socket framework allowing us to ease in PHP socket programming.

ZeroMQ 是一个套接字库,帮助非棘轮应用程序(其它PHP脚本)在棘轮套筒和网络接口发送数据。

ZeroMQ is a socket library that helps non-ratchet application to (other PHP script) send the data over Ratchet Socket and web-socket.

我下面的棘轮发现关于世界你好'和'推',但他们两人的教程似乎是不完整的,只教你如何只用控制台的工作。我还发现棘例如在GitHub上,但它是不正确的记录。我一直在寻找一个完整的例子(有专门的HTML页面和JavaScript)

I am following the tutorial found in ratchet about 'hello world' and 'pusher' but both of them seems to be incomplete and only teaches how to work with console only. I have also found ratchet-example in github but it is not properly documented. I was looking for a complete example (with a dedicated html page and javascript)

下面是code我的工作:这是我想提出一个Ajax请求的控制器的方法之一。这个方法将创建一个新的职位(可以说)。我想动态更新后的列表中的多个客户端的通过广播浏览器/带ZeroMq的帮助推。

Below is the code I am working on: This is one of the method of the controller which I am making a Ajax request for. This method will create a new post (lets say). I want to update the list of post dynamically in multiple client's browser by broadcasting/pushing with the help of ZeroMq.

在一个控制器的方法:

public function create_new_post(){
    // ------
    // code to create a new post.
    // -------

    // After creating a post
    $response = [
        'new_post_title'    => $title,
        'post_id'           => $id
    ];

    $context = new ZMQContext();
    $socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
    $socket->connect("tcp://localhost:8000");
    $socket->send(json_encode($response));

}

推文件:

use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;

class Pusher implements WampServerInterface{

     public function onPostEntry($data){
         // Data that were sent by ZeroMQ through create_new_post() method
         $entry_data = json_decode($data);      

         // AND AFTER THIS, I DONT HAVE CLUE OF WHAT TO DO NEXT !!             

     }
}

Shell脚本来运行服务器:

Shell Script to run server:

require dirname(__DIR__) . '/vendor/autoload.php';

$loop   = React\EventLoop\Factory::create();
$pusher = new MyApp\Pusher;

// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:8000'); 
$pull->on('message', array($pusher, 'onBidEntry'));

// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server($loop);
$webSock->listen(8080, '0.0.0.0'); 
$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
        new Ratchet\WebSocket\WsServer(
            new Ratchet\Wamp\WampServer(
                $pusher
            )
        )
    ),
    $webSock
);

$loop->run();

shell脚本只是告诉它将但是我怎么会提到我的路线服务于8080端口。可以说,我想只在页面'的mysite / allposts'的开放连接。此外,这将是我必须在客户端(JavaScript文件),以及如何通过客户端更新特定的DOM对象来接受这些新的数据写剧本。

Shell script only tells that it will serve in port 8080, however how would I mention my routes. Lets say I want the open connection in only the page 'mysite/allposts'. Also, what would be the script that I have to write in client side (a javascript file) and how to receive these new data by client side updating a particular DOM object.

推荐答案

我跟着你正在谈论的例子。他们似乎没有残缺给我,但我明白你的意思。棘轮是一个服务器端脚本,只允许你写一个实现的WebSockets服务,这是能够倾听ZMQ消息。您将启动棘轮脚本的命令行上,并把它作为平行于Apache的一个服务运行。

I followed the examples you are talking about. They didn't seem incomplete to me, but I understand what you mean. Ratchet is a server side script and just allows you to write a service that implements websockets and that is able to listen to ZMQ messages. You will launch your Ratchet script on the command line and it runs as a service in parallel to Apache.

这是所有独立于的WebSocket的客户端。就像他们推荐,我用Autobahn.js在客户端上。此库实现了WAMP协议。它简化了客户端code到最大。

This is all independent from the client side of the websocket. Like they recommend, I used Autobahn.js on the client side. This library implements the WAMP protocol. It simplifies the client side code to the max.

您code的问题是,类推实现WampServerInterface 不具有公共职能onPostEntry 。这个类必须实现 WampServerInterface ,这意味着它必须至少有以下功能:

The problem with your code is, that class Pusher implements WampServerInterface does not have a public function onPostEntry. This class has to implement the WampServerInterface, this means it must have at least these functions :

  • onSubscribe(ConnectionInterface $康恩,$主题)
  • onUnSubscribe(ConnectionInterface $康恩,$主题)
  • 的OnOpen(ConnectionInterface $康恩)
  • 的OnClose(ConnectionInterface $康恩)
  • onPublish(ConnectionInterface $康恩,$主题,$事件,数组$排除,数组$符合条件的
  • 的onError(ConnectionInterface $康恩,\异常$ E)
  • onZMQMessage($ jsondata)

可以有其他更先进的功能,如通话上的客户端荷兰国际集团远程过程。

There can be others for more advanced features, like calling remote procedures on clients.

在发送方(ZMQ消息),把这个code:

On the sender side (ZMQ message), put this code:

$zmq = new ZMQWrapper;
$zqm->publish('posts', $response);

class ZMQWrapper {
    function __construct(){
        $this->context = new ZMQContext();
        $this->socket = $this->context->getSocket(ZMQ::SOCKET_PUSH);
        $this->socket->setSockOpt(ZMQ::SOCKOPT_LINGER, 500);
        $this->socket->connect("tcp://127.0.0.1:" . ZMQ_PORT);
    }
    function publish($topic, $msg){
        $data = ['topic' => "mb.$topic", 'msg' => $msg];
        $this->socket->send(json_encode($data), ZMQ::MODE_DONTWAIT);
    }
}

在推杆文件把成才这样的:

In the pusher file put someting like:

public function onSubscribe(ConnectionInterface $conn, $topic) {
    $log = $this->getLogger();
    $topicId = $topic->getId();
    $log->info(sprintf('A client subscribed to %s', $topicId));
    // you could broadcast that user x joined the discussion
}
public function onUnSubscribe(ConnectionInterface $conn, $topic) {
    $log = $this->getLogger();
    $topicId = $topic->getId();
    $log->info(sprintf('A client unsubscribed from %s', $topicId));
    // you could broadcast that user x leaved the discussion
}
public function onOpen(ConnectionInterface $conn) {
    $log = $this->getLogger();
    $log->info(sprintf('Client %d connected', $conn->resourceId));
    $this->clients[$conn->resourceId] = array(); // this will allow you to save state information of the client, you can modify in onSubscribe and onUnsubscribe
    // clients will contain the list of all clients
}
public function onClose(ConnectionInterface $conn) {
    $log = $this->getLogger();
    $log->info(sprintf('Client %d disconnected', $conn->resourceId));
    // you could broadcast that user x leaved the discussion
}
public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
    $log = $this->getLogger();
    $topicId = $topic->getId();
    $log->info(sprintf('Client %d published to %s : %s', $conn->resourceId, $topicId, json_encode($event)));
    foreach($topic->getIterator() as $peer){
        if(!in_array($peer->WAMP->sessionId, $exclude)){
            $peer->event($topicId, $event);
        }
    }
}

最后是在客户端上。如果用户打开页面的mysite / allposts ,在JavaScript你包括 autobahn.js 。变量 AB 下的WebSocket将提供。然后,您做的:

The last piece is on the client. If a user opens the page mysite/allposts, in javascript you include autobahn.js. The websocket will be made available under the variable ab. You then do:

在打开的页面:

var currentSession;
ab.connect(
    Paths.ws,
    function(session) { // onconnect
        currentSession = session
        onWsConnect(session)
    },
    function(code, reason, detail) {// onhangup
        onWsDisconnect(code, reason, detail)
    },{
        maxRetries: 60,
        retryDelay: 2000,
        skipSubprotocolCheck: true
    }
)
currentSession.subscribe('posts', onPostReceived)

function onPostReceived(topic, message){
    //display the new post
}

在关闭的页面:

currentSession.unsubscribe(topic)

您注意,我一直都非常一般。这让我有几种类型由同一系统处理的消息。所不同的是ZMQ消息和 currentSession.subscribe 的参数。

You note that I kept everything very general. This allows me for having several types of messages handled by the same system. What differs are the ZMQ messages and the arguments of currentSession.subscribe.

我我的实现,我也跟踪的记录在打开连接的用户,但我剥离这部分的code。

I my implementation, I also keep track of the logged in users that opened the connection, but I stripped this part of the code.

我希望这会帮助你。

这篇关于如何绑定ZeroMQ套接字与棘轮网络套接字库做的PHP应用程序的实时应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆