0%

利用 socket.io 实现消息实时推送

场景

当发生了用户被点赞、评论、关注等操作时,需要由服务器向用户实时地推送一条消息。

实现方式

  • 后台Node.js

    后端推送消息的处理流程

  • 在 Node 服务器建立一个用户信息和 socket id 的映射表,因为同一用户可能打开了多个页面,所以他的 socket id 可能存在多个值。当用户建立连接时,往其中添加值;用户断开连接后,删除相应值。

  • 当 Java 后台存在需要推送的消息时,会向 Node 服务器的 /api 路径 post 一条消息,其中包括用于标识用户的 tokenId 和其它数据。

  • Node 服务器接收到 post 请求后,对请求内容进行处理。根据 tokenId 找出与该用户对应的 socket id,socket.io 会根据 id 来向用户推送消息。

对用户信息的处理

方便起见,这里只用一个数组保存用户信息,实际工作中可以根据需要放入数据库中保存。

1
global.users = []; // 记录下登录用户的tokenId, socketId

当用户登录时,client 会向 server 发送 user_login 事件,服务器接收到后会做如下操作:

1
2
3
4
socket.on('user_login', function(info) {
const { tokenId, userId, socketId } = info;
addSocketId(users, { tokenId, socketId, userId });
})

addSocketId() 会向 users 数组中添加用户信息,不同用户通过 tokenId 进行区分,每个用户有一个 socketIds 数组,保存可能存在的多个 socketId。该函数的具体代码可见 src/utils.js 文件。

同理,还有一个 deleteSocketId() 函数用于删除用户信息,代码可见同一文件。

在获取了用户的 tokenId 之后,就需要找到对应的 socketId,然后向特定用户推送消息。

1
2
3
4
5
// 只向 id = socketId 的这一连接发送消息
io.sockets.to(socketId).emit('receive_message', {
entityType,
data
});

服务器的思路大致如此,接下来介绍客户端中是如何进行相应的处理的。

客户端

Socket.io 的初始化
首先在 html 文件中引入 Socket.io 的 client 端文件,例如通过 CDN 引入:

1
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>

其它的引入方式:

1
2
3
const io = require('socket.io-client');
// or with import syntax
import io from 'socket.io-client';

引入 Socket.io 后就获得了 io 函数,通过它来与消息推送服务器建立连接。

1
2
3
4
5
6
7
// 假设你将 Node 服务器部署后的地址为:https://www.example.com/ws
// 则: WS_HOST = 'https://www.example.com'

const msgSocket = io(`${WS_HOST}`, {
secure: true,
path: '/ws/socket.io'
});

如果监听本地:

1
const msgSocket = io('http://localhost:4001');

这里如果写成 io(‘https://www.example.com/ws') 会出现错误,需要将 /ws 写入path中。

为了能在其它文件使用这一变量,可将 msgSocket 作为一个全局变量:

1
window.msgSocket = msgSocket;

用户建立连接

// 用户登录时,向服务器发送用户的信息。服务器会在收到信息后建立 socket 与用户的映射。
msgSocket.emit(‘user_login’, {
userId,
socketId: msgSocket.id,
tokenId
});

##demo
[demo博文原文](https://segmentfault.com/a/1190000010974426)
[demo](https://github.com/noiron/socket-message-push)
##资料
[socket-io官网](https://socket.io/get-started/chat/)