platypush-app/service/server.js

102 lines
2.7 KiB
JavaScript

const websocket = require('websocket').server
const http = require('http')
const express = require('express')
const path = require('path')
const bonjour = require('bonjour')()
const app = express(),
bodyParser = require('body-parser'),
wsPort = 3080,
httpPort = 18080,
sockets = new Set(),
services = {}
// Initialize HTTP websocket transport
const server = http.createServer(function(request, response) {
console.log(`[${(new Date())}] Received request for ${request.url}`)
response.writeHead(404)
response.end()
})
server.listen(wsPort, '127.0.0.1', () => {
console.log(`[${(new Date())}] Websocket transport listening on port ${wsPort}`)
})
// Initialize Express web service
app.use(bodyParser.json())
app.use(express.static(path.join(__dirname, '../webapp/dist')))
app.get('/', (req,res) => {
res.sendFile(path.join(__dirname, '../webapp/dist/index.html'))
})
app.listen(httpPort, () => {
console.log(`Web server listening on port ${httpPort}`)
})
// Initialize websocket service
wsServer = new websocket({
httpServer: server,
autoAcceptConnections: false,
})
function requestAllowed(request) {
if (request.resource !== '/services') {
console.log(`Unknown web socket resource: ${request.resource}`)
return false
}
if (request.remoteAddress !== '127.0.0.1' && request.remoteAddress !== '::1') {
console.log('Websocket requests are only allowed from localhost')
return false
}
return true
}
wsServer.on('request', (request) => {
if (!requestAllowed(request))
return
const connection = request.accept('', request.origin)
console.log(`[${(new Date())}] Connection accepted.`)
sockets.add(connection)
sendServiceInfo(connection)
connection.on('message', function(message) {
if (message.type === 'utf8') {
if (message.utf8Data === 'sync') {
console.log('Received sync request')
sendServiceInfo(connection)
} else {
console.log(`Unsupported command: ${message.utf8Data}`)
}
}
})
connection.on('close', function() {
console.log(`[${(new Date())}] Peer ${connection.remoteAddress} disconnected.`)
})
})
// Initialize the Zeroconf/Bonjour service
function discoverServices() {
bonjour.find({type: 'platypush-http'}, (service) => {
services[service.name] = service
for (const socket of sockets) {
sendServiceInfo(socket, service)
}
})
}
function sendServiceInfo(sock, service) {
const srvs = service ? [service] : Object.values(services)
for (const srv of srvs)
sock.sendUTF(JSON.stringify(srv))
}
discoverServices()
setInterval(discoverServices, 10000)