130 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| package kha.netsync;
 | |
| 
 | |
| import haxe.io.Bytes;
 | |
| #if sys_server
 | |
| import js.Node;
 | |
| import js.node.Buffer;
 | |
| import js.node.Dgram;
 | |
| #end
 | |
| 
 | |
| class Server {
 | |
| 	#if sys_server
 | |
| 	private var app: Dynamic;
 | |
| 	private var udpSocket: Dynamic;
 | |
| 	private var udpClients: Map<String, UdpClient> = new Map();
 | |
| 	private var lastId: Int = -1;
 | |
| 
 | |
| 	#if !direct_connection
 | |
| 	private var clients: Map<Int, NodeProcessClient> = new Map();
 | |
| 	private var connectionCallback: Client->Void;
 | |
| 	#end
 | |
| 	#end
 | |
| 	public function new(port: Int) {
 | |
| 		#if sys_server
 | |
| 		#if direct_connection
 | |
| 		var express = Node.require("express");
 | |
| 		app = express();
 | |
| 		Node.require("express-ws")(app);
 | |
| 
 | |
| 		app.use('/', untyped __js__("express.static('../html5')"));
 | |
| 
 | |
| 		app.use(function(err, req, res, next) {
 | |
| 			Node.console.error(err.stack);
 | |
| 		});
 | |
| 
 | |
| 		app.listen(port);
 | |
| 
 | |
| 		udpSocket = Dgram.createSocket("udp4");
 | |
| 		udpSocket.bind(port +
 | |
| 			1); // TODO: This is somewhat ugly, but necessary to maintain both websocket and UPD connections at the same time (see also kore/network/Network.hx)
 | |
| 		#else
 | |
| 		Node.process.on("message", function(message) {
 | |
| 			var msg: String = message.message;
 | |
| 			switch (msg) {
 | |
| 				case "connect":
 | |
| 					{
 | |
| 						var id: Int = message.id;
 | |
| 						var client = new NodeProcessClient(id);
 | |
| 						clients[id] = client;
 | |
| 						connectionCallback(client);
 | |
| 					}
 | |
| 				case "disconnect":
 | |
| 					{
 | |
| 						var id: Int = message.id;
 | |
| 						var client = clients[id];
 | |
| 						client._close();
 | |
| 						clients.remove(id);
 | |
| 					}
 | |
| 				case "message":
 | |
| 					{
 | |
| 						var id: Int = message.id;
 | |
| 						var client = clients[id];
 | |
| 						client._message(message.data);
 | |
| 					}
 | |
| 			}
 | |
| 		});
 | |
| 		#end
 | |
| 		#end
 | |
| 	}
 | |
| 
 | |
| 	public function onConnection(connection: Client->Void): Void {
 | |
| 		#if sys_server
 | |
| 		#if direct_connection
 | |
| 		app.ws('/', function(socket, req) {
 | |
| 			++lastId;
 | |
| 			connection(new WebSocketClient(lastId, socket));
 | |
| 		});
 | |
| 
 | |
| 		udpSocket.on('message', function(message: Buffer, info) {
 | |
| 			if (compare(message, "JOIN")) {
 | |
| 				++lastId;
 | |
| 				var client = new UdpClient(lastId, udpSocket, info.address, info.port);
 | |
| 				udpClients.set(info.address + info.port, client);
 | |
| 				connection(client);
 | |
| 				// var content = Bytes.alloc(4);
 | |
| 				// content.setInt32(0, lastId);
 | |
| 				// client.send(content, true);
 | |
| 			}
 | |
| 			else {
 | |
| 				var client = udpClients.get(info.address + info.port);
 | |
| 				if (client != null) {
 | |
| 					if (client.onReceive != null) {
 | |
| 						var data: haxe.io.BytesData = cast message;
 | |
| 						client.onReceive(Bytes.ofData(data));
 | |
| 					}
 | |
| 				}
 | |
| 				// TODO
 | |
| 				/*var id: Int = message[0];
 | |
| 					var client = clients[id];
 | |
| 					var content = Bytes.alloc(message.length - 1);
 | |
| 					content.blit(0, message, 1, message.length);
 | |
| 					client._message(message.length); */
 | |
| 			}
 | |
| 			// TODO: Timeout for disconnect
 | |
| 			// console.log('Received %d bytes from %s:%d\n', message.length, info.address, info.port);
 | |
| 		});
 | |
| 		#else
 | |
| 		connectionCallback = connection;
 | |
| 		#end
 | |
| 		#end
 | |
| 	}
 | |
| 
 | |
| 	public function reset(): Void {
 | |
| 		#if sys_server
 | |
| 		lastId = -1;
 | |
| 		#end
 | |
| 	}
 | |
| 
 | |
| 	#if sys_server
 | |
| 	private static function compare(buffer: Buffer, message: String): Bool {
 | |
| 		if (buffer.length != message.length)
 | |
| 			return false;
 | |
| 		for (i in 0...buffer.length) {
 | |
| 			if (buffer.readUInt8(i) != message.charCodeAt(i))
 | |
| 				return false;
 | |
| 		}
 | |
| 		return true;
 | |
| 	}
 | |
| 	#end
 | |
| }
 |