130 lines
3.3 KiB
Haxe
Raw Normal View History

2025-01-22 16:18:30 +01:00
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
}