-
-
Notifications
You must be signed in to change notification settings - Fork 37
/
multiplex_client.js
86 lines (75 loc) · 2.49 KB
/
multiplex_client.js
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
var WebSocketMultiplex = (function(){
// ****
var DumbEventTarget = function() {
this._listeners = {};
};
DumbEventTarget.prototype._ensure = function(type) {
if(!(type in this._listeners)) this._listeners[type] = [];
};
DumbEventTarget.prototype.addEventListener = function(type, listener) {
this._ensure(type);
this._listeners[type].push(listener);
};
DumbEventTarget.prototype.emit = function(type) {
this._ensure(type);
var args = Array.prototype.slice.call(arguments, 1);
if(this['on' + type]) this['on' + type].apply(this, args);
for(var i=0; i < this._listeners[type].length; i++) {
this._listeners[type][i].apply(this, args);
}
};
// ****
var WebSocketMultiplex = function(ws) {
var that = this;
this.ws = ws;
this.channels = {};
this.ws.addEventListener('message', function(e) {
var t = e.data.split(',');
var type = t.shift(), name = t.shift(), payload = t.join();
if(!(name in that.channels)) {
return;
}
var sub = that.channels[name];
switch(type) {
case 'uns':
delete that.channels[name];
sub.emit('close', {});
break;
case 'msg':
sub.emit('message', {data: payload});
break;
}
});
};
WebSocketMultiplex.prototype.channel = function(raw_name) {
return this.channels[escape(raw_name)] =
new Channel(this.ws, escape(raw_name), this.channels);
};
var Channel = function(ws, name, channels) {
DumbEventTarget.call(this);
var that = this;
this.ws = ws;
this.name = name;
this.channels = channels;
var onopen = function() {
that.ws.send('sub,' + that.name);
that.emit('open');
};
if(ws.readyState > 0) {
setTimeout(onopen, 0);
} else {
this.ws.addEventListener('open', onopen);
}
};
Channel.prototype = new DumbEventTarget()
Channel.prototype.send = function(data) {
this.ws.send('msg,' + this.name + ',' + data);
};
Channel.prototype.close = function() {
var that = this;
this.ws.send('uns,' + this.name);
delete this.channels[this.name];
setTimeout(function(){that.emit('close', {});},0);
};
return WebSocketMultiplex;
})();