PHP +Redis +Pub/Sub +WebSockets (+NodeJS) 实时聊天
Real time chat in PHP +Redis +Pub/Sub +WebSockets (+NodeJS)
我想开发与频道的实时聊天,这些是我的需求:
- PHP backend to manage site
- Redis as session and data primary storage
- Pub/Sub to send messages only to channel's interested users
- one WebSocket connection with which the messages will be send and received.
- (optional) NodeJS to use great npm packages like timesync or socket.io
我看到了两种不同的架构来实现这一点:
和Socket.io
和Crossbar.io
这些是我的问题:
- 我应该选择哪种架构,为什么?
- 关键是无法从客户端获取用户ID,因为它可能格式不正确。所以在第一个架构中,我认为我应该在每个套接字消息上附加来自 cookie 的 PHPSESSID 值,并在 sever-side 上从 Redis 检索 PHP session。我是对的还是有更好的方法来获取用户 ID?
- 我想知道在第二个架构中获取用户 ID 是否可以以不同的方式完成?
编辑:
我选择了Crossbar.io,因为它非常强大,可以实时交流多种不同语言的应用程序。研究示例后,我想出了这个:
每个登录用户都在数据库中生成密钥。
PHP 客户端(Thruway)连接到 Crossbar 服务器并注册自定义 WAMP-CRA 身份验证器
用户的浏览器连接到 Crossbar 服务器并受到挑战。 Secret 和 auth_id (user id) 是通过页面加载从数据库中加载的,所以它
可以完成质询并发送响应。
PHP 身份验证器在数据库中搜索提供的密码和 ID 等于 auth_id 的用户。如果有,则认证成功
session。现在我们可以相信 auth_id 是真实的用户 ID。
这些是我的问题:
如何订阅才能获得 auth_id?
我还添加了cookie认证,认证后会记住浏览器。但是当我查看 Chrome DevTools 时,本地存储中没有任何 cookie 或值。即使在清除缓存后,Crossbar 仍然记得我的浏览器。我想知道这怎么可能?
编辑2:
也许我被误解了,但主要问题是选择合适的架构并获得受信任的用户 ID。没有人注意所以我奖励了赏金,然后我被否决了。我阅读了很多关于 real-time 应用程序的文章,最后决定使用 Crossbar.io,所以我编辑了与之相关的问题。然后人们开始投票,提出另一种架构,但并没有真正回答我的问题。毕竟我自己设法做到了并提出了我的答案。
PHP Ratchet 是我通过 WebSockets 用于实时通信的最佳实现之一。它基于用于多个在线游戏应用程序和聊天应用程序的 ZMQ 套接字。
以下示例将帮助您快速入门,并将回答您有关 auth_id 和订阅的问题:
http://socketo.me/docs/hello-world
架构概述:
http://socketo.me/docs/push#networkarchitecture
我建议为每个对话创建单独的连接(toppics),因为它不会真正影响性能,并且会为每个聊天添加额外的安全层。
我深深点亮了 Streamer,NASA 使用它来为每个 second.The 最可靠的实时消息传递服务器转发大量数据。
为网络、手机、平板电脑、桌面和物联网应用程序提供动力。
针对 Web 和移动设备优化的数据流。
Lightstreamer 支持多种形式的实时消息传递。它足够灵活,可用于任何场景,包括关键任务应用程序。
► 实时数据推送和 Web Sockets
► 应用内消息和推送通知
► 带有扇出广播和一对一消息的发布订阅
► 防火墙和代理友好
► 自适应带宽限制
关于在订阅上获得 auth_id 的第一个问题,只需监视连接订阅,然后在成功连接后存储层。
此外,不推荐使用 cookie,使用 jwt.JSON Web 令牌是一种开放的行业标准 RFC 7519 方法,用于在两个 parties.Authentication 之间安全地表示声明是每个应用程序的重要组成部分之一。安全性总是在变化,evolving.JWT 帮助您解决 concern.Since 它是无状态的问题。
关于获取用户id:
我看到的每个 real-time 聊天示例都是从客户端获取 ID。这是不安全的,因为客户端很容易操纵它,所以我需要找到另一种方法。阅读 WAMP specs 后,我终于明白我不仅要在应用程序中验证用户身份,而且还要在 Crossbar.io 中验证用户身份。我选择了动态 WAMP-CRA 方法并实现如下:
- PHP 应用程序连接到 Crossbar 服务器并注册自定义身份验证器(类似于 example)
- 用户登录应用程序后,会为他生成密钥并保存在数据库中。注销后,密钥被销毁。
工作流程:
每个加载的页面包含 用户 ID 和 密钥 从 db:
加载
<script>
auth_id = '<?php echo $user->id ?>';
secret_key = '<?php echo $user->secret_key ?>';
</script>
- 用户浏览器连接到 Crossbar.io 服务器并从自定义身份验证器获得质询响应。
- 它使用密钥计算签名并与auth_id一起发送到Crossbar.io 服务器
- Authenticator 从 DB secret 获取提供的 auth_id 并计算签名。然后比较签名,如果它们相等则认证成功。
- 现在 auth_id 包含用户 ID,我们可以相信它的值。现在你可以参考'How I can get auth_id on subscribe?'.
部分
答案:
How I can get auth_id on subscribe?
默认情况下,发布者和订阅者彼此不了解,但 documentation 显示可以通过配置调用者身份的披露来更改它。然后你可以从回调详情中得到auth_id:
PHP:
$onEvent = function ($args, $argsKw, $details, $publicationId) use ($session) {
$auth_id = $details->publisher_authid;
...
}
$session->register('com.example.event', $onEvent);
JS:
function on_event(args, kwargs, details) {
auth_id = details['publisher_authid'];
...
}
session.subscribe('com.example.event', on_event);
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造成的。
我想开发与频道的实时聊天,这些是我的需求:
- PHP backend to manage site
- Redis as session and data primary storage
- Pub/Sub to send messages only to channel's interested users
- one WebSocket connection with which the messages will be send and received.
- (optional) NodeJS to use great npm packages like timesync or socket.io
我看到了两种不同的架构来实现这一点:
和Socket.io
和Crossbar.io
这些是我的问题:
- 我应该选择哪种架构,为什么?
- 关键是无法从客户端获取用户ID,因为它可能格式不正确。所以在第一个架构中,我认为我应该在每个套接字消息上附加来自 cookie 的 PHPSESSID 值,并在 sever-side 上从 Redis 检索 PHP session。我是对的还是有更好的方法来获取用户 ID?
- 我想知道在第二个架构中获取用户 ID 是否可以以不同的方式完成?
编辑:
我选择了Crossbar.io,因为它非常强大,可以实时交流多种不同语言的应用程序。研究示例后,我想出了这个:
每个登录用户都在数据库中生成密钥。
PHP 客户端(Thruway)连接到 Crossbar 服务器并注册自定义 WAMP-CRA 身份验证器
用户的浏览器连接到 Crossbar 服务器并受到挑战。 Secret 和 auth_id (user id) 是通过页面加载从数据库中加载的,所以它 可以完成质询并发送响应。
PHP 身份验证器在数据库中搜索提供的密码和 ID 等于 auth_id 的用户。如果有,则认证成功 session。现在我们可以相信 auth_id 是真实的用户 ID。
这些是我的问题:
如何订阅才能获得 auth_id?
我还添加了cookie认证,认证后会记住浏览器。但是当我查看 Chrome DevTools 时,本地存储中没有任何 cookie 或值。即使在清除缓存后,Crossbar 仍然记得我的浏览器。我想知道这怎么可能?
编辑2:
也许我被误解了,但主要问题是选择合适的架构并获得受信任的用户 ID。没有人注意所以我奖励了赏金,然后我被否决了。我阅读了很多关于 real-time 应用程序的文章,最后决定使用 Crossbar.io,所以我编辑了与之相关的问题。然后人们开始投票,提出另一种架构,但并没有真正回答我的问题。毕竟我自己设法做到了并提出了我的答案。
PHP Ratchet 是我通过 WebSockets 用于实时通信的最佳实现之一。它基于用于多个在线游戏应用程序和聊天应用程序的 ZMQ 套接字。
以下示例将帮助您快速入门,并将回答您有关 auth_id 和订阅的问题:
http://socketo.me/docs/hello-world
架构概述:
http://socketo.me/docs/push#networkarchitecture
我建议为每个对话创建单独的连接(toppics),因为它不会真正影响性能,并且会为每个聊天添加额外的安全层。
我深深点亮了 Streamer,NASA 使用它来为每个 second.The 最可靠的实时消息传递服务器转发大量数据。 为网络、手机、平板电脑、桌面和物联网应用程序提供动力。
针对 Web 和移动设备优化的数据流。 Lightstreamer 支持多种形式的实时消息传递。它足够灵活,可用于任何场景,包括关键任务应用程序。 ► 实时数据推送和 Web Sockets ► 应用内消息和推送通知 ► 带有扇出广播和一对一消息的发布订阅 ► 防火墙和代理友好 ► 自适应带宽限制
关于在订阅上获得 auth_id 的第一个问题,只需监视连接订阅,然后在成功连接后存储层。 此外,不推荐使用 cookie,使用 jwt.JSON Web 令牌是一种开放的行业标准 RFC 7519 方法,用于在两个 parties.Authentication 之间安全地表示声明是每个应用程序的重要组成部分之一。安全性总是在变化,evolving.JWT 帮助您解决 concern.Since 它是无状态的问题。
关于获取用户id:
我看到的每个 real-time 聊天示例都是从客户端获取 ID。这是不安全的,因为客户端很容易操纵它,所以我需要找到另一种方法。阅读 WAMP specs 后,我终于明白我不仅要在应用程序中验证用户身份,而且还要在 Crossbar.io 中验证用户身份。我选择了动态 WAMP-CRA 方法并实现如下:
- PHP 应用程序连接到 Crossbar 服务器并注册自定义身份验证器(类似于 example)
- 用户登录应用程序后,会为他生成密钥并保存在数据库中。注销后,密钥被销毁。
工作流程:
每个加载的页面包含 用户 ID 和 密钥 从 db:
加载<script> auth_id = '<?php echo $user->id ?>'; secret_key = '<?php echo $user->secret_key ?>'; </script>
- 用户浏览器连接到 Crossbar.io 服务器并从自定义身份验证器获得质询响应。
- 它使用密钥计算签名并与auth_id一起发送到Crossbar.io 服务器
- Authenticator 从 DB secret 获取提供的 auth_id 并计算签名。然后比较签名,如果它们相等则认证成功。
- 现在 auth_id 包含用户 ID,我们可以相信它的值。现在你可以参考'How I can get auth_id on subscribe?'. 部分
答案:
How I can get auth_id on subscribe?
默认情况下,发布者和订阅者彼此不了解,但 documentation 显示可以通过配置调用者身份的披露来更改它。然后你可以从回调详情中得到auth_id:
PHP:
$onEvent = function ($args, $argsKw, $details, $publicationId) use ($session) { $auth_id = $details->publisher_authid; ... } $session->register('com.example.event', $onEvent);
JS:
function on_event(args, kwargs, details) { auth_id = details['publisher_authid']; ... } session.subscribe('com.example.event', on_event);
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
: