所以,我正在运行一个 Ratchet (php) websocket 服务器,它有多个连接多个 Ratchet 应用程序 (MessageComponentInterfaces) 的路由:
//loop
$loop = \React\EventLoop\Factory::create();
//websocket app
$app = new Ratchet\App('ws://www.websocketserver.com', 8080, '0.0.0.0', $loop);
/*
* load routes
*/
$routeOne = '/example/route';
$routeOneApp = new RouteOneApp();
$app->route($routeOne, $routeOneApp, array('*'));
$routeTwo = '/another/route';
$routeTwoApp = new AnotherApp();
$app->route($routeTwo, $routeTwoApp, array('*'));
从这里我绑定(bind)一个 ZMQ 套接字,以便能够接收从在普通 apache 服务器上运行的 php 脚本发送的消息。
// 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:5050'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($routeOneApp, 'onServerMessage'));
最后,服务器启动:
//run
$loop->run();
只要我只将一个 Ratchet 应用程序绑定(bind)到 ZMQ 套接字,这一切都很好。但是,我希望能够分别将消息推送到两个 Ratchet 应用程序。为此,我想将两个 ZMQ 套接字绑定(bind)到不同的路由,例如:
$pullOne->bind('tcp://127.0.0.1:5050' . $routeOne); // Binding to 127.0.0.1 means the only client that can connect is itself
$pullOne->on('message', array($routeOneApp, 'onServerMessage'));
和
$pullTwo->bind('tcp://127.0.0.1:5050' . $routeTwo); // Binding to 127.0.0.1 means the only client that can connect is itself
$pullTwo->on('message', array($routeTwoApp, 'onServerMessage'));
但是,这会在绑定(bind)第二个套接字时导致来自 ZMQ 的错误消息,指出给定地址已在使用中。
所以问题是,有没有其他方法可以通过 ZMQ 套接字使用路由?
或者我应该使用其他方式来区分单独的 Ratchet 应用程序的消息,如果是这样,什么是一个好的解决方案?
我想过绑定(bind)到 2 个不同的端口,但认为这将是一个非常丑陋的解决方案?!
最佳答案
通常在 TCP 数据包中由 4 个元组标识(发送方 ip、发送方端口、接收方 ip、接收方端口)。
当传入的数据包到达网络层时,通过查看接收方 ip 和端口将其转发到适当的应用程序。如果您对两个应用程序使用相同的配对,则该层将无法决定在连接进入时将其发送给谁。
一种解决方案是绑定(bind)单个连接并编写一个查看传入内容的通用处理程序,然后决定(我假设你有一些逻辑)区分不同实例的传入连接,然后调用相应的处理程序。处理程序可以获取连接对象并可以处理连接。
如果您的两个实例是相同的,并且谁收到请求并不重要,那么您可以将新连接随机转发到任何处理程序。
编辑:无论应用程序类型(Racket/ZMQ 等)如何,我都试图回答这个问题,因为您试图解决的问题是任何网络应用程序共同的基本问题。
对于这种情况,由于您有两个应用程序正在运行并希望在同一个端口上监听,因此您可以拥有一个通用处理程序,它可以查看请求 URL 并将连接转发到适当的处理程序。
可以使用获取请求 URL
$querystring = $conn->WebSocket->request->getQuery();
现在客户端可以使用
ws://localhost:5050/app1
and
ws://localhost:5050/app2
您的不同应用现在可以分别处理这些连接。
关于php - 从 PHP 脚本向多个 Ratchet Websocket 应用程序发送消息(通过 ZMQ Socket),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42095900/