【问题标题】:PHP WebSocket ZMQ - Chat Operation - Send data to specific userPHP WebSocket ZMQ - 聊天操作 - 向特定用户发送数据
【发布时间】:2014-02-05 23:44:22
【问题描述】:

我正在开发一个基于 Symfony 2.2.11 的 PHP 项目,我安装了与以下教程 http://socketo.me/docs/install 相关的 socketo 以使我的聊天脚本正常工作。

ServerCommand.php // 启动 WebSocket 服务器的命令行代码

$oLoop = Factory::create();

    // Listen for the web server to make a ZeroMQ push after an ajax request
    $oContext = new Context($oLoop);
    $oPull = $oContext->getSocket(\ZMQ::SOCKET_PULL);
    // LET IT 127.0.0.1
    $oPull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
    $oPull->on('message', array($oChat, 'onMessage'));

    // Set up our WebSocket server for clients wanting real-time updates
    $oWebSock = new Server($oLoop);
    $oWebSock->listen(7979, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect
    $webServer = new IoServer(
        new HttpServer(
            new WsServer(
                new WampServer(
                    $oChat
                )
            )
        ),
        $oWebSock
    );

    $oLoop->run();

将消息添加到数据库后: MessagesController.php

....
// This is our new stuff
        $oContext = new \ZMQContext();
        $oSocket = $oContext->getSocket(\ZMQ::SOCKET_PUSH, 'PushMe');
        $oSocket->connect("tcp://mydomain:5555");

        $aData = array(
            'topic'         => 'message',
            'sUsername'     => $oUserCurrent->getUsername(),
            'sMessage'      => $sMessage
        );

        $oSocket->send(json_encode($aData));
.....

聊天服务: Chat.php

/**
 * A lookup of all the topics clients have subscribed to
 */
public function onSubscribe(ConnectionInterface $conn, $topic) 
{
    // When a visitor subscribes to a topic link the Topic object in a  lookup array
    $subject = $topic->getId();
    $ip = $conn->remoteAddress;

    if (!array_key_exists($subject, $this->subscribedTopics)) 
    {
        $this->subscribedTopics[$subject] = $topic;
    }

    $this->clients[] = $conn->resourceId;

    echo sprintf("New Connection: %s" . PHP_EOL, $conn->remoteAddress);

}

/**
 * @param string JSON'ified string we'll receive from ZeroMQ
 */
public function onMessage($jData) 
{
    $aData = json_decode($jData, true);

    var_dump($aData);

    if (!array_key_exists($aData['topic'], $this->subscribedTopics)) {
        return;
    }

    $topic = $this->subscribedTopics[$aData['topic']];

    // This sends out everything to multiple users, not what I want!!

    // re-send the data to all the clients subscribed to that category
    $topic->broadcast($aData);
}

接收数据的JS代码: messages.html.twig

var conn = new ab.Session(
                    'ws://mydomain:7979' // The host (our Ratchet WebSocket server) to connect to
                  , function() {            // Once the connection has been established
                        conn.subscribe('message', function(topic, data) 
                        {
                            console.log(topic);
                            console.log(data);
                        });
                    }
                  , function() {            // When the connection is closed
                        console.warn('WebSocket connection closed');
                    }
                  , {                       // Additional parameters, we're ignoring the WAMP sub-protocol for older browsers
                        'skipSubprotocolCheck': true
                    }
                );

所以一切工作正常,当我发送一条新消息时,它会转到数据库,然后它会降落在聊天页面上。

问题: 数据落到JS脚本的任何地方,结果是所有用户都可以得到相同的记录消息

询问: 如何让数据登陆特定用户页面?

谢谢

【问题讨论】:

标签: php symfony websocket zeromq ratchet


【解决方案1】:

你在后端使用Ratchet,对吧?

所以,这里有很好的案例示例:

http://socketo.me/docs/hello-world

您应该将您的客户端连接保留在 $clients 属性中(而不是资源 id 的集合!)。因此,您可以从该集合中选择一个元素并仅向该客户端发送消息。

例子:

public function onSubscribe(ConnectionInterface $conn, $topic) 
{
    // When a visitor subscribes to a topic link the Topic object in a  lookup array
    $subject = $topic->getId();
    $ip = $conn->remoteAddress;

    if (!array_key_exists($subject, $this->subscribedTopics)) 
    {
        $this->subscribedTopics[$subject] = $topic;
    }

    $this->clients[] = $conn; // you add connection to the collection

    $conn->send("Hello new user!"); // you send a message only to this one user
}

【讨论】:

  • 刚试了下还是不行,还是会广播到所有打开接收页面的浏览器页面。例如,如果可能的话,我想将消息发送到特定的用户名帐户(Symfony)
  • 能否请您在stackoverflow.com/questions/29576033/… 上投稿,您一定可以提供帮助,非常感谢提前
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 2020-05-06
  • 2016-02-16
  • 2014-04-17
  • 1970-01-01
相关资源
最近更新 更多