php - 使用 socket.io 和 redis 进行实时通知

标签 php node.js redis socket.io symfony

在我的网络应用程序 (symfony3) 中,我尝试集成一个实时通知系统。 我选择使用此配置来完成此操作: 服务器 Node 服务器redis 套接字.io socket.io-php-emitter(用于直接从 php 发出通知的 php 适配器)

app.js(服务器 Node )

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');

测试 Controller

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()
    ));
}

客户端 View

$(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;
    });
});

好的,这个简单的测试工作正常:当我从正确的 View 提交表单时,会向该页面上的所有客户端显示一条通知。

1- 现在我希望一个用户只能向另一个用户发送通知(当用户评论帖子时,帖子的作者会收到通知)。我该怎么做?

2- 如果作者未连接,我如何保存通知以在作者重新连接时显示?

最佳答案

对于您的第一个问题,在您以某种方式维护的服务器中,例如 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。每次用户连接时,您都必须在数据库中搜索他是否有任何未决通知,并发送给他。这可以为少量用户完成,而不会导致大量的计算使用,但这无法扩展。 为此,我将:

  • 在 redis 中搜索连接的用户
  • 如果未连接,将新通知保存到数据库中。
  • 当用户再次连接时,向 API 发出标准 HTTP 请求并将所有未决通知发送给他,处理它们并进行必要的更改。

希望对您有所帮助!

编辑

我忘了解释你是如何在连接上传递数据的。在客户端只需执行:var socket = io('http://216.157.91.131:8080/', { userId: "myUserId"});。很简单,不是吗?

关于php - 使用 socket.io 和 redis 进行实时通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40914636/

相关文章:

redis - 1 Redis 哨兵与多个 Redis 哨兵?

node.js - MongoDB 架构 : store id as FK or whole document

javascript - Heroku Node.js 应用程序崩溃 |模块.js :340 error

node.js - socket.io-redis 不断抛出 NOAUTH 错误

PHP-FPM 和 Nginx : 502 Bad Gateway

javascript - Node JS 能否提示 HTML 页面发生变化?

redis - 如何访问 Redis 日志文件

php - 使用 Instagram 基本显示 API 时出现 "Invalid platform app"错误

php - 在 PHP 中解析维基百科标记的最佳方法是什么?

php - 从 Laravel 本地存储中的特定目录中删除文件