Skip to content

Commit bbaedea

Browse files
心跳
1 parent 48879e6 commit bbaedea

4 files changed

Lines changed: 229 additions & 15 deletions

File tree

01-JS语言基础/02-常用操作/03-3-Set&Map区别Array.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
</head>
66
<body>
77
<script type="text/javascript">
8+
9+
/**
10+
* Map & Set 遍历
11+
* 参考下一篇
12+
*
13+
*/
14+
815
// Array可以使用下标,Map和Set不能使用下标,ES6引入了iterable类型,Array,Map,Set都属于iterable类型,它们可以使用for...of循环来遍历:
916
var a = ['A', 'B', 'C'];
1017
var s = new Set(['A', 'B', 'C']);
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title></title>
5+
</head>
6+
<body>
7+
<script>
8+
'use strict';
9+
10+
var m = new Map();
11+
var s= new Set();
12+
13+
// 【 1.Map 】
14+
// Map 键值对,查找速度快 (Key, Value),各种类型的值(包括对象)都可以当作键
15+
// 初始化为二维数组或空,注意:一个键只能有一个值
16+
// undefined和null是两个不同的键,虽然NaN不严格相等于自身,但 Map 将其视为同一个键
17+
var m1 = new Map([['Bob', 100], ['Jhon', 85], ['Mike', 66]]);
18+
m1.get('Bob'); // 100
19+
var m2 = new Map();
20+
m2.set('Adam', 67); // Map(1) {"Adam" => 67}
21+
m2.get('Adam'); // 67
22+
m2.has('Adam'); // true
23+
m2.delete('Adam');
24+
m2.get('Adam'); // undefined
25+
26+
let m3 = new Map();
27+
m3.set(-0, 123);
28+
m3.get(+0) // 123
29+
30+
m3.set(true, 1);
31+
m3.set('true', 2);
32+
m3.get(true) // 1
33+
34+
m3.set(undefined, 3);
35+
m3.set(null, 4);
36+
m3.get(undefined) // 3
37+
38+
m3.set(NaN, 123);
39+
m3.get(NaN) // 123
40+
41+
// 获取Map长度
42+
var map_es5 = {1:'1', 2:'2', 3:'3'};
43+
// es5
44+
console.log(Object.getOwnPropertyNames(map_es5).length);
45+
// es6 size属性
46+
console.log(m1.size); // 3
47+
48+
// 【 遍历 】
49+
// keys()、values()、entries() 键值对遍历器,Map 的遍历顺序就是插入顺序
50+
// forEach() 回调遍历
51+
for (let key of m1.keys()) {
52+
console.log(key);
53+
}
54+
for (let value of m1.values()) {
55+
console.log(value);
56+
}
57+
for (let item of m1.entries()) {
58+
console.log(item[0], item[1]);
59+
}
60+
for (let [key, value] of m1.entries()) {
61+
console.log(key, value);
62+
}
63+
for (let [key, value] of m1) {
64+
console.log(key, value);
65+
}
66+
67+
// 使用数组的 map 和 filter 方法
68+
const map0 = new Map().set(1, 'a').set(2, 'b').set(3, 'c');
69+
const map1 = new Map(
70+
[...map0].filter(([k, v]) => k < 3) // 产生 Map 结构 {1 => 'a', 2 => 'b'}
71+
);
72+
const map2 = new Map(
73+
[...map0].map(([k, v]) => [k * 2, '_' + v]) // 产生 Map 结构 {2 => '_a', 4 => '_b', 6 => '_c'}
74+
);
75+
76+
// 【 转换 】
77+
// Map => Array 扩展运算符(...)
78+
var array1 = [...m1.keys()]
79+
var array2 = [...m1.values()]
80+
var array3 = [...m1.entries()]
81+
var array4 = [...m1]
82+
83+
// Array => Map
84+
new Map([[true, 7], [{foo: 3}, ['abc']]])
85+
86+
// Map => Object
87+
function strMapToObj(strMap) {
88+
let obj = Object.create(null);
89+
for (let [k,v] of strMap) {
90+
obj[k] = v;
91+
}
92+
return obj;
93+
}
94+
let myMap1 = new Map().set('yes', true).set('no', false);
95+
console.log(strMapToObj(myMap1)); // {yes: true, no: false}
96+
97+
// Object => Map
98+
function objToStrMap(obj) {
99+
let strMap = new Map();
100+
for (let k of Object.keys(obj)) {
101+
strMap.set(k, obj[k]);
102+
}
103+
return strMap;
104+
}
105+
var obj = {yes: true, no: false}
106+
console.log(objToStrMap(obj)) // Map(2) {"yes" => true, "no" => false}
107+
108+
// Map => 对象JSON Map的键名都是字符串
109+
function strMapToObjJson(strMap) {
110+
return JSON.stringify(strMapToObj(strMap));
111+
}
112+
let strMap3 = new Map().set('yes', true).set('no', false);
113+
console.log(strMapToObjJson(strMap3)); // {"yes":true,"no":false}
114+
115+
// Map => 数组JSON Map的键名有非字符串
116+
function mapToArrayJson(arrMap) {
117+
return JSON.stringify([...arrMap]);
118+
}
119+
let myMap4 = new Map().set(true, 7).set({foo: 3}, ['abc']);
120+
console.log(mapToArrayJson(myMap4)); // [[true,7],[{"foo":3},["abc"]]]
121+
122+
// 对象JSON => Map 所有键名为字符串
123+
function jsonToStrMap(jsonStr) {
124+
return objToStrMap(JSON.parse(jsonStr));
125+
}
126+
console.log(jsonToStrMap('{"yes": true, "no": false}')); // Map(2) {"yes" => true, "no" => false}
127+
128+
// 数组JSON => Map
129+
function jsonToMap(jsonStr) {
130+
return new Map(JSON.parse(jsonStr));
131+
}
132+
console.log(jsonToMap('[[true,7],[{"foo":3},["abc"]]]')); // Map(2) {true => 7, {…} => Array(1)}
133+
134+
135+
/**
136+
* 【 2.Set 】
137+
*
138+
*/
139+
// 只存储不重复的key,不存value
140+
// 可以向Set中重复添加相同的元素,但是不会有效果
141+
var s1 = new Set(); // 空Set
142+
var s2 = new Set([1, 2, 3, 3, '3']); // Set(3) {1, 2, "3"}
143+
s2.add(3); // {1, 2, 3, "3"}
144+
s2.has(3);
145+
s2.delete(3); // {1, 2, "3"}
146+
s2.clear(); // Set(0) {}
147+
// 快速去除重复元素
148+
function dedupe(array) {
149+
return Array.from(new Set(array));
150+
}
151+
console.log(dedupe([1, 1, 2, 3])); // [1, 2, 3]
152+
// 获取Set长度
153+
console.log(dedupe([1, 1, 2, 3]).length); // [1, 2, 3]
154+
155+
// 【 遍历 】
156+
// keys()、values()、entries() 键值对遍历器,对Set,keys() = values()
157+
// forEach() 回调遍历
158+
let s3 = new Set(['red', 'green', 'blue']);
159+
console.log(s3.keys()); // SetIterator {"red", "green", "blue"}
160+
for (let item of s3.keys()) {
161+
console.log(item); // red green blue
162+
}
163+
for (let item of s3.values()) {
164+
console.log(item); // red green blue
165+
}
166+
for (let item of s3.entries()) {
167+
console.log(item); // ["red", "red"] ["green", "green"] ["blue", "blue"]
168+
}
169+
for (let item of s3) {
170+
console.log(item); // red green blue
171+
}
172+
let s4 = new Set([1, 2, 3]);
173+
s4.forEach((value, key) => console.log(value * 2) ) // 2 4 6
174+
175+
// 【 遍历的应用 】
176+
// 扩展去重:扩展运算符(...)内部使用for...of循环,所以也可以用于 Set 结构,还能够去重
177+
let s5 = new Set(['red', 'green', 'blue', 'red']);
178+
let unique = [...s5]; // ['red', 'green', 'blue']
179+
180+
// 数组的map和filter方法可用于 Set
181+
let s6 = new Set([1, 2, 3]);
182+
s6 = new Set([...s6].map(x => x * 2)); // Set(3) {2, 4, 6}
183+
let s7 = new Set([1, 2, 3, 4, 5]);
184+
s7 = new Set([...s7].filter(x => (x % 2) == 0)); // Set(2) {2, 4}
185+
186+
// 使用 Set 实现并集(Union)、交集(Intersect)和差集(Difference)
187+
let a = new Set([1, 2, 3]);
188+
let b = new Set([4, 3, 2]);
189+
// 并集
190+
let union = new Set([...a, ...b]); // Set {1, 2, 3, 4}
191+
// 交集
192+
let intersect = new Set([...a].filter(x => b.has(x))); // set {2, 3}
193+
// 差集
194+
let difference = new Set([...a].filter(x => !b.has(x))); // Set {1}
195+
196+
// 如果想在遍历操作中,同步改变原来的 Set 结构,目前没有直接的方法,但有两种变通方法
197+
// 一种是利用原 Set 结构映射出一个新的结构,然后赋值给原来的 Set 结构
198+
// 另一种是利用Array.from方法
199+
200+
201+
</script>
202+
</body>
203+
</html>

11-nodejs/koa2/8-chatroom/app.js

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: csxiaoyao
33
* @Date: 2018-04-18 17:53:40
44
* @Last Modified by: csxiaoyao
5-
* @Last Modified time: 2018-04-19 23:12:16
5+
* @Last Modified time: 2018-04-20 16:51:55
66
*/
77

88
// 只接受 ws://localhost:3000/ws/chat 用于区别其他http请求
@@ -96,22 +96,19 @@ function createWebSocketServer(server, onConnection, onMessage, onClose, onError
9696
});
9797
console.log('WebSocketServer was attached.');
9898

99-
// 心跳
100-
// wss.heartbeat = function heartbeat(data) {
101-
// wss.clients.forEach(function each(client) {
102-
// client.send(data);
103-
// });
104-
// };
99+
// 心跳 定期清理断开的客户端,3min清理一次,判定超时时间为60s,因为客户端心跳时间为50s
105100
setInterval(()=>{
106101
wss.clients.forEach(function each(client) {
107-
// console.log(client.auth);
108-
wss.unicast(createMessage('msg', null, `hello sunshine`),"sunshine");
102+
let timeDiff = Date.now() - client.timestamp;
103+
if(timeDiff > 60 * 1000){
104+
client.close();
105+
}
106+
// wss.unicast(createMessage('msg', null, `hello sunshine`),"sunshine");
109107
})
110-
let connList = getConnList(wss.clients);
111-
console.log(connList);
112-
// console.log(getLength(connList));
113-
// console.log(Object.getOwnPropertyNames(connList).length);
114-
},5000);
108+
let connNum = Array.from(new Set(wss.clients)).length;
109+
let connList = Array.from(new Set(getConnList(wss.clients)));
110+
console.log('当前连接数:' + connNum + '\n当前在线人数:' + connList.length);
111+
}, 3 * 60 * 1000);
115112

116113
return wss;
117114
}
@@ -160,6 +157,9 @@ function getLength(map) {
160157

161158
// 自定义生命周期函数
162159
function onConnect() {
160+
// 获取时间戳绑定到当前client,用户判断客户端是否失联 (onConnect、onMessage)
161+
this.timestamp = Date.now();
162+
163163
// 获取用户信息,在connection中获取
164164
let auth = this.auth;
165165
let connList = getConnList(this.wss.clients);
@@ -174,6 +174,9 @@ function onConnect() {
174174
}
175175

176176
function onMessage(message) {
177+
// 获取时间戳绑定到当前client,用户判断客户端是否失联 (onConnect、onMessage)
178+
this.timestamp = Date.now();
179+
177180
if(message.length <= 2){
178181
this.send(createMessage('error', null, 'msg error'));
179182
return;

11-nodejs/koa2/8-chatroom/test.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
ws.onerror = onError;
2525
}
2626
function onOpen(event) {
27+
console.log('onopen');
2728
heartCheck.start();
2829
};
2930
function onMessage(event) {
@@ -54,7 +55,7 @@
5455

5556
// 心跳保活
5657
var heartCheck = {
57-
timeout: 30,
58+
timeout: 50,
5859
tryInterval: 3,
5960
timeoutObj: null,
6061
tryCount : 0,

0 commit comments

Comments
 (0)