2

情况:

有一个长时间运行的任务需要异步启动。这个任务的细节并不是那么重要(基础是要配置多个虚拟机和复杂的网络设置),这是由将在不同服务器上运行的 python 脚本处理的。我们决定使用 WebSockets 来进行 Web 服务器和客户端之间的来回通信,并且我可以在那里进行双向通信。Web 服务器将向另一台服务器发送请求,并在每台机器启动并运行时接收来自 python 脚本的 HTTP POST 通知,并在整个网络启动时收到最终的 HTTP POST。

所有这些都有效。我们在 Web 服务器上使用的框架是 Laravel 4,而 Web 套接字服务器是使用Ratchet构建的,并在 artisan 命令中实现。我的问题是我不确定如何将 HTTP POST 从 python 脚本中继到 Laravel 控制器到 WebSocket 服务器,以便它反过来可以将该信息中继回客户端。

下面是 RatchetMessageComponentInterface::onMessage方法的实现,它使用观察者模式来通知任何订阅的侦听器消息事件。

// 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 服务器?

4

1 回答 1

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(<--这是我最后选择的)

如果有人想出不同的想法/更好的客户端库来使用,我会暂时保留这个问题。

于 2014-03-10T20:19:40.887 回答