NetworkMessage *MessageConnection::StartNewMessage(unsigned long id, size_t numBytes) { NetworkMessage *msg = AllocateNewMessage(); if (!msg) { LOG(LogError, "MessageConnection::SendMessage: StartNewMessage failed! Discarding message send."); return 0; // Failed to allocate a new message. This is caused only by memory allocation issues. } msg->id = id; msg->reliable = false; msg->contentID = 0; msg->obsolete = false; // Give the new message the lowest priority by default. msg->priority = 0; // By default, the message is not fragmented. Later when admitting the message into the send queue, the need for // fragmentation is examined and this field will be updated if needed. msg->transfer = 0; #ifdef KNET_NETWORK_PROFILING msg->profilerName = ""; #endif msg->Resize(numBytes); return msg; }
void MessageConnection::HandleInboundMessage(packet_id_t packetID, const char *data, size_t numBytes) { AssertInWorkerThreadContext(); if (!socket) return; // Ignore all messages from connections that have already died. assert(data && numBytes > 0); // Read the message ID. DataDeserializer reader(data, numBytes); message_id_t messageID = reader.ReadVLE<VLE8_16_32>(); ///\todo Check that there actually is enough space to read. if (messageID == DataDeserializer::VLEReadError) { LOG(LogError, "Error parsing messageID of a message in socket %s. Data size: %d bytes.", socket->ToString().c_str(), (int)numBytes); throw NetException("MessageConnection::HandleInboundMessage: Network error occurred when deserializing message ID VLE field!"); } LOG(LogData, "Received message with ID %d and size %d from peer %s.", (int)packetID, (int)numBytes, socket->ToString().c_str()); char str[256]; sprintf(str, "messageIn.%u", (unsigned int)messageID); ADDEVENT(str, (float)reader.BytesLeft(), "bytes"); // Pass the message to TCP/UDP -specific message handler. bool childHandledMessage = HandleMessage(packetID, messageID, data + reader.BytePos(), reader.BytesLeft()); if (childHandledMessage) return; // If the derived class handled the message, no need to propagate it further. switch(messageID) { case MsgIdPingRequest: HandlePingRequestMessage(data + reader.BytePos(), reader.BytesLeft()); break; case MsgIdPingReply: HandlePingReplyMessage(data + reader.BytePos(), reader.BytesLeft()); break; default: { NetworkMessage *msg = AllocateNewMessage(); msg->Resize(numBytes); assert(reader.BitPos() == 0); memcpy(msg->data, data + reader.BytePos(), reader.BytesLeft()); msg->dataSize = reader.BytesLeft(); msg->id = messageID; msg->contentID = 0; msg->receivedPacketID = packetID; bool success = inboundMessageQueue.Insert(msg); if (!success) { LOG(LogError, "Failed to add a new message of ID %d and size %dB to inbound queue! Queue was full.", (int)messageID, (int)msg->dataSize); FreeMessage(msg); } } break; } }