pierreavn
pierreavn

Reputation: 607

Is there a better solution than socket.io for slow-speed in-game chat?

I am creating a browser game with node.js (backend api) and angular (frontend). My goal is to implement an in-game chat to allow communication between players on the same map. The chat is not an essential part of the game, so messages don't need to be instant (few seconds of latency should be ok). It is just a cool feature to talk some times together.

A good solution should be to implement socket.io to have real-time communication. But as chat is not an essential component and is the only thing which will require websockets, i'm wondering if there is not an alternative to avoid server overload with sockets handling.

I thinked about polling every 2 or 3 seconds my REST API to ask for new messages, but it may overload server the same way... What are your recommandations?

Thank you for your advices

Upvotes: 1

Views: 946

Answers (1)

O. Jones
O. Jones

Reputation: 108686

There's a pretty cool package called signalhub. It has a nodejs server component and stuff you can use in your users' browsers. It uses a not-so-well-known application of the http (https) protocol called EventSource. EventSource basically opens persistent http (https) connections to a web server.

It's a reliable and lightweight setup. (The README talks about WebRTC signalling, but it's useful for much more than that.)

On the server side, a simple but effective server setup might look like this:

module.exports = function makeHubServer (port) {
  const signalhubServer = require('signalhub/server')
  const hub = signalhubServer({ maxBroadcasts: 0 })

  hub.on('subscribe', function (channel) {
    /* you can, but don't have to, keep track of subscriptions here. */
  })

  hub.on('publish', function (channel, message) {
    /* you can, but don't have to, keep track of messages here. */
  })

  hub.listen(port, null, function () {
    const addr = hub.address()
  })
  return hub
}

In a browser you can do this sort of thing. It user GET to open a persistent EventSource to receive messages. And, when it's time to send a message, it POSTs it.

And, Chromium's devtools Network tab knows all about EventSource connections.

  const hub = signalhub('appname', [hubUrl])
  ...
  /* to receive */
  hub.subscribe('a-channel-name')
    .on('data', message => {
      /* Here's a payload */
      console.log (message)
    })
  ...
  /* to send */
  hub.broadcast('a-channel-name', message)

Upvotes: 1

Related Questions