-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathindex.js
130 lines (102 loc) · 2.67 KB
/
index.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
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
/**
* Module dependencies.
*/
var uid2 = require('uid2')
, mubsub = require('mubsub')
, msgpack = require('msgpack-js')
, Adapter = require('socket.io-adapter')
, debug = require('debug')('socket.io-mongo')
, mongodbUri = require('mongodb-uri');
;
/**
* Module exports.
*/
module.exports = adapter;
/**
* Returns a mongo Adapter class.
*
* @param {String} optional, mongo uri
* @return {Mongo} adapter
* @api public
*/
function adapter(uri, opts) {
opts = opts || {};
// handle options only
if ('object' == typeof uri) {
opts = uri;
uri = null;
}
// handle uri string
if (uri) {
// ensure uri has mongodb scheme
if (uri.indexOf('mongodb://') !== 0) {
uri = 'mongodb://' + uri;
}
// Parse to uri into an object
var uriObj = mongodbUri.parse(uri);
if (uriObj.username && uriObj.password) {
opts.username = uriObj.username;
opts.password = uriObj.password;
}
opts.host = uriObj.hosts[0].host;
opts.port = uriObj.hosts[0].port;
opts.db = uriObj.database;
}
// opts
var socket = opts.socket;
var creds = (opts.username && opts.password) ? opts.username + ':' + opts.password + '@' : '';
var host = opts.host || '127.0.0.1';
var port = Number(opts.port || 27017);
var db = opts.db || 'mubsub';
var client = opts.client;
var key = opts.key || 'socket.io';
// init clients if needed
var uri = 'mongodb://' + creds + host + ':' + port + '/' + db
if (!client) client = socket ? mubsub(socket) : mubsub(uri, opts);
// this server's key
var uid = uid2(6);
var channel = client.channel(key);
/**
* Adapter constructor.
*
* @param {String} namespace name
* @api public
*/
function Mongo(nsp) {
Adapter.call(this, nsp);
channel.subscribe(key, this.onmessage.bind(this));
}
/**
* Inherits from `Adapter`.
*/
Mongo.prototype.__proto__ = Adapter.prototype;
/**
* Called with a subscription message
*
* @api private
*/
Mongo.prototype.onmessage = function (msg) {
if (uid == msg.uid || !msg.uid) return debug('ignore same uid');
var args = msgpack.decode(msg.data.buffer);
if (args[0] && args[0].nsp === undefined)
args[0].nsp = '/';
if (!args[0] || args[0].nsp != this.nsp.name) return debug('ignore different namespace');
args.push(true);
this.broadcast.apply(this, args);
};
/**
* Broadcasts a packet.
*
* @param {Object} packet to emit
* @param {Object} options
* @param {Boolean} whether the packet came from another node
* @api public
*/
Mongo.prototype.broadcast = function (packet, opts, remote) {
Adapter.prototype.broadcast.call(this, packet, opts);
if (!remote) {
channel.publish(key, { uid: uid, data: msgpack.encode([packet, opts]) });
}
};
return Mongo;
}