Matthew Dean

Updating Roblox Game Servers in Realtime with HTTP Long Polling

Scenario

Let’s say you want to notify a game server immediately when some state outside of the game server changes. Here are some example use cases:

You can use a technique called HTTP long polling to accomplish this. The basic idea is that you send an HTTP request to your web server. Instead of the web server responding immediately, it waits until there is an update and then sends back a response. If the request takes longer than say 60 seconds the server will abort the request anyway.

Here is an example of what the server-side code might look like (node.js):

var EventEmitter = require('events').EventEmitter
var messageBus = new EventEmitter()
messageBus.setMaxListeners(500)

var express = require('express')
var app = express()
var timeout = 30 * 1000 // 30 seconds in milliseconds

var bodyParser = require('body-parser')
app.use(bodyParser.json())

app.set('port', (process.env.PORT || 80))

app.get('/', function(req, res) {
  function listener(data) {
    res.json({ updates: true, data: data})
  }
  messageBus.once('message', listener)
  setTimeout(function() {
    messageBus.removeListener('message', listener)
    res.json({ updates: false, data: null })
  }, timeout)
})

app.post('/', function(req, res) {
  messageBus.emit('message', res.body)
})

app.listen(app.get('port'))

And here is the Roblox Lua code:

local httpService = game:GetService("HttpService")
local url = "https://api.example.com/"

while true do
  local success, result = pcall(function() return httpService:GetAsync(url) end)
  if success then
    local data = httpService:JSONDecode(result)
    if data.updates then
      -- do something with the data
    end
  else
    warn("error while fetching")
    wait(10)
  end
end