# 离线消息缓存发送
客户端:
- 设置uid,确定ws唯一的标识
- 断线重连后,发送roomid与uid
const urlParams = new URLSearchParams(window.location.search)
const uid = urlParams.get("uid")
if (this.name.trim() === "") {
alert("用户名不得为空")
return
}
this.wsHandle.send(
JSON.stringify({
name: this.name,
roomid: this.roomid,
uid: uid,
event: "login",
})
)
this.isShow = false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
服务端:
- 使用redis进行消息的缓存
- 对客户端的连接进行唯一性标识
- 对于断开连接的客户端,离线消息进行保存
- 再次连接过来的客户端,发送离线消息
wss.on("connection", function(ws, req) {
// 初始化客户端的连接状态量
ws.isAlive = true
// console.log('a new client is connected!');
ws.on("message", async function(msg) {
var msgObj = JSON.parse(msg)
if (msgObj.event === "heartbeat" && msgObj.message === "pong") {
ws.isAlive = true
return
}
if (msgObj.name) {
ws.name = msgObj.name
}
if (msgObj.uid) {
ws.uid = msgObj.uid
}
if (typeof ws.roomid === "undefined" && msgObj.roomid) {
// 还需要一个客户端的标识,可以知道ws给谁去发送消息
ws.roomid = msgObj.roomid
const result = await existKey(prefix + msgObj.roomid)
if (result === 0) {
// 初始化数据
setValue(prefix + msgObj.roomid, ws.uid)
} else {
let arrStr = await getValue(prefix + msgObj.roomid)
// String -> Json
let arr = arrStr.split(",")
if (arr.indexOf(ws.uid) === -1) {
arrStr += "," + ws.uid
setValue(prefix + msgObj.roomid, arrStr)
}
}
}
// 广播到其他的客户端
let arrStr1 = await getValue(prefix + ws.roomid)
let arr1 = arrStr1.split(",")
// 在线人数,计算uid的个数
msgObj.total = arr1.length
msgObj.num = wss.clients.size
wss.clients.forEach(async function each(client) {
if (client.readyState === WebSocket.OPEN && client.roomid === ws.roomid) {
client.send(JSON.stringify(msgObj))
// 删除已经发送了消息的对应的对象
if (arr1.indexOf(client.uid) !== -1) {
arr1.splice(arr1.indexOf(client.uid), 1)
}
let result = await existKey(ws.uid)
if (result !== 0) {
let tmpArr = await getValue(ws.uid)
let tmpObj = JSON.parse(tmpArr)
let uid = ws.uid
if (tmpObj.length > 0) {
let i = []
// 遍历数组,判断是否是同一个roomid,否则的话,就保存数据
tmpObj.forEach(function(item) {
if (item.roomid === client.roomid && uid === client.uid) {
// 如果是同一个roomid,就发送对应的消息数据。
client.send(JSON.stringify(item.msg))
i.push(item)
}
})
if (i.length > 0) {
i.forEach(function(item) {
tmpObj.splice(item, 1)
})
}
setValue(ws.uid, JSON.stringify(tmpObj))
}
}
}
// 判断,是否有客户端没有连接。
// 对于没有连接的客户端的数据,进行分发缓存处理
})
// 说明有一些客户端断开了与roomid的连接,并且,其他客户端发送了对应的消息
if (arr1.length > 0 && msgObj.event === "message") {
arr1.forEach(async function(item) {
const result = await existKey(item)
if (result !== 0) {
let udata = await getValue(item)
let uObj = JSON.parse(udata)
uObj.push({
roomid: ws.roomid,
msg: msgObj,
})
setValue(item, JSON.stringify(uObj))
} else {
// 说明先前,这个数据没有进行缓存 ,没有记录
setValue(
item,
JSON.stringify([
{
roomid: ws.roomid,
msg: msgObj,
},
])
)
}
})
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102