-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.js
147 lines (126 loc) · 5.73 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
/**
Copyright (C) 2012 Andrew P. Sillers (apsillers@gmail.com)
This file is part of the HTML5 Netrek Client.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Protocol:
[BROWSER] [WEB SERVER] [NETREK SERVER]
| ---->[connect]-----> | |
| | |
| --->serverDataReq--> | | (optional)
| <----serverData<---- | |
| | |
| ---->joinServer----> | |
| | ----[connect]----> |
| <--severConnected<-- | |
| | |
| <--------------------------------------------> |
| <--------------[NETREK PROTOCOL]-------------> |
| <------(the web server becomes a proxy)------> |
| <--------------------------------------------> |
| | |
| --->[disconnect]---> | |
| | ----->[disconnect]----> |
NOTES:
- In order to form the serverData message, the Web Server should query the
metaserver; however, it could also hold a fixed list of known good clients.
- When the Netrek server (NS) sends a SP_PING packet, the Web server (WS)
handles it directly. This eliminates needless traffic to the client, since
the WS can vouch that the client is still alive just as well as the browser.
*/
// info for the metaserver
var META_HOST = "";
var META_PORT = 0;
var USE_REAL_META = false;
var STATIC_HOSTS = [
{host:"continuum.us.netrek.org",port:2592},
{host:"pickled.netrek.org",port:2592},
{host:"netrek.apsillers.com",port:2592},
];
var net = require('net');
var express = require("express"),
app = express()
, http = require('http')
, server = http.createServer(app)
// serve files
app.use(express.static(__dirname));
// get the port from either: heroku port var, nodester port var, command-line arg, or use 16446
var address = process.env.OPENSHIFT_NODEJS_IP || "0.0.0.0";
var port = process.env.app_port || process.env.PORT || process.env.OPENSHIFT_NODEJS_PORT || process.argv[2] || 16446;
console.log("listening on port " + port)
server.listen(port, address);
var io = require('socket.io').listen(server);
io.set('log level', 1);
//io.set("transports", ["xhr-polling"]);
//io.set("polling duration", 10);
// new browser client is connecting to the WS server
io.sockets.on('connection', function (socket) {
console.log("CONNECTION");
socket.on('serverDataReq', function (hostInfo) {
if(USE_REAL_META) {
//TODO: query metaserver and send server info to client
var metaServerConn = net.connect(META_HOST, META_PORT, function() {
socket.emit("serverData", []);
});
} else {
// just use a static list of hosts
socket.emit("serverData", STATIC_HOSTS);
}
});
// the client has picked a server to join and passed info about which one
socket.on('joinServer', function (hostInfo) {
// make a new connection to the Netrek server
var serverConn = net.connect(hostInfo.port, hostInfo.host, function() {
console.log("joined")
console.log("connected to NT server!");
/* PROXY BEHAVIOR */
// forward all data from the server to the browser client
serverConn.on('data', function(sp_data) {
// base64-encode the Buffer of bytes and send it to the client
if(process.argv.indexOf("--verbose-server") != -1) { console.log("FROM SERVER", sp_data); }
socket.send(sp_data.toString("base64"));
});
serverConn.on('end', function() {
console.log("server connection finished");
socket.emit("serverClosure");
socket.disconnect();
});
serverConn.on('close', function() {
console.log("server connection died");
socket.disconnect();
});
serverConn.on('error', function(e) {
socket.emit("serverError");
});
// foward all data from the browser client to the server
// data is a base64-encoded string
socket.on('message', function(cp_data) {
cp_data = new Buffer(cp_data, "base64");
if(process.argv.indexOf("--verbose-client") != -1) { console.log("FROM CLIENT", cp_data); }
serverConn.write(cp_data);
});
socket.on('disconnect', function() {
console.log("DISCONNECT");
serverConn.end();
// TODO: clean up connection
// send CP_QUIT/CP_BYE message? (unless the client never picked a
// server or already exited gracefully)
});
/* END PROXY BEHAVIOR */
// connection made to real server; browser can now send data
socket.emit('serverConnected');
}).on('error', function(e) {
console.log("Connect error: " + e.message);
socket.emit("connectError");
});
});
});