123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- var express = require('express');
- var http = require('http')
- var io = require('socket.io');
- var net = require('net');
- var app_debugging = express();
- var http_debugging = http.Server(app_debugging)
- var io_debugging = io(http_debugging);
- var app_vis = express();
- var http_vis = http.Server(app_vis)
- var io_vis = io(http_vis);
- var queue = []
- // serve GET requests of client for debugging interface
- app_debugging.get('*', function(req, res) {
- if ( req.url == '/' ) {
- res.sendFile(__dirname + '/debugging_environment.html');
- } else if ( req.url.match(/\.js$/)
- || req.url.match(/\.html$/)
- || req.url.match(/\.css$/)
- || req.url.match(/\.png$/)
- ) {
- res.sendFile(__dirname + req.url);
- }
- });
- // user connects on the debugging interface: queue all incoming messages and tag them as debug messages
- io_debugging.on('connection', function(socket){
- console.log('A user connected!');
-
- socket.on('message', function(msg) {
- queue.push('dbg_' + msg);
- })
- });
- http_debugging.listen(9595, function() {
- console.log('Listening for user on port 9595');
- });
- // serve GET requests of client for visualization interface
- app_vis.get('*', function(req, res) {
- if ( req.url == '/' ) {
- res.sendFile('/visualization_server.html', {root: '../'});
- } else if ( req.url.match(/\.js$/)
- || req.url.match(/\.html$/)
- || req.url.match(/\.css$/)
- || req.url.match(/\.png$/)
- ) {
- res.sendFile(req.url, {root: '../'});
- }
- });
- // user connects on the visualization interface: queue all incoming messages and tag them as visualization messages
- io_vis.on('connection', function(socket){
- console.log('A user connected!');
-
- socket.on('message', function(msg) {
- queue.push('vis_' + msg);
- })
- });
- http_vis.listen(9696, function() {
- console.log('Listening for user on port 9696');
- });
- String.prototype.endsWith = function(suffix) {
- return this.indexOf(suffix, this.length - suffix.length) !== -1;
- };
- /*
- This is the server that ties debugging UI - visualization UI - debuggable simulator together.
- It waits for the simulation client to connect on port 9999 and coordinates all message traffic between the three components.
- */
- net.createServer(function(sock) {
- console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
-
- buffer = '';
-
- // Protocol: each message ends with a newline. Buffers messages until the buffer ends with a new line, in case a message is only partially sent.
- sock.on('data', function(data) {
- buffer += String(data);
- if (buffer.endsWith('\n')) {
- String(buffer).split('\n').forEach(function(entry) {
- if (entry != '') {
- try {
- msg = eval(entry); // TODO: probably not a very good idea, msg = JSON.parse(entry); is better but doesn't work with Infinity
- } catch (err) {
- throw err;
- }
- if (msg[0] == "VIS") {
- // visualization messages are sent to the visualization interface
- io_vis.emit('msg', JSON.stringify(msg.slice(1)));
- } else if (msg[0] == "DBG") {
- // debugging messages (state updates, for example) are sent to the debugging interface
- io_debugging.emit('msg', JSON.stringify(msg.slice(1)));
- }
- }
- })
- buffer = '';
- }
-
- });
-
- sock.on('close', function(data) {
- console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
- });
-
- sock.on('error', function(error) {
- console.log('ERROR: ' + error);
- });
-
- /*
- Every 5 milliseconds, check whether any message was sent by the user from the debugging interface and/or the visualization interface. If so, pass it on.
- In case of a message from the debugging interface: send it to the simulator, although if it's a reset, also forward to the visualization.
- In case of a message from the visualization interface: only send it to the debugger when it's an interrupt. Send it to the debugging interface if it's a message wanting to select an entity.
- */
- setInterval(function() {
- while (queue.length) {
- var msg = queue.pop();
- var msg_head = msg.substring(0, 4)
- if (msg_head == "dbg_") {
- var parsed_msg = eval('(' + msg.substring(4) + ')');
- // forward selected messages to visualization
- if (parsed_msg["parameters"].length && parsed_msg["parameters"][0] == "reset") {
- io_vis.emit('msg', msg);
- }
- // forward to simulator
- sock.write(msg + '\n');
- } else if (msg_head == "vis_") {
- if (msg.substring(4).lastIndexOf('INTERRUPT', 0) == 0) {
- // forward to simulator
- sock.write(msg + '\n');
- } else {
- var parsed_msg = eval('(' + msg.substring(4) + ')');
- // forward selected messages to debugging interface
- if (parsed_msg["name"] == "select_instance") {
- io_debugging.emit('msg', msg);
- }
- }
- }
- }
- }, 5)
-
- }).listen(9999, '127.0.0.1');
- console.log('Listening for simulator on localhost:9999');
|