Mercurial > hg > nodescore
comparison basictest.js @ 72:9af4250ff7d5
added file to test why static webserver doesnt work on home machine - using connect now instead of node-static this will be pushed into the main nodescore.js once its cleaned up
author | tzara <rc-web@kiben.net> |
---|---|
date | Sun, 27 Oct 2013 01:49:58 +0100 |
parents | |
children | 52e44ee1c791 |
comparison
equal
deleted
inserted
replaced
71:a1eacfae4fcf | 72:9af4250ff7d5 |
---|---|
1 /* | |
2 //////////////////////////////////////////// | |
3 | |
4 nodescore server | |
5 nodescore.kiben.net | |
6 nodescore@kiben.net | |
7 | |
8 //////////////////////////////////////////// | |
9 */ | |
10 | |
11 var sio = require('socket.io') | |
12 , http = require('http') | |
13 , ch = require('./chronometer') | |
14 , url = require('url') | |
15 , path = require('path') | |
16 , fs = require('fs') | |
17 , connect = require('connect') | |
18 , static = require('node-static'); | |
19 | |
20 var mimeTypes = { | |
21 "html": "text/html", | |
22 "jpeg": "image/jpeg", | |
23 "jpg": "image/jpeg", | |
24 "png": "image/png", | |
25 "js": "text/javascript", | |
26 "css": "text/css"}; | |
27 | |
28 var requirejs = require('requirejs'); | |
29 | |
30 requirejs.config({ | |
31 //Pass the top-level main.js/index.js require | |
32 //function to requirejs so that node modules | |
33 //are loaded relative to the top-level JS file. | |
34 nodeRequire: require, | |
35 findNestedDependencies: true | |
36 }); | |
37 | |
38 var pinging=0 | |
39 console.log("ping set to 0") | |
40 | |
41 // run webserver serving static html | |
42 //////////////////////////////////////////// | |
43 var httpServer = connect() | |
44 .use(connect.logger('dev')) | |
45 .use(connect.static('www')) | |
46 .use(function(req, res){ | |
47 res.end('404\n'); | |
48 }) | |
49 .listen(8890); | |
50 | |
51 //////////////////////////////////////////// | |
52 // connect to websockets | |
53 //////////////////////////////////////////// | |
54 | |
55 | |
56 io = sio.listen(httpServer) | |
57 , nicknames = {}; | |
58 | |
59 //var sequencer = require('./sequencer') | |
60 | |
61 io.set('log level', 4); // reduce logging | |
62 io.sockets.on('connection', function (socket) { | |
63 | |
64 socket.on('nickname', function (nick, fn) { | |
65 if (nicknames[nick]) { | |
66 fn(true); | |
67 } else { | |
68 fn(false); | |
69 nicknames[nick] = socket.nickname = nick; | |
70 socket.broadcast.emit('announcement', nick + ' connected'); | |
71 io.sockets.emit('nicknames', nicknames); | |
72 } | |
73 }); | |
74 | |
75 /// chat user messages to screens and to log file | |
76 // date format for filename | |
77 var da = new Date(); var dtstring = da.getFullYear()+ '-' + da.getMonth()+ '-' + da.getDate(); | |
78 //////////////////////// | |
79 /// log messages to file | |
80 socket.on('user message', function (msg) { | |
81 fs.open('logs/chatlog-'+dtstring+'.txt', 'a', 666, function( e, id ) { | |
82 //time format for message stamp | |
83 var dt = new Date();var timestring = dt.getHours() + ':' + dt.getMinutes() + ':' + dt.getSeconds(); | |
84 socket.broadcast.emit('user message', socket.nickname, msg); | |
85 var fs = require('fs'), str = msg; | |
86 fs.write( id, timestring+" " + socket.nickname + ": "+ msg+"\n", null, 'utf8', function(){}); | |
87 }); | |
88 }); | |
89 | |
90 //////////////////////////////////////////// | |
91 // chronometer + sequencer controls (all this should be modularised) | |
92 //////////////////////////////////////////// | |
93 | |
94 socket.on('stopWatch', function (state) { stopWatch(state);}); | |
95 socket.on('stopChr', function () { stopChr(); }); | |
96 socket.on('resetChr', function () { resetChr();}); | |
97 socket.on('startSeq', function () { startChr(); }); | |
98 var chronstate=0; | |
99 | |
100 // send the date/time every second | |
101 | |
102 xdatetime = setInterval(function () { | |
103 d = ch.xdateTime() | |
104 socket.broadcast.emit('dateTime', d) | |
105 socket.emit('dateTime', d) | |
106 }, 1000) | |
107 | |
108 ////////////////////////////// | |
109 // /* this should be moved to its own file chronometer.js | |
110 | |
111 function chronCtrl (state,interval){ | |
112 if (state==1){ console.log("chronControl....onestate") | |
113 var date = new Date(); var starttime = new Date().getTime() / 1000; | |
114 xstopwatch = setInterval(function () { | |
115 var nowtime = new Date().getTime() / 1000; | |
116 now = nowtime-starttime | |
117 hours = parseInt( now / 3600 ) % 24; | |
118 minutes = parseInt( now / 60 ) % 60; | |
119 seconds = parseInt(now % 60); | |
120 milliseconds = Math.floor((now-seconds)*10)%60; | |
121 time = | |
122 (hours < 10 ? "0" + hours : hours) + ":" + | |
123 (minutes < 10 ? "0" + minutes : minutes) + ":" + | |
124 (seconds < 10 ? "0" + seconds : seconds) + "."+ | |
125 milliseconds; | |
126 socket.broadcast.emit('chronFromServer', time) | |
127 socket.emit('chronFromServer', time) | |
128 }, 100) | |
129 } | |
130 | |
131 if (state==0) { console.log("chronControl....zerostate") ; clearInterval(xstopwatch); } | |
132 | |
133 } | |
134 | |
135 | |
136 // if not already started start the chronometer and sequencer | |
137 function startChr(socket) { chronCtrl(1,100); step(seqA);step(seqB); step(seqC); step(seqD); } | |
138 // stop the chronometer | |
139 function stopChr() { console.log("stop chron"); chronCtrl(0); } | |
140 | |
141 function pad(number) { return (number < 10 ? '0' : '') + number } | |
142 function resetChr() {//clearInterval(); | |
143 zecsec = 0; seconds = 0; mins = 0; hours = 0; | |
144 var chron = pad(hours) +":"+pad(mins)+ ':'+ pad(seconds)+ ":"+ zecsec | |
145 // send 0.00.00 values to display | |
146 socket.broadcast.emit('chronFromServer', chron) | |
147 socket.emit('chronFromServer', chron) | |
148 } | |
149 | |
150 //////////////////////////////////////////// | |
151 // magic square sequencer (this should be modularised) | |
152 //////////////////////////////////////////// | |
153 // all the variables this sequencer needs are in scoreB.js | |
154 requirejs(['scoreB'],function(scoreB) {}); | |
155 | |
156 var sequencerState=0; | |
157 var numberoftransects=3 | |
158 var order=8 | |
159 var countdowntick=function(seq){ | |
160 var unit=seq.units[seq.transect%numberoftransects][seq.counter]; | |
161 var unitlast=seq.units[seq.transect%numberoftransects][seq.counter-1]; | |
162 var voice=seq.voice; | |
163 var tempoms = Math.floor(60000/seq.mm) | |
164 var timemultiplier=1000 | |
165 var outcount=4; var incount=4; | |
166 var dur=srcsqr[Math.floor(unit/order)][unit%order] + 4 | |
167 var time = dur; | |
168 var ztime=time; | |
169 var totaltime=time | |
170 initPage=function(seq){ | |
171 // initiate first page here | |
172 socket.emit("pageIni", voice, unit, time, seq.mm,seq.counter,seq.nextunit ); | |
173 socket.emit("pageFlipfromserver", voice, unit, time, seq.mm,seq.counter,seq.nextunit ); | |
174 } | |
175 | |
176 function sequenCer() { | |
177 if (ztime >= 0 ){ | |
178 var counter = ztime | |
179 // flip the page | |
180 if (counter == 0){ | |
181 //increment the row position | |
182 seq.counter = (seq.counter + 1) % (order) | |
183 //increment the transect | |
184 if ( seq.counter==0 ){ seq.transect += 1 } | |
185 socket.broadcast.emit("pageFlipfromserver", voice, unit, time, seq.mm,seq.counter,seq.nextunit); | |
186 clearInterval(pulse) | |
187 step(seq); | |
188 } | |
189 | |
190 if (counter >= 0 ){ | |
191 socket.broadcast.emit('counterText', | |
192 voice, unit, counter,seq.counter,unitlast,seq.transect%numberoftransects); | |
193 socket.emit('counterText', | |
194 voice, unit, counter,seq.counter,unitlast,seq.transect%numberoftransects); | |
195 | |
196 if (counter <= outcount ) { | |
197 socket.broadcast.emit('countinFromServer', | |
198 voice, counter, | |
199 "","stop in: ", "red", "transparent",unit); | |
200 socket.emit('countinFromServer', | |
201 voice, counter, | |
202 "","stop in: ", "red", "transparent",unit); | |
203 } | |
204 | |
205 if (counter > (totaltime)-incount && counter <= totaltime ) { | |
206 socket.broadcast.emit('countinFromServer', | |
207 voice, counter-(totaltime-incount), | |
208 "","play in: ", "green","transparent",unit); | |
209 socket.emit('countinFromServer', | |
210 voice,counter-(totaltime-incount), | |
211 "","play in: ", "green","transparent",unit); | |
212 } | |
213 | |
214 if (counter == (totaltime)-incount ) { | |
215 socket.broadcast.emit('countinFromServer', | |
216 voice, "+", | |
217 "","playing.. ", "green","transparent",unit); | |
218 socket.emit('countinFromServer', | |
219 voice, "+", | |
220 "","playing.. ", "green","transparent",unit); | |
221 } | |
222 } | |
223 | |
224 // on each beat do: | |
225 // push out the pulse to metronome | |
226 seq.metrobeat = (seq.metrobeat+1)%seq.beatsinbar ; | |
227 socket.broadcast.emit('metroPulse', tempoms, voice,seq.metrobeat); | |
228 socket.emit('metroPulse', tempoms, voice, seq.metrobeat); | |
229 } | |
230 | |
231 // decrement the time | |
232 ztime -= 1 | |
233 | |
234 // this shows undefined counter output - bug related | |
235 // console.log(counter) | |
236 } | |
237 | |
238 var pulse = setInterval(sequenCer, tempoms); | |
239 | |
240 socket.on('stopSeq', function () { | |
241 sequenCer.clearInterval | |
242 console.log("sequencer stopping...") | |
243 // grrr why wont this clearInterval work | |
244 sequencerState = 0 | |
245 clearInterval(pulse) | |
246 sequenCer.clearInterval(pulse) | |
247 stopChr(); | |
248 }); | |
249 }; | |
250 | |
251 step = function (seq) { | |
252 clearInterval(countdowntick); | |
253 countdowntick(seq) | |
254 sequencerState=1; | |
255 initPage(seq) | |
256 }; | |
257 | |
258 socket.on('resetSeq', function () { resetChr(); }); | |
259 | |
260 //////////////////////////////////////////// | |
261 // some latency calculations | |
262 /////////////////////////////////////////// | |
263 | |
264 /* | |
265 a ping is periodically broadcast to all connected clients each | |
266 connected returns a pong to the server via an "emit" and in turn | |
267 the server returns each unique client a report of the latency | |
268 via another emit - the emit only sends to the source of the | |
269 request, whereas the broadcast.emit.. broadcasts.. ie to all | |
270 connected clients | |
271 | |
272 TODO: smooth range and average out results to remove erratic ping | |
273 times. | |
274 | |
275 TODO: | |
276 The result then needs to be used to stagger outgoing messages to | |
277 compensate for latency - how much compensation is more connected | |
278 to the time that any audio/video feed needs to encode/decode as | |
279 the latency of the route from node A to node B is inavoidable?! | |
280 so maybe latency is irrelevant in this context - we just need to | |
281 stagger signals according to encoding decoding times.. hmmm | |
282 */ | |
283 | |
284 | |
285 // periodically broadcast a ping | |
286 function serverTime(freq) { | |
287 if (pinging==0){ st = setInterval(function() { | |
288 var pinging=1; | |
289 var d = new Date(); var n = d.getTime(); | |
290 socket.emit("timeFromServer", n); | |
291 }, 1000); } else console.log("already pinging") | |
292 } | |
293 // receive the pong calculate the latency and | |
294 // return the response to the client | |
295 | |
296 socket.on("clientTimeResponse", function(x) { | |
297 var d = new Date(); var n = d.getTime(); | |
298 var latency = (n-x)/2; | |
299 //console.log("SERVERTIME:"+x + " LATENCY:" + latency); | |
300 socket.emit("latencyFromServer", latency); | |
301 }); | |
302 | |
303 | |
304 | |
305 serverTime(1000); | |
306 | |
307 socket.on('disconnect', function(client) { | |
308 console.log(socket.nickname + " is gone..." ) | |
309 clearInterval(st); | |
310 | |
311 if (!socket.nickname) return; | |
312 | |
313 delete nicknames[socket.nickname]; | |
314 socket.broadcast.emit('announcement', socket.nickname + ' disconnected'); | |
315 socket.broadcast.emit('nicknames', nicknames); | |
316 }); | |
317 | |
318 }); | |
319 | |
320 exports.socket= io.sockets; | |
321 exports.httpServer = httpServer; | |
322 | |
323 |