Пример #1
0
  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)
    })
  }
Пример #2
0
 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);
     });
 }
Пример #3
0
	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);
	}
Пример #4
0
      initCB = () => {
        broker = new WebSocketServer({server}, {perMessageDeflate: false});

        broker.on('connection', socket => this.onConnection(socket));
        broker.on('error', error => this.onError(error));
      };
Пример #5
0
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
}
Пример #6
0
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);
    }
  };
}
Пример #7
0
const WebSocketServer = require('uws').Server;
const wss = new WebSocketServer({ port: 1307 });

wss.on('connection', (ws) => {
    ws.on('message', (message) => {
        ws.send(message);
    });
});
Пример #8
0
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
}
Пример #9
0
// 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)