情况:
需要异步启动长时间运行的任务。这项任务的细节并不是那么重要(基础是要配置多个虚拟机和复杂的网络设置),这是由将在不同服务器上运行的python脚本处理的。我们决定使用WebSockets在Web服务器和客户端之间来回通信,我在那里进行双向通信。 Web服务器将向其他服务器发送请求,并在每台计算机启动并运行时从python脚本接收HTTP POST通知,并在整个网络启动时返回最终的HTTP POST。
所有这一切都有效。我们在Web服务器上使用的框架是Laravel 4,Web套接字服务器是使用Ratchet构建的,并在artisan命令中实现。我的问题是我不确定如何将HTTP POST从python脚本中继到Laravel控制器到WebSocket服务器,以便它可以将该信息转发回客户端。
下面是Ratchet的MessageComponentInterface::onMessage
方法的实现,该方法使用Observer模式通知任何订阅的侦听器消息事件。
// Class: SocketMessenger
public function onMessage(ConnectionInterface $from, $msg) {
$respondTo = null;
foreach($this->_clients as $client) {
if($client->resourceId == $from->resourceId) {
$respondTo = $client;
break;
}
}
$msg = json_decode($msg, true);
if(!$respondTo || !$msg || !isset($msg['type'])) {
echo 'Malformed Socket Message Received, Rejecting.';
return;
}
$type = $msg['type'];
// Notify any subscribed listeners with this message type of the
// incoming message. Any response received will be relayed back to
// the client.
if(isset($this->_listeners[$type])) {
foreach( $this->_listeners[$type] as $listener ) {
$response = $listener->notify( $respondTo, $msg );
if($response) {
$respondTo->send( $response );
}
}
}
}
WebSocket服务器是在服务提供者中构建的,如下所示:
// Class: SocketServiceProvider
$app->bind( 'Ratchet\MessageComponentInterface', function( $app, $params ) {
$port = $params && isset($params[0]) ?
$params[0] : self::DEFAULT_PORT
;
$messenger = new SocketMessenger;
// Setup the Ratchet Server.
$server = IoServer::factory(
new HttpServer(
new WsServer(
$messenger
)
),
$port
);
// Subscribe socket listeners to the socket messenger
$messenger->subscribe( new TopologyMessageListener, TopologyMessageListener::TYPE );
return $server;
} );
有没有办法将请求发送到Laravel控制器并在命令控制器的方法被命中时通知正在运行的WebSocket服务器?
答案 0 :(得分:3)
这里的答案似乎是我需要在PHP中创建一个WebSocket客户端,它将向WebSocket服务器发送消息,就像用JavaScript编写的客户端一样。对于任何对这个问题感兴趣的感兴趣的观众,我能够找到一些用PHP编写的WebSocket客户端:
如果有人想出一个不同的想法/更好的客户端库,我会暂时搁置这个问题。