restify = require 'restify' WebSocketServer = require('ws').Server util = require 'util' class Cache data = [] push : (id, message) -> data[id] = [] if not data[id]? data[id].push message getMessage : (id, idx) -> data[id][idx] getIds : -> Object.keys data getLatestId : -> @getIds().reduce ((a,e) -> if a < e then e else a),null getAllMessagesLatestIdFormatted : -> latest = @getLatestId() @getAllMessagesForId latest getAllMessagesForId : (id) -> if id? data[id] .map (s) -> "\"#{s}\"" .join(',\n') else "" getStorageStatus : -> ids = @getIds() total = ids.reduce ((a,e) -> a + data[e].length),0 {ids,total} class DebugServer cache = new Cache constructor : (@port=9000) -> @server = restify.createServer name : "SafeDispatch Map Debug Server" @server.pre restify.pre.sanitizePath() @server.use restify.queryParser() @server.use restify.CORS {origins: ['*']} @server.use restify.fullResponse() @server.use restify.urlEncodedBodyParser() @addRoutes() @server.listen @port, () => console.log "Server is listening on port #{@port}.\nStarted in `#{__dirname}`." @initWebSocketServer @server initWebSocketServer : () -> @ws = new WebSocketServer @server @ws.on "connection", (ws) -> console.log "new connection from #{ws.upgradeReq.connection.remoteAddress}" ws.on "error", -> ws.close() ws.on "close", -> console.log "Connection closed!!!" ws.on "message", (message) -> console.log message if message.toLowerCase() is 'start' ws.send "Starting on #{new Date()}" # idx = 0; # id = setInterval -> # if (idx < queue.length) # ws.send queue[idx++], (error) -> clearInterval(id) if error? # ,200 addRoutes : () -> #server static files for everything not matching api @server.get /^(?!\/api).+/, restify.serveStatic directory : "#{__dirname}/../.." default : 'SfmbMapsMainMap.html' @server.get "api/status", (req, res) -> res.send {status : 'OK', storage : cache.getStorageStatus()} @server.get "api/commands/:id", (req, res) -> {params:{id}} = req if id == 'latest' rez = cache.getAllMessagesLatestIdFormatted() else rez = cache.getAllMessagesForId id res.setHeader 'content-type', 'text/plain' res.send rez @server.post "api/command/:id/:command", (req, res) -> {params:{id,command}} = req; console.log "#{id}:#{command}" cache.push id, command res.send {response : 'OK'} # i = 0 # setInterval (-> queue.push "Message #{i++}"), 4000 new DebugServer ### To do: - intelligent management of the debug-server on the client - don't consume resources if it's not available - don't clog memory with cache if it runs for a long time - add an identifier for an instance, timestamp is the likeliest candidate since I can't get the IP - add a way to connect only to a particular instance - a new page with links to each connected instances - the SfmbMainMap html will parse it's own href and extract the id to connect to - you need to send the user's actions too, like scroll, pan, clicks, open InfoBubble - the 2 connected apps need to synchronize and there are a lot of things to be put in order For now, 7 september, I think it's way too much to do and I will leave it be for the moment. ###