PHP WebSocket ZMQ-聊天操作-向特定用户发送数据
我正在做一个基于Symfony 2.2.11的PHP项目,我安装了与以下教程相关的socketo,以使我的聊天脚本正常工作 ServerCommand.php//启动WebSocket服务器的命令行代码PHP WebSocket ZMQ-聊天操作-向特定用户发送数据,php,symfony,websocket,zeromq,ratchet,Php,Symfony,Websocket,Zeromq,Ratchet,我正在做一个基于Symfony 2.2.11的PHP项目,我安装了与以下教程相关的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); $
$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();
将消息添加到数据库后:
messagescocontroller.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));
.....
/**
* 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);
}
聊天服务:
Chat.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));
.....
/**
* 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
}
);
所以每一次都很完美,当我发送一条新消息时,它会进入DB,然后它会在聊天页面上登陆
问题:
数据到达JS脚本所在的任何地方,结果是所有用户都可以获得相同的记录消息
提问:
如何在特定用户页面中创建数据区域
谢谢您在后端使用的是
棘轮
,对吗
因此,这里有一个非常好的例子,说明您需要:
您应该将客户端连接保存在$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),例如,如果可能的话,您可以在上投稿,您当然可以帮助,非常感谢您提前查看了此答案吗?是的,我看了,我们不是用同样的方法工作的,他的聊天类扩展了MessageComponentInterface引用,而我的聊天类扩展了WampServerInterface引用