-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
157 lines (125 loc) · 3.94 KB
/
server.js
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
var express = require('express')
, app = express()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server);
server.listen(8443);
// Index
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
// Static files
app.use('/css', express.static(__dirname + '/css'));
app.use('/img', express.static(__dirname + '/img'));
app.use('/snd', express.static(__dirname + '/snd'));
// Room needs to be after sound files
// for precedence reasons
app.get('/:room', function (req, res) {
res.sendfile(__dirname + '/room.html');
});
// hold all adm for the rooms
var adms = {};
// On new connections (from admin or instrument)
io.sockets.on('connection', function (socket) {
// once a new client joins the server
socket.on('join', function (room) {
// define role
var role = adms[room] ? 'cli' : 'adm';
// join room
socket.join(room);
// tell the role
socket.emit('role', role);
// if admin add to list
if (role == 'adm') {
adms[room] = socket.id;
// clean adm list on disconnect
// so next client will get to be the admin
socket.on('disconnect', function () {
delete adms[room];
});
// update stats for new admin
stats(room);
}
else {
// call stats on disconnect
socket.on('disconnect', function () {
stats(room);
});
}
});
// When new instrument joins
socket.on('instrument', function(data) {
// if admin left and no new
// admin came in THIS IS BUG
// IN THE WAY WE SELECT NEW ADMIN
if (!adms[data.room]) {
return;
}
// mark socket to generate stats
socket.set('instrument', data.sound, function () {
// Report to admin which one
// this is sent to all clients
stats(data.room);
});
});
// Once admin requests a HIT
socket.on('hit', function(data) {
// Hit the instrument!
io.sockets.in(data.room).emit('hit', data.sound);
});
// Start playing the pattern
socket.on('start', function (data) {
var step = 0;
var interval = setInterval(function () { pattern(data, step++); }, 60000 / data.tempo / 4);
socket.on('stop', function (data) {
clearInterval(interval);
});
socket.on('disconnect', function (data) {
clearInterval(interval);
});
});
});
// pattern step, this is called
// on each of the steps during pattern loop
function pattern (data, step) {
// get list of patterns for this step
var pattern = data.pattern[step % data.pattern.length];
// if nothing to play we JUMP jump jump! Everybody jump!
if (!pattern) {
return;
}
// play all sounds in this step at once
for (var i in pattern) {
// Hit the instrument!
io.sockets.in(data.room).emit('hit', pattern[i]);
}
}
// This is called to update
// stats at the admin side
function stats (room) {
// this is the stats we return (emit)
var stats = {};
// get all sockets in this room
var clis = io.sockets.clients(room);
// loop through them
for (var i in clis) {
// get data we assign to socket and do something in the callback
clis[i].get('instrument', function (err, name) {
// only count if there is an instrument assigned
if (!name) {
return;
}
// if first time we see this name ZERO it
if (!stats[name]) {
stats[name] = 0;
}
// update stat counter
stats[name]++;
})
}
// in case of no admin it breaks
if (!adms[room]) {
return;
}
// send STATS updated to admin
io.sockets.sockets[adms[room]].emit('instrument', stats);
}