PHP 实时聊天 +Redis +Pub/Sub +WebSockets (+NodeJS) [英] Real time chat in PHP +Redis +Pub/Sub +WebSockets (+NodeJS)

查看:64
本文介绍了PHP 实时聊天 +Redis +Pub/Sub +WebSockets (+NodeJS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想开发与频道的实时聊天,这是我的需求:

I want to develop real time chat with channels and these are my needs:

  • 用于管理站点的 PHP 后端
  • Redis 作为会话和数据的主存储
  • Pub/Sub 仅向频道感兴趣的用户发送消息
  • 一个用于发送和接收消息的 WebSocket 连接.
  • (可选)NodeJS 使用很棒的 npm 包,例如 timesync 或 socket.io

我看到了两种不同的架构来实现这一点:

I see two different architectures to achieve this:

  • 使用 Socket.io

使用 Crossbar.io

这些是我的问题:

These are my questions:

  1. 我应该选择哪种架构?为什么?
  2. 关键是无法从客户端获取用户 ID,因为它可能格式错误.所以在第一个架构中,我认为在每个套接字消息上我应该附加来自 cookie 的 PHPSESSID 值,并在服务器端从 Redis 检索 PHP 会话.我是对的还是有更好的方法来获取用户 ID?
  3. 我想知道在第二种架构中获取用户 ID 是否可以采用不同的方式?

我选择了 Crossbar.io,因为它非常强大,可以实时交流许多不同语言的应用程序.在研究了例子之后,我想出了这个:

I choosed Crossbar.io, cause it is very powerful and allows to communicate many different language applications in real time. After studying examples, I come up with this:

  • 每次登录时,用户都会在数据库中生成密钥.

  • On every login user have generated secret key in database.

PHP 客户端 (Thruway) 连接到 Crossbar 服务器并注册自定义 WAMP-CRA 身份验证器

PHP client (Thruway) connect to Crossbar server and register custom WAMP-CRA authenticator

用户的浏览器连接到 Crossbar 服务器并受到挑战.Secret 和 auth_id(用户 ID)是在页面加载时从 DB 加载的,所以它可以完成挑战并发送响应.

User's browser connect to Crossbar server and is challenged. Secret and auth_id (user id) are loaded from DB with page load, so it can accomplish challenge and send response.

PHP 身份验证器在数据库中搜索用户提供的机密和 id 等于 auth_id.如果有,那么它成功认证会议.现在我们可以相信 auth_id 是真实的用户 ID.

PHP authenticator search in DB for user with provided secret and id equal to auth_id. If there is, then it successfully authenticate session. Now we can trust that auth_id is real user id.

这些是我的问题:

  1. 如何在订阅时获取 auth_id?

  1. How I can get auth_id on subscribe?

我还添加了 cookie 身份验证,并在身份验证后记住浏览器.但是当我查看 Chrome DevTools 时,本地存储中没有任何 cookie 或值.即使在清除缓存后,Crossbar 仍然记得我的浏览器.我想知道这怎么可能?

I also added cookie authentication and browser is remembered after authentication. But when I look in Chrome DevTools there is any cookie nor value in local storage. Even after clearing cache my browser is still remember by Crossbar. I wonder how it is possible?

编辑 2:

也许我被误解了,但主要问题是选择合适的架构并获得可信任的用户 ID.没有人注意,所以我奖励了赏金,之后我被否决了.我阅读了很多关于实时应用程序的内容,最终决定使用 Crossbar.io,因此我编辑了与其相关的问题.然后人们开始投票,提出另一种架构,但并没有真正回答我的问题.毕竟我自己设法做到了并提出了我的答案.

Maybe I was misunderstood, but the main question was choosing appropriate architecture and getting trusted user id. There was no attention so I awarded bounty and after that I was downvoted. I read a lot about real-time apps and finally decided to use Crossbar.io, so I edited question to be related to it. Then people started upvoting, proposing another architectures, but not really answering my questions. After all I managed to do it myself and presented my answer.

推荐答案

关于获取用户 ID:

我看到的每个实时聊天示例都是从客户端获取 id.它是不安全的,因为客户端很容易操纵它,所以我需要找到另一种方法.在阅读了 WAMP 规范后,我终于明白了我不仅必须在应用程序中验证用户身份,还必须在 Crossbar.io 中验证用户身份.我选择了动态 WAMP-CRA 方法并实现如下:

About getting user id:

Every real-time chat examples which I saw, was getting id from client. It is unsafe, because client easily can manipulate it, so I needed to find another method. After reading WAMP specs I finally figured out that I have to authenticate user not only in app, but also in Crossbar.io. I choosed the dynamic WAMP-CRA method and implemented as following:

  • PHP 应用程序连接到 Crossbar 服务器并注册自定义身份验证器(类似于 示例)
  • 用户登录应用程序后,会为他生成密钥并保存在数据库中.注销后,密钥被销毁.
  • 工作流程:

  • PHP app connect to Crossbar server and register custom authenticator (similar to example)
  • After user login in app there is generated secret key for him and saved in database. After logout, key is destroyed.
  • Workflow:

  1. 每个加载的页面都包含从数据库加载的用户标识密钥:

<script>
    auth_id = '<?php echo $user->id ?>';
    secret_key = '<?php echo $user->secret_key ?>';
</script>

  • 用户浏览器连接到 Crossbar.io 服务器并从自定义身份验证器获得质询响应.
  • 它使用key计算签名并与auth_id一起发送到Crossbar.io服务器
  • Authenticator 从 DB secret 获取提供的 auth_id 并计算签名.然后比较签名,如果它们相等,则身份验证成功.
  • 现在 auth_id 包含用户 ID,我们可以信任它的值.现在您可以参考订阅时如何获取 auth_id?"部分.
  • User browser connect to Crossbar.io server and get response with challenge from custom authenticator.
  • It calculate signature using key and send along with auth_id to Crossbar.io server
  • Authenticator gets from DB secret for provided auth_id and calculate signature. Then signatures are compared and if they are equal then authentication is successfull.
  • Now auth_id contain user id and we can trust its value. Now you can refer section 'How I can get auth_id on subscribe?'.
  • 如何在订阅时获取 auth_id?

    How I can get auth_id on subscribe?

    默认情况下,发布者和订阅者彼此不了解,但是文档显示有选项可以通过配置呼叫者身份的披露来更改它.然后就可以从回调详情中获取auth_id:

    By default publishers and subscribers does not have any knowledge about each other, but documentation show there is option to change it by configuring disclosure of caller identity. Then you can get auth_id from callback details:

    • PHP:

    • PHP:

    $onEvent = function ($args, $argsKw, $details, $publicationId) use ($session) {
        $auth_id = $details->publisher_authid;
        ...
    }
    $session->register('com.example.event', $onEvent);
    

  • JS:

  • JS:

    function on_event(args, kwargs, details) {
        auth_id = details['publisher_authid'];
        ...
    }
    session.subscribe('com.example.event', on_event);
    

  • 我还添加了 cookie 身份验证,并在身份验证后记住浏览器.但是当我查看 Chrome DevTools 时,本地存储中没有任何 cookie 或值.即使在清除缓存后,Crossbar 仍然记得我的浏览器.我想知道这怎么可能?

    I also added cookie authentication and browser is remembered after authentication. But when I look in Chrome DevTools there is any cookie nor value in local storage. Even after clearing cache my browser is still remember by Crossbar. I wonder how it is possible?

    首先,清除缓存和硬重新加载不会删除 cookie.当我问这个问题时,有任何 cookie 出现,但今天我可以看到 cbtid:前两天有Chrome更新,所以可能是之前版本的bug造成的.

    First of all, clearing cache and hard reload does not remove cookies. When I was asking this question there was any cookie presented, but today I can see cbtid: There was Chrome update two days ago, so maybe this was caused by bug in previous version.

    这篇关于PHP 实时聊天 +Redis +Pub/Sub +WebSockets (+NodeJS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆