在我的网络应用程序(symfony3)中,我尝试集成实时通知系统。 我选择使用此配置完成此操作: 服务器NodeJS 服务器redis socket.io socket.io-php-emitter(php adaptater直接从php发出通知)
app.js(服务器节点)
var app = require('express')();
var http = require('http').Server(app);
var server = require('http').createServer();
var io = require('socket.io').listen(server);
var redis = require('socket.io-redis');
io.sockets.on('connection', function (socket) {
console.log('user connected!');
});
io.adapter(redis({ host: 'localhost', port: 6379 }));
server.listen(8081, 'myhost');
测试控制器
public function testAction(Request $request)
{
$notification = 'A message has been received by the server!<br />'
$form = $this->createFormBuilder()->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
$redis = new \Redis();
$redis->connect('127.0.0.1', '6379');
$emitter = new SocketIO\Emitter($redis);
$emitter->emit('notification', $notification);
$response = new JsonResponse();
$response->setData(array(
'notification' => $notification
));
return $response;
}
return $this->render('@PMPlatform/Test/test.html.twig', array(
'form' => $form->createView()
));
}
客户端视图
$(document).ready(function() {
// Getting socket
var socket = io('http://myhost:8081');
// Listening on notification from server
socket.on('notification', function (data) {
$('.server').append('qsfdqsfdqsdfqsfdqsfd');
});
// Listener on form submit event
$(document).on('submit', '.form', function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '/app_dev.php/test',
data: $(this).serialize(),
success : function(response){
$('.client').append('A message has been sent to server from this client!<br />');
},
error : function(response){
console.log('Something went wrong.');
},
cache: false
});
return false;
});
});
好的,这个简单的测试工作正常:当我从正确的视图提交表单时,会向该页面上的所有客户端显示通知。
1-现在我希望一个用户能够仅向另一个用户发送通知(当用户评论帖子时,帖子的作者收到通知)。我怎么能这样做?
2-如果作者没有连接,我怎么能保存通知,以便在作者连接回来时显示它?
答案 0 :(得分:1)
对于您的第一个问题,在您以某种方式维护的服务器中,例如redis,通过套接字列出所有已连接的客户端。但是,这里的关键是在连接到服务器时传递用户的id。现在,您的socket.io服务器中的用户已完全通过其ID识别。
io.sockets.on('connection', function (socket) {
console.log(socket);
});
如果查看连接附带的套接字对象,那么您将拥有刚刚连接的用户的id。
然后,当您想要向该用户发送通知时,您只需要在redis中搜索要发送通知的用户ID的相应套接字。当您实例化发射器$emitter = new SocketIO\Emitter($redis);
时,您将不得不在redis中搜索该特定套接字 - 用户ID搜索redis -
对于第二个问题,我不会为这个功能进入websockets。每次用户连接时,如果他有任何待处理通知,则必须在数据库中搜索,然后发送给他。这可以针对少量用户完成,而不会导致繁重的计算用量,但这不会扩展。 为此,我将:
希望它有所帮助!
修改强>
我忘了解释如何在连接上传递数据。在客户端上只需执行:var socket = io('http://216.157.91.131:8080/', { userId: "myUserId" });
。很容易,不是吗?