Skip to content

Instantly share code, notes, and snippets.

@timetocode
Created October 17, 2018 00:47
Show Gist options
  • Save timetocode/547aa97a8860ff1e53daf2d7fc4e9324 to your computer and use it in GitHub Desktop.
Save timetocode/547aa97a8860ff1e53daf2d7fc4e9324 to your computer and use it in GitHub Desktop.
Example of using tls-json + express to create a master server listing service.
const fs = require('fs')
const express = require('express')
const config = require('config')
const TLSServer = require('tls-json').Server
const Router = require('express-promise-router')
const servers = require('../servers')
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
// game instances connected to the master server
const clients = new Map()
let instanceListing = []
let invalidateCache = false
let cacheTimestamp = Date.now()
// rebuilds the public-facing server list
const rebuildListing = function () {
const now = Date.now()
// cache logic: don't rebuild the list unless it has been 500 ms
if (now > cacheTimestamp + 500 || invalidateCache) {
cacheTimestamp = now
invalidateCache = false
instanceListing = []
clients.forEach(client => {
const listing = {}
for (prop in client) {
if (prop !== 'socket') {
listing[prop] = client[prop]
}
}
instanceListing.push(listing)
})
}
}
const server = new TLSServer({
options: {
key: fs.readFileSync(config.API_KEY),
cert: fs.readFileSync(config.API_CERT)
},
password: config.API_PASSWORD
})
server.on('authenticated', (id, socket) => {
let ip = socket.remoteAddress
if (ip.startsWith("::ffff:")) {
ip = ip.slice(7)
}
const subdomain = servers.byIp(ip)
// create the initial listing, id, socket, ip, subdomain
clients.set(id, { id, socket, ip, subdomain })
})
server.on('close', id => {
invalidateCache = true
clients.delete(id)
})
server.on('error', (id, err) => {
console.log(`client(${id})::error::${err}`)
})
server.on('message', (id, message) => {
if (message.type === 'list') {
// copy the submitted listing to our records
Object.assign(clients.get(id), message.listing)
}
})
server.on('request', (id, req, res) => { })
server.listen(config.MASTER_API_PORT, () => {
console.log(`MASTER API listening on ${config.MASTER_API_PORT}`)
})
const router = new Router()
// public server listing
router.get('/servers', async (req, res) => {
rebuildListing()
res.send(instanceListing)
})
app.use(router)
app.listen(7999, () => {
console.log(`MASTER HTTP listening on 7999`)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment