forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			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 | ||
|  | } |