-
Notifications
You must be signed in to change notification settings - Fork 2
/
server.js
132 lines (106 loc) · 3.36 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
/* eslint no-console: 0, strict: 0, global-require: 0, import/no-extraneous-dependencies: 0 */
'use strict';
/*
Node server for Tjube.Ninja.
The server generates a unique room id when a user connects.
This id allows the remotes to send data to the screen(s).
*/
const http = require('http');
const express = require('express');
const morgan = require('morgan');
const app = express();
const server = http.createServer(app);
const io = require('socket.io')(server);
const bodyParser = require('body-parser');
const mustache = require('mustache-express');
const filterYoutubeData = require('./src/utils/FilterYoutubeData');
const roomIdLength = 3;
const roomIdChars = 'abcdefghijklmnopqrstuvwxyz';
const roomIdRegex = `[${roomIdChars}]{${roomIdLength}}`;
server.listen(process.env.PORT || 1337, () => console.log('opened server on', server.address()));
function generateRoomId() {
let id = '';
for (let j = 0; j < roomIdLength; j += 1) {
id += roomIdChars.charAt(Math.floor(Math.random() * roomIdChars.length));
}
return id;
}
function roomExists(id) {
return Object.hasOwnProperty.call(io.sockets.adapter.rooms, id);
}
// Tries 10 times to generate a unique room id
function generateUniqueRoomId() {
for (let i = 0; i < 10; i += 1) {
const id = generateRoomId();
if (!roomExists(id)) {
return id;
}
}
return false;
}
if (process.env.NODE_ENV !== 'production') {
console.log('running in dev mode!');
const webpack = require('webpack');
const devMiddleware = require('webpack-dev-middleware');
const hotMiddleware = require('webpack-hot-middleware');
const webpackConfig = require('./webpack.config.dev');
const compiler = webpack(webpackConfig);
app.use(devMiddleware(compiler, {
publicPath: webpackConfig.output.publicPath,
}));
app.use(hotMiddleware(compiler));
} else {
// Serve build files
app.use(express.static('./build'));
}
// Serve static files
app.use(express.static('./static'));
// Logging express routes
app.use(morgan('short'));
// Parse application/json post body
app.use(bodyParser.json());
// Use mustache to render html
app.engine('mustache', mustache());
// Show room select/create screen
app.get('/', (req, res) => {
const roomId = generateUniqueRoomId();
if (roomId) {
res.redirect(`/player/${roomId}`);
} else {
res.status(503).send('Server is crowded, please try again later :)');
}
});
// Redirect to remote
app.get(`/:room(${roomIdRegex})`, (req, res) => {
res.redirect(`/remote/${req.params.room}`);
});
// Show public screen
app.get(`/player/:room(${roomIdRegex})`, (req, res) => {
res.render('template.mustache', { view: 'player', room: req.params.room });
});
// Show remote screen
app.get(`/remote/:room(${roomIdRegex})`, (req, res) => {
res.render('template.mustache', { view: 'remote', room: req.params.room });
});
// add video with post request
app.post(`/add/:room(${roomIdRegex})`, (req, res) => {
const video = filterYoutubeData(req.body);
if (video && roomExists(req.params.room)) {
io.to(req.params.room).emit('addVideo', video);
res.json({ status: 'ok' });
return;
}
res.status(422).json({ status: 'error' });
});
// Communicate with clients
io.on('connect', (socket) => {
let currentRoom = '';
socket.on('registerRoom', (room) => {
currentRoom = room;
socket.join(currentRoom);
});
socket.on('addVideo', (video, success) => {
socket.broadcast.to(currentRoom).emit('addVideo', video);
success();
});
});