@cocreate/socket-server 1.18.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/CoCreate.config.js +24 -24
- package/docs/index.html +0 -1
- package/package.json +4 -3
- package/src/index.js +289 -144
- package/src/mesh.js +71 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
# [1.19.0](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.18.1...v1.19.0) (2023-10-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* added '@cocreate/utlis' ([cc8267a](https://github.com/CoCreate-app/CoCreate-socket-server/commit/cc8267abf7ded45033929bd4c4997eb9adc89d42))
|
|
7
|
+
* handling of socket.id and clientId ([9e66f16](https://github.com/CoCreate-app/CoCreate-socket-server/commit/9e66f16f4e869e7ec29a261068fb61c46569f408))
|
|
8
|
+
* Improved handling of data.sync ([190ebd6](https://github.com/CoCreate-app/CoCreate-socket-server/commit/190ebd6c10f337fbd4e8be81caba865cfffb5c0a))
|
|
9
|
+
* send _id with syncMessage ([e37e2de](https://github.com/CoCreate-app/CoCreate-socket-server/commit/e37e2de8aff8945a3884c416514adc1e89fc54e2))
|
|
10
|
+
* update to use data.socketId and data.clientId ([125f2be](https://github.com/CoCreate-app/CoCreate-socket-server/commit/125f2bedd6090488ae26dc2228b53bb4aa63d4ff))
|
|
11
|
+
* use message_log ([d4b4c4a](https://github.com/CoCreate-app/CoCreate-socket-server/commit/d4b4c4ad2708cd61567d7172ac7bcb0635349a6a))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* Authentication happens during upgrade ([c01cb0e](https://github.com/CoCreate-app/CoCreate-socket-server/commit/c01cb0eeb5fc4e135a8d9855fbab7e8b9535423d))
|
|
17
|
+
* get, set, delete socket functions ([9066911](https://github.com/CoCreate-app/CoCreate-socket-server/commit/9066911016072841cd08463c8354eeef892b41e3))
|
|
18
|
+
* method sync sent to server with sync details ([3c914b7](https://github.com/CoCreate-app/CoCreate-socket-server/commit/3c914b74d720949c8ae56f3f9159041ef1d5f24f))
|
|
19
|
+
* on socket connection the data is parsed from ([0b69b35](https://github.com/CoCreate-app/CoCreate-socket-server/commit/0b69b357c891da63c3e94aaca8361866f252de98))
|
|
20
|
+
|
|
21
|
+
## [1.18.1](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.18.0...v1.18.1) (2023-09-18)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* Add path and pathname ([5b5fb7e](https://github.com/CoCreate-app/CoCreate-socket-server/commit/5b5fb7e6d718f916dfdbfc3754cb63c6b1a51c47))
|
|
27
|
+
* Update clients array to use map for improved management of each client ([cff2f2a](https://github.com/CoCreate-app/CoCreate-socket-server/commit/cff2f2ad3d34ac1d7b926180da508c65e5855b37))
|
|
28
|
+
* Update dCoCreate dpendencies to latest versions ([03fa429](https://github.com/CoCreate-app/CoCreate-socket-server/commit/03fa429efc31db9f0ed5aec41dbf5b471475e0ba))
|
|
29
|
+
|
|
1
30
|
# [1.18.0](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.17.0...v1.18.0) (2023-09-17)
|
|
2
31
|
|
|
3
32
|
|
package/CoCreate.config.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
"organization_id": "",
|
|
3
|
-
"key": "",
|
|
4
|
-
"host": "",
|
|
5
|
-
"sources": [
|
|
6
|
-
{
|
|
7
|
-
"array": "files",
|
|
8
|
-
"object": {
|
|
9
|
-
"_id": "6204254580b409001727b744",
|
|
10
|
-
"name": "index.html",
|
|
11
|
-
"path": "/docs/socket-server
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
]
|
|
24
|
-
}
|
|
1
|
+
module.exports = {
|
|
2
|
+
"organization_id": "",
|
|
3
|
+
"key": "",
|
|
4
|
+
"host": "",
|
|
5
|
+
"sources": [
|
|
6
|
+
{
|
|
7
|
+
"array": "files",
|
|
8
|
+
"object": {
|
|
9
|
+
"_id": "6204254580b409001727b744",
|
|
10
|
+
"name": "index.html",
|
|
11
|
+
"path": "/docs/socket-server",
|
|
12
|
+
"pathname": "/docs/socket-server/index.html",
|
|
13
|
+
"src": "{{./docs/index.html}}",
|
|
14
|
+
"host": [
|
|
15
|
+
"*",
|
|
16
|
+
"general.cocreate.app"
|
|
17
|
+
],
|
|
18
|
+
"directory": "socket-server",
|
|
19
|
+
"content-type": "text/html",
|
|
20
|
+
"public": "true"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
};
|
package/docs/index.html
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/socket-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
4
4
|
"description": "CoCreate-socket-server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cocreate-socket",
|
|
@@ -40,8 +40,9 @@
|
|
|
40
40
|
},
|
|
41
41
|
"homepage": "https://cocreate.app/docs/CoCreate-socket-server",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@cocreate/config": "^1.5.
|
|
44
|
-
"@cocreate/uuid": "^1.7.
|
|
43
|
+
"@cocreate/config": "^1.5.2",
|
|
44
|
+
"@cocreate/uuid": "^1.7.2",
|
|
45
|
+
"@cocreate/utils": "^1.24.2",
|
|
45
46
|
"ws": "7.5.9"
|
|
46
47
|
}
|
|
47
48
|
}
|
package/src/index.js
CHANGED
|
@@ -2,107 +2,266 @@ const WebSocket = require('ws');
|
|
|
2
2
|
const { URL } = require("url");
|
|
3
3
|
const EventEmitter = require("events").EventEmitter;
|
|
4
4
|
const uid = require('@cocreate/uuid')
|
|
5
|
+
const { ObjectId } = require('@cocreate/utils')
|
|
5
6
|
const config = require('@cocreate/config')
|
|
6
7
|
|
|
7
8
|
class SocketServer extends EventEmitter {
|
|
8
|
-
constructor(server
|
|
9
|
+
constructor(server) {
|
|
9
10
|
super();
|
|
11
|
+
this.serverId = uid.generate(12)
|
|
10
12
|
this.organizations = new Map();
|
|
11
13
|
this.clients = new Map();
|
|
12
|
-
this.
|
|
14
|
+
this.sockets = new Map();
|
|
15
|
+
this.users = new Map();
|
|
16
|
+
|
|
13
17
|
config({ organization_id: { prompt: 'Enter your organization_id: ' } })
|
|
14
18
|
|
|
15
19
|
this.wss = new WebSocket.Server({ noServer: true });
|
|
20
|
+
|
|
16
21
|
this.wss.on('headers', (headers, request) => {
|
|
17
22
|
headers.push('Access-Control-Allow-Origin: *');
|
|
18
23
|
});
|
|
19
24
|
|
|
25
|
+
this.wss.on('error', (error) => {
|
|
26
|
+
socket.destroy();
|
|
27
|
+
});
|
|
28
|
+
|
|
20
29
|
server.on('upgrade', (request, socket, head) => {
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
const self = this;
|
|
31
|
+
let organization_id = request.url.split('/')
|
|
32
|
+
organization_id = organization_id[organization_id.length - 1]
|
|
33
|
+
|
|
34
|
+
if (organization_id) {
|
|
35
|
+
this.wss.handleUpgrade(request, socket, head, function (socket) {
|
|
36
|
+
let options = decodeURIComponent(request.headers['sec-websocket-protocol'])
|
|
37
|
+
options = JSON.parse(options)
|
|
38
|
+
|
|
39
|
+
socket.organization_id = organization_id
|
|
40
|
+
socket.id = options.socketId;
|
|
41
|
+
socket.clientId = options.clientId;
|
|
42
|
+
socket.pathname = request.url
|
|
43
|
+
socket.origin = request.headers.origin || request.headers.host
|
|
44
|
+
|
|
45
|
+
if (socket.origin.startsWith('http'))
|
|
46
|
+
socket.origin = socket.origin.replace('http', 'ws')
|
|
47
|
+
|
|
48
|
+
socket.socketUrl = socket.origin + socket.pathname
|
|
49
|
+
|
|
50
|
+
if (socket.origin && socket.origin !== 'null') {
|
|
51
|
+
const url = new URL(socket.origin);
|
|
52
|
+
socket.host = url.host || socket.origin;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let data = {
|
|
56
|
+
socket,
|
|
57
|
+
method: 'read.object',
|
|
58
|
+
array: 'message_log',
|
|
59
|
+
$filter: {
|
|
60
|
+
sort: [
|
|
61
|
+
{ key: '_id', direction: 'desc' }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
sync: true,
|
|
65
|
+
organization_id
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (options.lastSynced)
|
|
69
|
+
data.$filter.query = [
|
|
70
|
+
{ key: '_id', value: options.lastSynced, operator: '$gt' }
|
|
71
|
+
]
|
|
72
|
+
else
|
|
73
|
+
data.$filter.limit = 1
|
|
74
|
+
|
|
75
|
+
self.emit('read.object', data);
|
|
76
|
+
|
|
77
|
+
if (self.authenticate && options.token)
|
|
78
|
+
self.authenticate.decodeToken(options.token).then(({ user_id, expires }) => {
|
|
79
|
+
if (user_id) {
|
|
80
|
+
socket.user_id = user_id;
|
|
81
|
+
socket.expires = expires;
|
|
82
|
+
self.emit('userStatus', { socket, method: 'userStatus', user_id, userStatus: 'on', organization_id });
|
|
83
|
+
} else
|
|
84
|
+
this.emit('userStatus', { socket, user_id, status: 'off', organization_id });
|
|
85
|
+
|
|
86
|
+
self.onWebSocket(socket);
|
|
87
|
+
})
|
|
88
|
+
else
|
|
89
|
+
self.onWebSocket(socket);
|
|
90
|
+
})
|
|
23
91
|
}
|
|
24
92
|
});
|
|
25
93
|
}
|
|
26
94
|
|
|
27
|
-
|
|
28
|
-
const self = this;
|
|
29
|
-
// const url = new URL(req.url);
|
|
30
|
-
// const pathname = req.url;
|
|
31
|
-
const config = this.getKeyFromUrl(req.url)
|
|
32
|
-
if (config.type == this.prefix) {
|
|
33
|
-
this.wss.handleUpgrade(req, socket, head, function (socket) {
|
|
34
|
-
socket.config = config
|
|
35
|
-
self.onWebSocket(req, socket);
|
|
36
|
-
})
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
onWebSocket(req, socket) {
|
|
95
|
+
onWebSocket(socket) {
|
|
43
96
|
const self = this;
|
|
44
|
-
|
|
45
|
-
this.addClient(socket);
|
|
97
|
+
this.add(socket);
|
|
46
98
|
|
|
47
99
|
socket.on('message', async (message) => {
|
|
48
|
-
self.onMessage(
|
|
100
|
+
self.onMessage(socket, message);
|
|
49
101
|
})
|
|
50
102
|
|
|
51
|
-
socket.on('close',
|
|
52
|
-
self.
|
|
103
|
+
socket.on('close', () => {
|
|
104
|
+
self.delete(socket)
|
|
53
105
|
})
|
|
54
106
|
|
|
55
107
|
socket.on("error", () => {
|
|
56
|
-
self.
|
|
108
|
+
self.delete(socket)
|
|
57
109
|
});
|
|
58
110
|
|
|
59
|
-
|
|
111
|
+
socket.send(JSON.stringify({ method: 'connect', connectedKey: socket.pathname }))
|
|
60
112
|
|
|
61
113
|
}
|
|
62
114
|
|
|
63
|
-
|
|
64
|
-
let organization_id = socket.
|
|
65
|
-
|
|
66
|
-
|
|
115
|
+
add(socket) {
|
|
116
|
+
let organization_id = socket.organization_id
|
|
117
|
+
|
|
118
|
+
let organization = this.organizations.get(organization_id)
|
|
119
|
+
if (!organization) {
|
|
120
|
+
organization = {
|
|
121
|
+
status: true,
|
|
122
|
+
clients: {}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.organizations.set(organization_id, organization)
|
|
126
|
+
|
|
127
|
+
this.emit('update.object', {
|
|
128
|
+
method: 'update.object',
|
|
129
|
+
array: 'organizations',
|
|
130
|
+
object: {
|
|
131
|
+
_id: organization_id, ['$push.activeHost']: socket.socketUrl // needs socketId
|
|
132
|
+
},
|
|
133
|
+
organization_id
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
this.emit('mesh.create', {
|
|
137
|
+
url: socket.socketUrl,
|
|
138
|
+
organization_id
|
|
139
|
+
});
|
|
67
140
|
|
|
68
|
-
let user_id = socket.config.user_id
|
|
69
|
-
let key = socket.config.key
|
|
70
|
-
let clients = this.clients.get(key);
|
|
71
|
-
if (clients) {
|
|
72
|
-
clients.push(socket);
|
|
73
|
-
} else {
|
|
74
|
-
clients = [socket];
|
|
75
141
|
}
|
|
76
|
-
this.clients.set(key, clients);
|
|
77
142
|
|
|
78
|
-
if (
|
|
79
|
-
this.
|
|
143
|
+
if (!this.clients.has(socket.clientId)) {
|
|
144
|
+
this.clients.set(socket.clientId, []);
|
|
145
|
+
organization.clients[socket.clientId] = []
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!this.sockets.has(socket.id)) {
|
|
149
|
+
this.sockets.set(socket.id, socket);
|
|
150
|
+
this.clients.get(socket.clientId).push(socket);
|
|
151
|
+
organization.clients[socket.clientId].push(socket)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (socket.user_id) {
|
|
155
|
+
this.emit('userStatus', { socket, user_id: socket.user_id, userStatus: 'on', organization_id });
|
|
156
|
+
|
|
157
|
+
if (!this.users.has(socket.user_id)) {
|
|
158
|
+
this.users.set(socket.user_id, [socket])
|
|
159
|
+
} else {
|
|
160
|
+
this.users.get(socket.user_id).push(socket)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
get(data) {
|
|
167
|
+
let sockets = []
|
|
168
|
+
if (data.broadcast !== false) {
|
|
169
|
+
let organization = this.organizations.get(data.organization_id)
|
|
170
|
+
if (organization) {
|
|
171
|
+
const clients = organization.clients
|
|
172
|
+
for (let client of Object.keys(clients)) {
|
|
173
|
+
if (data.broadcastSender === false && client === data.clientId) continue
|
|
174
|
+
|
|
175
|
+
if (data.broadcastClient)
|
|
176
|
+
sockets.push(clients[client][0])
|
|
177
|
+
else
|
|
178
|
+
sockets.push(...clients[client])
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
// TODO: requires a messageQueue that expires
|
|
182
|
+
console.log('organization could not be found', data)
|
|
183
|
+
}
|
|
184
|
+
} else if (data.broadcastSender !== false) {
|
|
185
|
+
sockets.push(data.socket)
|
|
186
|
+
}
|
|
187
|
+
return sockets
|
|
80
188
|
}
|
|
81
189
|
|
|
82
|
-
|
|
83
|
-
let organization_id = socket.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
let clients = this.clients.get(key)
|
|
87
|
-
const index = clients.indexOf(socket);
|
|
190
|
+
delete(socket) {
|
|
191
|
+
let organization_id = socket.organization_id
|
|
192
|
+
if (this.organizations.has(organization_id)) {
|
|
193
|
+
const clients = this.organizations.get(organization_id).clients;
|
|
88
194
|
|
|
89
|
-
|
|
90
|
-
clients.
|
|
195
|
+
// Check if the client exists
|
|
196
|
+
if (clients && clients[socket.clientId]) {
|
|
197
|
+
const client = clients[socket.clientId]
|
|
198
|
+
|
|
199
|
+
// Check if the socket exists in the client's sockets
|
|
200
|
+
const index = client.findIndex(item => item.id === socket.id);
|
|
201
|
+
if (index !== -1) {
|
|
202
|
+
client.splice(index, 1);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (!client.length) {
|
|
206
|
+
delete clients[socket.clientId];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!Object.keys(clients).length) {
|
|
210
|
+
this.organizations.delete(socket.organization_id);
|
|
211
|
+
this.emit('update.object', {
|
|
212
|
+
method: 'update.object',
|
|
213
|
+
array: 'organizations',
|
|
214
|
+
object: {
|
|
215
|
+
_id: organization_id, ['$pull.activeHost']: socket.socketUrl
|
|
216
|
+
},
|
|
217
|
+
organization_id
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
this.emit('mesh.update', {
|
|
221
|
+
url: socket.socketUrl,
|
|
222
|
+
organization_id
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
}
|
|
91
227
|
}
|
|
92
228
|
|
|
93
|
-
if (
|
|
94
|
-
this.
|
|
229
|
+
if (this.clients.has(socket.clientId)) {
|
|
230
|
+
const client = this.clients.get(socket.clientId)
|
|
231
|
+
const index = client.findIndex(item => item.id === socket.id);
|
|
232
|
+
if (index !== -1) {
|
|
233
|
+
client.splice(index, 1);
|
|
234
|
+
}
|
|
95
235
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
236
|
+
if (!client.length) {
|
|
237
|
+
this.clients.delete(socket.clientId);
|
|
238
|
+
}
|
|
99
239
|
}
|
|
100
240
|
|
|
241
|
+
if (this.clients.size === 0) {
|
|
242
|
+
this.organizations.delete(socket.organization_id);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
this.sockets.delete(socket.id);
|
|
246
|
+
|
|
247
|
+
if (socket.user_id) {
|
|
248
|
+
let sockets = this.users.get(socket.user_id)
|
|
249
|
+
if (sockets) {
|
|
250
|
+
const index = sockets.findIndex(item => item.id === socket.id);
|
|
251
|
+
if (index !== -1) {
|
|
252
|
+
sockets.splice(index, 1);
|
|
253
|
+
}
|
|
254
|
+
if (!sockets.length) {
|
|
255
|
+
this.users.delete(socket.user_id);
|
|
256
|
+
this.emit('userStatus', { socket, user_id, status: 'off', organization_id });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
101
260
|
}
|
|
102
261
|
|
|
103
|
-
async onMessage(
|
|
262
|
+
async onMessage(socket, message) {
|
|
104
263
|
try {
|
|
105
|
-
const organization_id = socket.
|
|
264
|
+
const organization_id = socket.organization_id
|
|
106
265
|
|
|
107
266
|
this.emit("setBandwidth", {
|
|
108
267
|
type: 'in',
|
|
@@ -110,35 +269,38 @@ class SocketServer extends EventEmitter {
|
|
|
110
269
|
organization_id
|
|
111
270
|
});
|
|
112
271
|
|
|
113
|
-
|
|
114
|
-
if (active === false)
|
|
272
|
+
if (this.organizations.has(organization_id) && !this.organizations.get(organization_id).status)
|
|
115
273
|
return this.send({ socket, method: 'Access Denied', balance: 'Your balance has fallen bellow 0' })
|
|
116
274
|
|
|
117
275
|
let data = JSON.parse(message)
|
|
118
|
-
|
|
119
276
|
if (data.method) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
277
|
+
if (data.method === 'region.added' || data.method === 'region.removed')
|
|
278
|
+
console.log('data.method: ', data.method)
|
|
279
|
+
|
|
280
|
+
if (socket.user_id && socket.expires && new Date().getTime() >= socket.expires) {
|
|
281
|
+
socket.user_id = socket.expires = null
|
|
282
|
+
this.send({ socket, method: 'updateUserStatus', userStatus: 'off', socketId: data.socketId, organization_id })
|
|
283
|
+
}
|
|
123
284
|
|
|
124
285
|
if (this.authorize) {
|
|
286
|
+
if (!this.sockets.has(socket.id)) {
|
|
287
|
+
if (!this.organizations.get(organization_id).status)
|
|
288
|
+
return this.send({ socket, method: 'Access Denied', balance: 'Your balance has fallen bellow 0' })
|
|
289
|
+
}
|
|
290
|
+
|
|
125
291
|
data.socket = socket
|
|
126
292
|
|
|
127
|
-
|
|
128
|
-
const authorized = await this.authorize.check(data, user_id)
|
|
293
|
+
const authorized = await this.authorize.check(data, socket.user_id)
|
|
129
294
|
if (authorized.storage === false) {
|
|
130
295
|
data.database = process.env.organization_id
|
|
131
296
|
data.organization_id = process.env.organization_id
|
|
132
297
|
|
|
133
|
-
const authorized2 = await this.authorize.check(data, req, user_id)
|
|
298
|
+
const authorized2 = await this.authorize.check(data, req, socket.user_id)
|
|
134
299
|
if (!authorized2 || authorized2.error) {
|
|
135
300
|
return this.send({ socket, method: 'Access Denied', authorized2, ...data })
|
|
136
301
|
}
|
|
137
302
|
} else if (!authorized || authorized.error) {
|
|
138
|
-
|
|
139
|
-
this.send({ socket, method: 'updateUserStatus', userStatus: 'off', clientId: data.clientId, organization_id })
|
|
140
|
-
|
|
141
|
-
return this.send({ method: 'Access Denied', authorized, ...data })
|
|
303
|
+
return this.send({ socket, method: 'Access Denied', authorized, ...data })
|
|
142
304
|
}
|
|
143
305
|
// dburl is true and db does not have 'keys' array
|
|
144
306
|
// action: syncCollection data{array: 'keys', object[]}
|
|
@@ -150,15 +312,6 @@ class SocketServer extends EventEmitter {
|
|
|
150
312
|
if (authorized.authorized)
|
|
151
313
|
data = authorized.authorized
|
|
152
314
|
|
|
153
|
-
if (user_id) {
|
|
154
|
-
if (!socket.config.user_id) {
|
|
155
|
-
socket.config.user_id = user_id
|
|
156
|
-
this.emit('userStatus', { socket, method: 'userStatus', user_id, userStatus: 'on', organization_id });
|
|
157
|
-
}
|
|
158
|
-
} else {
|
|
159
|
-
this.send({ socket, method: 'updateUserStatus', userStatus: 'off', clientId: data.clientId, organization_id })
|
|
160
|
-
}
|
|
161
|
-
|
|
162
315
|
this.emit(data.method, data);
|
|
163
316
|
|
|
164
317
|
}
|
|
@@ -168,85 +321,77 @@ class SocketServer extends EventEmitter {
|
|
|
168
321
|
}
|
|
169
322
|
}
|
|
170
323
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
let organization_id = socket.config.organization_id;
|
|
176
|
-
let url = `/${this.prefix}/${organization_id}`;
|
|
177
|
-
|
|
178
|
-
let namespace = data.namespace;
|
|
179
|
-
if (namespace) {
|
|
180
|
-
url += `/${namespace}`
|
|
181
|
-
}
|
|
324
|
+
async send(data) {
|
|
325
|
+
// const socket = this.sockets.get(data.socketId)
|
|
326
|
+
const socket = data.socket
|
|
182
327
|
|
|
328
|
+
if (data.sync) {
|
|
329
|
+
if (!data.object || !data.object.length)
|
|
330
|
+
return
|
|
183
331
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
rooms = [rooms]
|
|
188
|
-
for (let room of rooms) {
|
|
189
|
-
let url = url;
|
|
190
|
-
url += `/${room}`;
|
|
332
|
+
for (let i = 0; i < data.object.length; i++) {
|
|
333
|
+
data.object[i].data._id = data.object[i]._id
|
|
334
|
+
data.object[i].data.sync = true
|
|
191
335
|
|
|
192
|
-
this.
|
|
336
|
+
const authorized = await this.authorize.check(data.object[i].data, socket.user_id)
|
|
337
|
+
if (authorized && authorized.authorized)
|
|
338
|
+
socket.send(JSON.stringify(authorized.authorized));
|
|
339
|
+
else
|
|
340
|
+
socket.send(JSON.stringify(data.object[i].data));
|
|
193
341
|
}
|
|
194
342
|
} else {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
343
|
+
const sent = []
|
|
344
|
+
|
|
345
|
+
const authorized = await this.authorize.check(data, socket.user_id)
|
|
346
|
+
if (authorized && authorized.authorized)
|
|
347
|
+
data = authorized.authorized
|
|
348
|
+
|
|
349
|
+
if (!data.method.startsWith('read.') || data.log) {
|
|
350
|
+
let object = { url: socket.socketUrl, data }
|
|
351
|
+
delete object.socket
|
|
352
|
+
this.emit('create.object', {
|
|
353
|
+
method: 'create.object',
|
|
354
|
+
array: 'message_log',
|
|
355
|
+
object,
|
|
356
|
+
organization_id: data.organization_id
|
|
357
|
+
});
|
|
358
|
+
}
|
|
198
359
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
let responseData = JSON.stringify(data);
|
|
216
|
-
client.send(responseData);
|
|
217
|
-
|
|
218
|
-
if (socket.config && socket.config.organization_id)
|
|
219
|
-
this.emit("setBandwidth", {
|
|
220
|
-
type: 'out',
|
|
221
|
-
data: responseData,
|
|
222
|
-
organization_id: socket.config.organization_id
|
|
223
|
-
})
|
|
224
|
-
}
|
|
360
|
+
let sockets = this.get(data);
|
|
361
|
+
|
|
362
|
+
delete data.socket
|
|
363
|
+
|
|
364
|
+
for (let i = 0; i < sockets.length; i++) {
|
|
365
|
+
const authorized = await this.authorize.check(data, sockets[i].user_id)
|
|
366
|
+
if (authorized && authorized.authorized)
|
|
367
|
+
sockets[i].send(JSON.stringify(authorized.authorized));
|
|
368
|
+
else
|
|
369
|
+
sockets[i].send(JSON.stringify(data));
|
|
370
|
+
sent.push(socket.clientId)
|
|
371
|
+
this.emit("setBandwidth", {
|
|
372
|
+
type: 'out',
|
|
373
|
+
data: authorized.authorized || data,
|
|
374
|
+
organization_id: socket.organization_id
|
|
375
|
+
})
|
|
225
376
|
}
|
|
226
|
-
}
|
|
227
377
|
|
|
378
|
+
// TODO: sent is an array of clientId's so that notification can send to subscribed clients that are not currently connected
|
|
379
|
+
this.emit("notification", { sent })
|
|
380
|
+
}
|
|
228
381
|
}
|
|
229
382
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
383
|
+
getConfigFromUrl(pathname) {
|
|
384
|
+
const path = pathname.split("/");
|
|
385
|
+
if (path[2]) {
|
|
386
|
+
path[2] = decodeURIComponent(path[2]);
|
|
387
|
+
path[2] = JSON.parse(path[2]) || {};
|
|
235
388
|
}
|
|
236
|
-
if (path.length > 0) {
|
|
237
|
-
params.type = path[1];
|
|
238
|
-
params.organization_id = path[2]
|
|
239
|
-
}
|
|
240
|
-
return params
|
|
241
|
-
}
|
|
242
389
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return url.host;
|
|
247
|
-
} else if (req.headers.host && req.headers.host !== 'null') {
|
|
248
|
-
return req.headers.host;
|
|
390
|
+
const config = {
|
|
391
|
+
organization_id: path[1],
|
|
392
|
+
...path[2]
|
|
249
393
|
}
|
|
394
|
+
return config
|
|
250
395
|
}
|
|
251
396
|
|
|
252
397
|
}
|
package/src/mesh.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const socket = require('@cocreate/socket-client')
|
|
2
|
+
const crud = require('@cocreate/crud-client')
|
|
3
|
+
const EventEmitter = require('events');
|
|
4
|
+
const eventEmitter = new EventEmitter();
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const organizations = {}
|
|
8
|
+
const urls = new Map()
|
|
9
|
+
const servers = {}
|
|
10
|
+
|
|
11
|
+
async function addServer(data) {
|
|
12
|
+
if (!servers[data.url])
|
|
13
|
+
servers[data.url] = { [data.serverId]: { [data.organization_id]: true } }
|
|
14
|
+
else
|
|
15
|
+
servers[data.url][data.serverId][data.organization_id] = true
|
|
16
|
+
|
|
17
|
+
// TODO: needs to get orgaizations activeRegions
|
|
18
|
+
let activeRegions = await crud.send({
|
|
19
|
+
method: 'read.object',
|
|
20
|
+
array: 'organizations',
|
|
21
|
+
object: { _id: data.organization_id },
|
|
22
|
+
organization_id: data.organization_id
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
console.log('mesh activeRegions: ', activeRegions)
|
|
26
|
+
// socket.send({
|
|
27
|
+
// method: 'region.added',
|
|
28
|
+
// host: data.url,
|
|
29
|
+
// activeRegions: '',
|
|
30
|
+
// serverId: data.serverId,
|
|
31
|
+
// broadcast: false,
|
|
32
|
+
// broadcastSender: false,
|
|
33
|
+
// organization_id: data.organization_id
|
|
34
|
+
// })
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function deleteServer(data) {
|
|
38
|
+
delete servers[data.url][data.serverId][data.organization_id]
|
|
39
|
+
if (!Object.keys(servers[data.url][data.serverId]).length)
|
|
40
|
+
delete servers[data.url][data.serverId]
|
|
41
|
+
if (!Object.keys(servers[data.url]).length) {
|
|
42
|
+
console.log('mesh deleteServer: ', data.url)
|
|
43
|
+
|
|
44
|
+
// socket.send({
|
|
45
|
+
// method: 'region.removed', // delete.region
|
|
46
|
+
// host: data.url,
|
|
47
|
+
// serverId: data.serverId,
|
|
48
|
+
// organization_id: data.organization_id
|
|
49
|
+
// })
|
|
50
|
+
socket.delete(data.url)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
socket.listen('region.added', function (data) {
|
|
56
|
+
addServer(data)
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
socket.listen('region.removed', function (data) {
|
|
60
|
+
delete servers[data.url][data.serverId]
|
|
61
|
+
if (!Object.keys(servers[data.url]).length)
|
|
62
|
+
socket.delete(data.url)
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
eventEmitter.on('mesh.create', addServer);
|
|
66
|
+
eventEmitter.on('mesh.delete', deleteServer);
|
|
67
|
+
|
|
68
|
+
// eventEmitter.emit('customEvent', 'Hello, Node.js!');
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
// let response = await crud.send(request)
|