Created
October 17, 2018 00:47
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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