实时通讯

websocket 实现实时通讯

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
"use strict";

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}

var socket = (function () {
function socket() {
// 调用socket方法时传入的第一个参数为url, 第二个参数为options配置
var url =
arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
var options = arguments[1];

_classCallCheck(this, socket);

this.heartBeatTimer = null;
this.options = options;
this.messageMap = {};
this.connState = 0;
this.socket = null;
this.url = url;
this.limitConnect = 3; // 断线重连次数
this.timeConnect = 0;
}

socket.prototype.doOpen = function doOpen() {
var _this = this;
if (this.connState) return;
this.connState = 1;
this.afterOpenEmit = [];
var BrowserWebSocket = window.WebSocket || window.MozWebSocket;
var socket = new BrowserWebSocket(this.url);
socket.binaryType = "arraybuffer";
socket.onopen = function (evt) {
return _this.onOpen(evt);
};
socket.onclose = function (evt) {
return _this.onClose(evt);
};
socket.onmessage = function (evt) {
return _this.onMessage(evt.data);
};
socket.onerror = function (err) {
return _this.onError(err);
};
this.socket = socket;
};

socket.prototype.onOpen = function onOpen(evt) {
this.connState = 2;
this.heartBeatTimer = setInterval(this.checkHeartbeat.bind(this), 5000);
this.onReceiver({
Event: "open"
});
};

socket.prototype.checkOpen = function checkOpen() {
return this.connState === 2;
};

socket.prototype.onClose = function onClose() {
this.connState = 0;
if (this.connState) {
this.onReceiver({
Event: "close"
});
}
console.log("服务器已经断开");
this.reconnect();
};

socket.prototype.send = function send(data) {
this.socket.send(JSON.stringify(data));
};

socket.prototype.emit = function emit(data) {
var _this2 = this;

return new Promise(function (resolve) {
_this2.socket.send(JSON.stringify(data));
_this2.on("message", function (data) {
resolve(data);
});
});
};

socket.prototype.onMessage = function onMessage(message) {
if ("pong" !== message) {
try {
var data = JSON.parse(message);
this.onReceiver({
Event: "message",
Data: data
});
} catch (err) {
// console.error(' >> Data parsing error:', err);
}
}
};

socket.prototype.checkHeartbeat = function checkHeartbeat() {
this.socket.send("ping");
};

socket.prototype.onError = function onError(err) {
console.log("服务器报错:");
this.reconnect();
};

// 重连
socket.prototype.reconnect = function reconnect() {
if (this.heartBeatTimer) {
clearInterval(this.heartBeatTimer);
this.heartBeatTimer = null;
}
if (this.limitConnect > 0) {
// lockReconnect加锁,防止onclose、onerror两次重连
if (localStorage.getItem("lockReconnect") != true) {
localStorage.setItem("lockReconnect", 1);
this.limitConnect--;
this.timeConnect++;
console.log("第" + this.timeConnect + "次重连");
// 进行重连
setTimeout(function () {
TVjsApi.initSocket();
localStorage.removeItem("lockReconnect");
}, 2000);
}
} else {
console.log("TCP连接已超时");
}
};

socket.prototype.onReceiver = function onReceiver(data) {
var callback = this.messageMap[data.Event];
if (callback) callback(data.Data);
};

socket.prototype.on = function on(name, handler) {
this.messageMap[name] = handler;
};

socket.prototype.doClose = function doClose() {
this.socket.close();
};

socket.prototype.destroy = function destroy() {
if (this.heartBeatTimer) {
clearInterval(this, this.heartBeatTimer);
this.heartBeatTimer = null;
}
this.doClose();
this.messageMap = {};
this.connState = 0;
this.socket = null;
};

return socket;
})();