constructor(httpServer) { super() const wss = new WebSocketServer({ server: httpServer, }) this.server = wss const sockets = new Map() this.sockets = sockets wss.on("connection", (socket) => { const connection = new Connection(socket) sockets.set(socket, connection) connection.on("close", () => { sockets.delete(socket) }) super.emit("connection", connection) }) }
init() { this.webSocketServer = new Server({ perMessageDeflate: this.perMessageDeflate, verifyClient: (info) => this.validateURLQuery(info), server: this.server, }); const serverListening = this.server || this.webSocketServer; serverListening.on('listening', () => WebSocketBuilder.listenUrl.next(this.url)); this.webSocketServer.on('error', (err) => { WebSocketBuilder.listenUrl.next(''); this.onError(err); }); this.webSocketServer.on('connection', (ws) => { const { type, wcId, senderId, key } = this.readURLQuery(ws.upgradeReq.url); let webSocketBuilder; let wg = this.webGroups.get(wcId); if (type === Channel.WITH_MEMBER && (wg === undefined || wg.state === WebGroupState.LEFT)) { wg = new WebGroup(this.wcOptions); this.webGroups.set(wcId, wg); const wc = wcs.get(wg); if (this.leaveOnceAlone) { wc.onAlone = () => { wc.leave(); this.webGroups.delete(wcId); }; } wc.init(key, wcId); this.onWebGroup(wg); wc.onMyId(wc.myId); webSocketBuilder = wc.webSocketBuilder; } else if (wg !== undefined) { webSocketBuilder = wcs.get(wg).webSocketBuilder; } else { ws.close(); return; } webSocketBuilder.newWebSocket(ws, senderId, type); }); }
constructor(server) { this.server = server; this.wss = new WebSocketServer({ server: server.rest, path: '/gateway' }); this.wss.on('connection', this.onConnection.bind(this)); this.userMap = new Map(); this.packetHandlers = new Map(); for (const Handler of PACKET_HANDLERS) { const handler = new Handler(this); this.packetHandlers.set(handler.options.code, handler); } this.heartbeatInterval = setInterval(this.heartbeat.bind(this), 40e3); }
initCB = () => { broker = new WebSocketServer({server}, {perMessageDeflate: false}); broker.on('connection', socket => this.onConnection(socket)); broker.on('error', error => this.onError(error)); };
function setupWebSocketServer (server) { const wss = new WebSocketServer({ server, path: '/' }) // Handle socket connections. wss.on('connection', onConnection) // Setup RabbitMQ producer and consumer. const workExchange = Rabbit.getWorkExchangeProducer(SERVER_ID) Rabbit.getPublishConsumer(SERVER_ID, message => { // Broadcast once we receive a published message. if (!isValidPublishMessage(message)) { log(`id=${SERVER_ID} event=error msg='Got invalid publish message: ${JSON.stringify(message)}'`) return } const { payload, meta, session } = message let socket wss.clients.forEach(x => { if (x.id === meta.socketId) { socket = x return } }) if (socket) { // Make sure we decrease throttled messages for this socket. Throttle.dec(socket.id) // Upgrade / handshake this socket connetions if we get a session. if (session) { if (!session.userId || !session.email) { log(`id=${SERVER_ID} event=error msg='Got invalid session data: ${JSON.stringify(session)}'`) } else { // Upgrade this socket connection (i.e. perform a handshake) if a session object is found in reply. log(`id=${SERVER_ID} event=session email=${session.email} uid=${session.userId}`) socket.session = session } } if (payload.reply) { // Reply to single socket connected to this server. send(socket, payload.reply.topic, payload.reply.payload, meta) } } if (payload.broadcast) { // Broadcast to selected users connected to this server. broadcast(wss, payload.broadcast, meta) } }) // Print calls / second stats. Throttle.printStats() function onConnection (socket) { socket.id = Shortid.generate() socket.on('message', onMessage) socket.on('close', () => { const sid = socket.session ? socket.session.email : 'public' log(`id=${SERVER_ID} event=disconnect socket=${socket.id} sid=${sid}`) }) async function onMessage (json) { const sid = socket.session ? socket.session.email : 'public_' + Shortid.generate() const meta = { // Start timer when we receive a message. start: Date.now(), ms: 0, from: 'server', sid } try { const message = JSON.parse(json) if (typeof message !== 'object') throw new Error('Message is not an object') if (!message.topic) throw new Error('Message missing topic') if (!message.payload) throw new Error('Message missing payload') meta.requestId = message.meta ? message.meta.requestId : sid meta.socketId = socket.id meta.from = message.topic // Throttle incoming messages. Throttle.inc(socket.id) Throttle.throttle(socket.id) // Ack message at this point. ackMessage(socket, meta) log(`id=${SERVER_ID} event=recv topic=${message.topic} sid=${meta.sid}`) // Queue message for processing. const bindingKey = message.topic.split(':').join('.') await workExchange.produce(bindingKey, { message, meta, session: socket.session }) // And we’re done. } catch (err) { log('Error:', err) log(`id=${SERVER_ID} event=error source='${json}'`) send(socket, 'error', { message: err.message }, meta) } } } return wss }
export default function expressWs(app, httpServer, options = {}) { let server = httpServer; if (server === null || server === undefined) { /* No HTTP server was explicitly provided, create one for our Express application. */ server = http.createServer(app); app.listen = function serverListen(...args) { return server.listen(...args); }; } /* Make our custom `.ws` method available directly on the Express application. You should * really be using Routers, though. */ addWsMethod(app); /* Monkeypatch our custom `.ws` method into Express' Router prototype. This makes it possible, * when using the standard Express Router, to use the `.ws` method without any further calls * to `makeRouter`. When using a custom router, the use of `makeRouter` may still be necessary. * * This approach works, because Express does a strange mixin hack - the Router factory * function is simultaneously the prototype that gets assigned to the resulting Router * object. */ if (!options.leaveRouterUntouched) { addWsMethod(express.Router); } // allow caller to pass in options to WebSocketServer constructor const wsOptions = options.wsOptions || {}; wsOptions.server = server; const wsServer = new uws.Server(wsOptions); wsServer.on('connection', (socket, request) => { if ('upgradeReq' in socket) { request = socket.upgradeReq; } request.ws = socket; request.wsHandled = false; /* By setting this fake `.url` on the request, we ensure that it will end up in the fake * `.get` handler that we defined above - where the wrapper will then unpack the `.ws` * property, indicate that the WebSocket has been handled, and call the actual handler. */ request.url = websocketUrl(request.url); const dummyResponse = new http.ServerResponse(request); dummyResponse.writeHead = function writeHead(statusCode) { if (statusCode > 200) { /* Something in the middleware chain signalled an error. */ dummyResponse._header = ''; socket.close(); } }; app.handle(request, dummyResponse, () => { if (!request.wsHandled) { /* There was no matching WebSocket-specific route for this request. We'll close * the connection, as no endpoint was able to handle the request anyway... */ socket.close(); } }); }); return { app, getWss: function getWss() { return wsServer; }, applyTo: function applyTo(router) { addWsMethod(router); } }; }
const WebSocketServer = require('uws').Server; const wss = new WebSocketServer({ port: 1307 }); wss.on('connection', (ws) => { ws.on('message', (message) => { ws.send(message); }); });
export default function start() { const metrics = start_metrics ({ statsd: { ...configuration.statsd, prefix : 'realtime_service' } }) const visitor_tracker = new Visitor_tracker(metrics) visitor_tracker.report() const server = new WebSocket.Server({ port: configuration.realtime_service.websocket.port }) const user_connections = {} // Broadcasts to all server.broadcast = function broadcast(message) { server.clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send(message) } }) } server.on('connection', (socket) => { // log.info('Client connected. Total clients:', server.clients.length) socket.send_message = (message) => socket.send(JSON.stringify(message)) // Broadcasts to everyone else socket.broadcast = (message) => { server.clients.forEach((client) => { if (client !== socket && client.readyState === WebSocket.OPEN) { client.send(message) } }) } socket.on('close', async () => { try { // log.info('Client disconnected. Clients left:', server.clients.length) visitor_tracker.disconnected(socket) } catch (error) { log.error(error) } if (socket.user_id) { user_connections[socket.user_id].remove(socket) } }) socket.on('message', async (message) => { try { message = JSON.parse(message) } catch (error) { return log.error(error) } try { switch (message.command) { case 'initialize': // If a user connected (not a guest) // then store `userId` for push notifications. // Using an authentication token here // instead of simply taking `userId` out of the `message` // because the input can't be trusted (could be a hacker). if (message.token) { // (make sure `socket.user_id` is a `String`) // The token could be a JWT token (jwt.io) // and `authenticateUserByToken` function could // check the token's authenticity (by verifying its signature) // and then extract `userId` out of the token payload. const payload = verify_jwt(message.token, configuration.web_service_secret_keys, { ignoreExpiration: true }) console.log('@@@@@@@@@@@@@@', payload) socket.user_id = payload.sub socket.access_token_id = payload.refresh_token_id if (!user_connections[socket.user_id]) { user_connections[socket.user_id] = [] } user_connections[socket.user_id].push(socket) } const response = { command: 'initialized' } if (!socket.user_id) { socket.guest_id = message.guest } visitor_tracker.connected(socket) return socket.send_message(response) case 'active': // if (socket.user_id) // { // http.post // ( // `${address_book.user_service}/ping`, // undefined, // { headers: { Authorization: `Bearer ${socket.token}` } } // ) // } return visitor_tracker.active(socket) case 'inactive': return visitor_tracker.inactive(socket) default: return socket.send_message ({ status: 404, error: `Unknown command: ${message.command}` }) } } catch (error) { log.error(error) } }) }) server.on('error', (error) => { log.error(error) }) log.info(`Realtime service WebSocket is listening at port ${configuration.realtime_service.websocket.port}`) const result = { server, close: () => new Promise(resolve => server.close(resolve)), user_connections } return result }
// if sysdig is already running, use existing container. Otherwise, start a new one const sysdigContainerName = 'sysdig_container_hive' let sysdigProcess execa.shell(`docker ps | grep ${sysdigContainerName}`).then(isSysdigRunning => { console.info('tailing existing sysdig container') sysdigProcess = execa('docker', `logs --tail=0 -f ${sysdigContainerName}`.split(' ')) }) .catch(err => { console.error(err) console.info('starting a new sysdig container') sysdigProcess = execa('docker', `run -i --name ${sysdigContainerName} --rm --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro sysdig/sysdig sysdig -pc evt.type=accept`.split(' ')) }) // setup web socket configuration on top of webserver const server = http.createServer(app) const wss = new WebSocketServer({ server: server }) wss.on('connection', function (ws) { setInterval(ps, 5000) ws.on('message', message => { const parsedMessage = JSON.parse(message) switch (parsedMessage.type) { case 'run': const image = `${parsedMessage.data.image}` runContainer(image).then(() => { sendMessage('ran', {image}) ps() }) break case 'kill': console.log('killing container: ', parsedMessage.data.id)