将请求路由到Laravel Controller以运行WebSocket服务器

时间:2014-03-10 15:23:22

标签: php websocket laravel-4 ratchet

情况:

需要异步启动长时间运行的任务。这项任务的细节并不是那么重要(基础是要配置多个虚拟机和复杂的网络设置),这是由将在不同服务器上运行的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服务器?

1 个答案:

答案 0 :(得分:3)

这里的答案似乎是我需要在PHP中创建一个WebSocket客户端,它将向WebSocket服务器发送消息,就像用JavaScript编写的客户端一样。对于任何对这个问题感兴趣的感兴趣的观众,我能够找到一些用PHP编写的WebSocket客户端:

  1. https://github.com/gabrielbull/php-websocket-client
  2. https://github.com/Devristo/phpws
  3. https://github.com/symbiose/php-websocket-client(< - 这是我结束的那个)
  4. 如果有人想出一个不同的想法/更好的客户端库,我会暂时搁置这个问题。