//Called when we get a packet on the transport public void _OnReceivePacket(RouterPacket p) { //Get the global ID of this packet and see if we need to create it ulong globalId = p.GetGlobalMessageID(); RouterMessage msg; if (!receivingPackets.TryGetValue(globalId, out msg)) { msg = new RouterMessage(this, p); receivingPackets.Add(globalId, msg); } //Write chunk if (msg.WriteChunk(p)) { //We've read all data needed. Handle this packet try { HandleIncomingMessage(msg, p); } catch (Exception ex) { Log("HandlerWorker", $"Failed to handle incoming message (opcode {msg.opcode} from {msg.sender_addr_router}:{msg.sender_addr_local}) in client code: {ex.Message}{ex.StackTrace}", DeltaLogLevel.Medium); } //Clean up receivingPackets.Remove(globalId); } }
public bool WriteChunk(RouterPacket packet) { //Calculate where to place this int offset = BaseRouterIO.MESSAGE_PAYLOAD_SIZE * packet.chunk_index; //Write chunksReceived++; Array.Copy(packet.payload, 0, payload, offset, packet.payload.Length); //Check if we've received the entire message return(chunksReceived == BaseRouterIO.GetChunksInPayload(packet.total_message_length)); }
public RouterMessage(BaseRouterIO io, RouterPacket p) { this.io = io; this.responseToken = p.response_token; this.opcode = p.opcode; this.sender_addr_local = p.sender_addr_local; this.sender_addr_router = p.sender_addr_router; this.lib_version_major = p.lib_version_major; this.lib_version_minor = p.lib_version_minor; this.app_version_major = p.app_version_major; this.app_version_minor = p.app_version_minor; this.message_id = p.message_id; this.opcode = p.opcode; this.payload = new byte[p.total_message_length]; this.flagIsLast = 1 == ((p.flags >> 1) & 1U); }
private void HandleIncomingMessage(RouterMessage msg, RouterPacket lastPacket) { if (lastPacket.CheckFlag(0)) { //This is a response. The response token will be registered and waiting by us. We'll just have to respond to it if (waitingResponseSessions.TryGetValue(lastPacket.response_token, out Channel <RouterMessage> channel)) { //Write response channel.Writer.WriteAsync(msg).GetAwaiter().GetResult(); //If that's it, clean up and close the channel if (lastPacket.CheckFlag(1)) { //Remove waitingResponseSessions.TryRemove(lastPacket.response_token, out channel); //Close channel channel.Writer.Complete(); } } else { //Not found! Huh. Log("HandleIncomingMessage", $"Got packet response token {lastPacket.response_token}, but there were no waiting sessions for it! Dropping packet...(although something bad has probably happened)", DeltaLogLevel.High); } } else if (lastPacket.CheckFlag(1)) { //This is an incoming system message if (lastPacket.opcode == -1) { //Ping message msg.Respond(new byte[] { DeltaConnection.LIB_VERSION_MAJOR, DeltaConnection.LIB_VERSION_MINOR, appVersion.major, appVersion.major }, true); } } else { //This is an incoming message, handle as usual RouterReceiveMessage(msg); } }
public abstract void QueueOutgoingMessage(RouterPacket packet);