in JavaScript

基于Socket.IO 的私聊

引子

Socket.IO Real-Time Web Application Development最近听到这么一个问题:Socket.IO 怎么实现私聊?换个提法:怎么定位到人(端),或者说怎么标识到连接,而不是依赖每个连接的socket.id。好问题。

在 Socket.IO Real-Time Web Application Development 的指引下,形成了如下思路:

  1. 服务端在每个用户初次进入系统时,产生session_id
  2. 服务端强制用户输入昵称,与session_id对应
  3. 服务端的Socket.IO在连接时,可以拿到socket.request.headers.cookie,从这个cookie中解析出session_id,将socket 连接与 Web框架的context中的session_id 对应上
  4. 在服务端使用一个数组来保存如上三者产生的对应关系:[{name, session_id, socket} , ...]
  5. 有了对应关系的数组,就能定位到人并分清 [我] 和 [其他人],也便能够利用保存的socket 进行私聊

有了思路,就可以动手实践了:

Server端

ES6 的生成器太好用,做 Node Web 就从 koa 开始吧。那么,我的 package.json 看起来就会有这些依赖的库:

用户列表

思路中提到的用户列表,就是一个简单的数组:[{name, session_id, socket} , ...],围绕它的操作也特别简单(socketHandler:

Session存储

koa-session 这个库提供了 session 存储功能,它的使用非常简单:

此外,koa-session会在Web request的cookie中会附上一个 koa:sess的session_id 标识串,那么,在 socket.io 的事件侦听中,我们可以这么用它:

用户登录

所谓的登录,就是让用户输入一个昵称,将它与session_id对应上,并存储到前述用户数组中。假设我们的路由路径为 /chat,登录action路径为/chat/login,那么这个路由看起来是这样:

广播和私聊消息处理

客户端

在连接到服务端后,客户端会定时拉取其他人的列表:

对应的,服务端会有一个这样的接口:

运行效果

在三个不同的浏览器中跑起来,宛如上世纪90年代火得不行的聊天室 🙂

Chat Room Demo

源码

完整的源码放在我的Github上:https://github.com/rockdragon/socketchat,想让它跑起来,你需要把 Node 升到 0.11.14(因为用到了 Co V4 ),当然,README.MD里有详细的设置说明。

打赏作者
您的支持将激励我继续创作!

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

Write a Comment

Comment