-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
executable file
Β·165 lines (148 loc) Β· 5.07 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
158
159
160
161
162
163
164
165
import express from "express";
import compression from "compression";
import path from "path";
import logger from "morgan";
import bodyParser from "body-parser";
import swig from "swig";
import React from "react";
import { renderToString } from "react-dom/server";
import { match, RouterContext } from "react-router";
import routes from "./app/routes";
import storage from "node-persist";
import moment from "moment";
storage.initSync();
// APP
var app = express();
app.set("port", process.env.PORT || 3000);
app.use(logger("dev"));
app.use(bodyParser.json());
app.use(compression());
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(express.static(path.join(__dirname, "public")));
// POST POSITION
app.post("/", (req, res) => {
if ("id" in req.body) {
// store the request
storage.setItemSync(
req.body.id,
JSON.stringify({
last: new Date().getTime(),
name: req.body.name,
location: {
lat: req.body.latitude,
lng: req.body.longitude
}
})
);
// broadcast via socketio
io.sockets.in(req.body.id).emit("position", req.body);
}
// push the viewer count back
return res.status(200).send({
viewers: io.sockets.adapter.rooms[req.body.id]
? io.sockets.adapter.rooms[req.body.id].length
: 0
});
});
// DELETE CHANNEL
app.delete("/", (req, res) => {
if ("id" in req.body) {
storage.removeItemSync(req.body.id);
io.sockets.in(req.body.id).emit("closed", req.body);
}
return res.status(204).send();
});
// REACT MIDDLEWARE
app.use((req, res) => {
match(
{ routes: routes, location: req.url },
(err, redirectLocation, renderProps) => {
// error
if (err) {
return res.status(500).send(err.message);
} else if (redirectLocation) {
// redirect
return res
.status(302)
.redirect(
redirectLocation.pathname + redirectLocation.search
);
} else if (renderProps) {
var title = "Trevvio";
var data = {};
var nope = false;
// check if this is a share route and an id exists
if ("id" in renderProps.params) {
// try to fetch the storage
var info = storage.getItemSync(renderProps.params.id);
if (info) {
// parse JSON
data = JSON.parse(info);
title = data.name + " // Trevvio";
if (
moment(data.last).isBefore(
moment().subtract("30", "minutes")
)
) {
nope = true;
}
} else {
nope = true;
}
}
if (nope === true) {
var page = swig.renderFile("views/nope.html", {
html: html
});
return res.status(200).send(page);
}
// `RouterContext` is what the `Router` renders. `Router` keeps these
// `props` in its state as it listens to `browserHistory`. But on the
// server our app is stateless, so we need to use `match` to
// get these props before rendering.
var html = renderToString(<RouterContext {...renderProps} />);
// dump the HTML into a template, lots of ways to do this, but none are
// really influenced by React Router, so we're just using a little
// function, `renderPage`
var page = swig.renderFile("views/index.html", {
html: html,
title: title,
data: JSON.stringify(data)
});
return res.status(200).send(page);
} else {
// not found
return res.status(404).send("Page Not Found");
}
}
);
});
// EXPRESS
var server = app.listen(app.get("port"), () => {
console.log("Express server listening on port " + app.get("port"));
});
// SOCKET.IO
var io = require("socket.io")(server);
io.sockets.on("connection", function(socket) {
// ON: join
socket.on("join", function(room) {
socket.join(room);
// on every new join, emit the connection count to the app user
socket.in(room).emit("viewers", io.sockets.adapter.rooms[room].length);
});
// ON: disconnect
socket.on("disconnecting", reason => {
Object.keys(socket.rooms).forEach(r => {
socket
.in(r)
.emit(
"viewers",
Math.max(0, io.sockets.adapter.rooms[r].length - 1)
);
});
});
});