使用Websocket和Pusher显示连接用户的登录状态


Show the connecting user login status using Websocket and Pusher

我第一次使用Pusher构建聊天室web应用程序。我读了很多Pusher的文档来了解它是如何工作的。我的问题更多的是关于机制,而不是关于代码。

所以我想做的是,当用户连接并加入presence-channel时,它允许我显示谁在线。我想为用户显示一个状态标志(绿色=在线,黄色=离开)(如Skype),所有登录的用户都可以实时看到状态之间的变化。

我已经看到了这个问题,如果我理解的话,每个用户都必须加入一个私有通道才能更好地管理其客户端事件。那么,我如何管理private-channel的更改状态事件并将其显示在presence-channel中,或者我如何在两个通道之间进行通信?

您不需要单独的通道来构建用户状态。

现在实现这一点的最佳方法是使用idle.js之类的东西来检测用户状态,然后在呈现频道(可能是client-status-updated)上触发带有用户状态信息的事件(例如{"user_id":SOME_ID, "status":"away"})。

注意:对于客户端事件,事件名称上需要client-前缀

您可以使用客户端事件来执行此操作,也可以在现有的呈现频道上执行此操作。但是,您应该注意,通过使用客户端事件,这意味着任何经过身份验证的用户都可能触发状态事件,并建议它完全针对另一个用户。因此,通过服务器这样做会更安全,服务器可以设置甚至来自正在设置状态的用户的信息。

然而,我并没有真正看到"黑客"设置另一个用户状态的好处。

下面是一个使用呈现通道和客户端事件的示例。

<script src="libs/idle.js"></script>
<script src="//js.pusher.com/2.2/pusher.min.js"></script>
<script>
var pusher = new Pusher(APP_KEY);
var presence = pusher.subscribe('presence-online');
// Basic online/offline
presence.bind('pusher:subscription_succeeded', function(members) {
  members.each(addUser);
});
presence.bind('pusher:member_added', addUser);
presence.bind('pusher:member_removed' removeUser);
function addUser(member) {
  // Online - add to UI
}
function removeUser(member) {
  // Offline - remove from UI
  // Consider doing this in a setTimeout
  // in case the user comes back online again
}
// User state
var idle = new Idle({
  onHidden:    function() { sendUserStatus('hidden'); },
  onVisible:   function() { sendUserStatus('visible'); },
  onAway:      function() { sendUserStatus('away'); },
  onAwayBack:  function() { sendUserStatus('hidden'); },
  awayTimeout: 30000 //away with 30 seconds of inactivity
}).start();
function sendUserStatus(status) {
  var userStatusUpdate = {
    "user_id": presence.members.me.id, // current user unique ID
    "status": status
  };
  presence.trigger('client-status-updated', userStatusUpdate);
}
presence.bind('client-status-updated', function(update) {
  var userId = update.user_id;
  var status = user.status;
  // Update UI to reflect user status
});
</script>