Created
October 17, 2018 01:00
-
-
Save timetocode/0bd1ca783fcb97457083e7091b26368e to your computer and use it in GitHub Desktop.
Example of using tls-json + express to create a master server listing service. master.js uses tls-json to listen over tls and accept connections + listing data from other services that connect, meanwhile instance.js shows a snippet of a game server that is listing itself on the master server. server.json is an example of what the http call to th…
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
// from the game instance | |
const master = new TLSClient({ | |
options: { | |
ca: fs.readFileSync(config.API_CERT), | |
}, | |
reconnectInterval: 2000, | |
host: config.MASTER_API_HOST, | |
port: config.MASTER_API_PORT, | |
password: config.API_PASSWORD | |
}) | |
master.on('authenticated', () => { | |
syncListing() | |
}) | |
master.on('message', message => { ... }) | |
master.on('close', () => { ... }) | |
master.on('error', err => { ... }) | |
function syncListing() { | |
master.send({ | |
type: 'list', | |
listing: { | |
version: config.GAME_VERSION, | |
port: 8001, | |
currentPlayers: 0, // these would be variables | |
maxPlayers: 100, | |
mode: 'idle', | |
etc: 'anything' | |
} | |
}) | |
} | |
function updatePlayerCount() { | |
master.send({ | |
type: 'list', | |
listing: { | |
currentPlayers: 10 | |
} | |
}) | |
} |
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`) | |
}) |
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
[ | |
{"id":0,"ip":"127.0.0.1","version":"0.0.3","mode":"idle","port":8001,"currentPlayers":0,"maxPlayers":0}, | |
{"id":1,"ip":"127.0.0.1","version":"0.0.3","mode":"idle","port":8002,"currentPlayers":0,"maxPlayers":0} | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment