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

Show the connecting user login status using Websocket and Pusher

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

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

我看过 this question,如果我理解,每个用户都必须加入一个私人频道才能更好地管理其客户事件。那么如何管理 private-channel 的状态变化事件并将其显示在 presence-channel 中,或者如何在两个通道之间进行通信?

您不需要单独的渠道来建立用户状态。

现在实现此目的的最佳方法是使用 idle.js 之类的方法检测用户状态,然后在存在通道(可能是 client-status-updated)上触发一个事件,其中包含有关用户状态的信息(例如 {"user_id":SOME_ID, "status":"away"})。

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

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

但是,我并没有真正看到 "hack" 设置另一个用户状态的好处。

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

<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>