-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapp.js
More file actions
121 lines (94 loc) · 4.18 KB
/
Copy pathapp.js
File metadata and controls
121 lines (94 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// NodeJS+Express+Socket.IO Proof of Concept
// Hacked on November 19th, 2011 by Dave Falkenburg
//
// This code sketch is intended to demonstrate a lightweight server implementation
// for shared state management utilizing Javascript on both the client and the server.
// Simplified layoutState
//
// In our contrived example, we have 3 turnouts, with the following initial states.
// In the real world, this should or could be in a database or key-value server, but
// for now we're just going to use a javascript array of objects for this demo.
var layoutState = [
{id:'NT1',state:'thrown'},
{id:'NT2',state:'normal'},
];
// Our HTTP server is just an Express web server object fused with a socket.io
// server. The socket.io module is where most of the real magic lives, it is a
// package which supports connections via WebSockets, long-lived XMLHttpRequests,
// or worst case Adobe Flash sockets (ick).
var express = require('express')
var app = express.createServer();
var io = require('socket.io').listen(app);
var jmri = require('./jmri.js');
// Our server running on port 3000, and we'll serve up static files for now.
app.configure( function() {
app.use(express.logger());
app.use(express.bodyParser());
});
app.configure('development', function(){
app.use(express.static(__dirname + '/static'));
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
var oneYear = 31557600000;
app.use(express.static(__dirname + '/static', { maxAge: oneYear }));
app.use(express.errorHandler());
});
app.listen(3000);
// socket.io Callbacks
//
// Allow web client(s) to connect using a socket interface. The client and server
// ship streamed JSON objects back and forth to get the job done.
//
// Whenever a client connects, it is given a copy of the entire layout state, and
// a callback is installed for that client which allows individual elements to be
// "clicked" via a JSON blob send from client to server. In response to the click,
// the server broadcasts the changed state back to ALL clients.
//
// NOTE: In the real world case, the client should indicate what subset of the state
// they are interested in, but for now we just give every client the full state.
io.configure('production', function(){
io.enable('browser client minification'); // send minified client
io.enable('browser client etag'); // enable caching
io.enable('browser client gzip'); // gzip the file
io.set('log level', 1); // disable debug logs
});
io.configure('development', function(){
io.set('transports', ['websocket']);
});
io.sockets.on('connection', function (socket) {
// whenever a new client connects, send the entire layout state
socket.emit('update', layoutState);
// Install a callback for whenever a client sends a 'click' message. In a the real
// implementation, we would most likely support primitives like "get/set" instead.
socket.on('click',function parseClickMessage(data) {
var changedState = [];
// Incomming data is a JSON object of the form "{'click':<id>}"
var clickTargetId = data['click'];
// Walk through the layoutState array to toggle the state
for (i in layoutState) {
if (layoutState[i].id == clickTargetId) {
if (layoutState[i].state == 'thrown') {
layoutState[i].state = 'normal';
} else {
layoutState[i].state = 'thrown';
}
changedState.push(layoutState[i]);
}
}
for (i in changedState) {
var turnoutState = (changedState[i].state === 'normal' ? '2' : '4');
var turnoutName = changedState[i].id;
// talk to the jmri server
jmri.xmlioRequest('10.0.0.25',12080,{'xmlio':{'turnout':{'name':turnoutName,'set':turnoutState}}},function (data) {
console.log('got '+data);
});
}
// Send the changed layout elements to all the clients.
socket.broadcast.emit('update', changedState);
// NOTE: We need to specifically reply to the requesting client,
// because socket.broadcast.emit skips that by default.
socket.emit('update', changedState);
}
);
});