internal void CommitAndEnqueueForSending(OutgoingMessage msg, DeliveryType deliveryType, byte channelIndex) { if (deliveryType != AgNet.DeliveryType.Reliable && msg.BodyLength > PayloadMTU) { throw new AgNetException(string.Format("You can't send unreliable messages more than {0} bytes", PayloadMTU)); } if (msg.Sealed) { throw new AgNetException("This message already has been sent. You can't send one message twice. Please use SendMessage() method with multiple recipients"); } msg.Sealed = true; IAgNetChannel channel = GetChannel(deliveryType, channelIndex); lock (channel) { IEnumerable <OutgoingMessage> messages = null; if (deliveryType == DeliveryType.Reliable) { messages = AgNetReliableChannel.TrySplit(msg, PayloadMTU); } else { messages = new OutgoingMessage[1] { msg } }; foreach (OutgoingMessage splittedMsg in messages) { splittedMsg.RemoteEP = ClientEndPoint; channel.CommitMessage(splittedMsg); splittedMsg.Status = AgNetSendStatus.Queued; } } }
internal IEnumerable <IncomingMessage> ReceiveMessage(IncomingMessage msg) { LastIncomingData = DateTime.UtcNow; if (msg.DeliveryType == DeliveryType.Reliable && msg.Type != PacketType.ConfirmDelivery) { reliableChannel.AddToSendConfirmation(msg); } IAgNetChannel channel = GetChannel(msg.DeliveryType, msg.Channel); IEnumerable <IncomingMessage> messages = channel.ProcessMessage(msg); List <IncomingMessage> userMessages = new List <IncomingMessage>(); foreach (var message in messages) { if (ProcessMessage(channel, message)) { userMessages.Add(message); } } return(userMessages); }
bool ProcessMessage(IAgNetChannel channel, IncomingMessage msg) { if (msg.Type == PacketType.ConfirmDelivery) { int confirmed = msg.ReadInt32(); for (int i = 0; i < confirmed; i++) { int sequence = msg.ReadInt32(); OutgoingMessage deliveryFor = reliableChannel.PopFromAwaitConfirmation(sequence); if (deliveryFor == null) { continue; } deliveryFor.Status = AgNetSendStatus.Confirmed; if (State == SessionState.Connecting && deliveryFor.Type == PacketType.ConnectAck) { SetState(SessionState.Connected); } if (State == SessionState.Closing && deliveryFor.Type == PacketType.FinResp) { Close("Shutdown method called"); } deliveryFor.Dispose(); } return(false); } if (msg.Type == PacketType.Ping) { Pong(msg); return(false); } if (msg.Type == PacketType.MTUExpandRequest) { ReceivedMtuExpand(msg); return(false); } if (msg.Type == PacketType.MTUSuccess) { ReceivedMtuResponse(msg); return(false); } if (msg.Type == PacketType.Pong) { lastPongReceived = DateTime.UtcNow; DateTime sent = new DateTime(msg.ReadInt64()); TimeSpan ts = DateTime.UtcNow - sent; PingRoundtrip = (int)ts.TotalMilliseconds; return(false); } if (msg.Type == PacketType.ConnectionError) { Close(msg.ReadString()); return(false); } if (msg.Type == PacketType.FinAck) { SetState(SessionState.Closing); FinResp(); return(false); } if (msg.Type == PacketType.FinResp) { Close("Connection closed by remote peer"); return(false); } if (msg.Type == PacketType.ConnectAck && State == SessionState.Closed) { var server = peer as AgNetServer; if (server != null) { if (server.MaximumSessions > 0 && server.SessionsCount >= server.MaximumSessions) { SendError("Server rejected connection"); } else { SetState(SessionState.Connected); } } return(false); } if (msg.Type == PacketType.Ping) { return(false); } if (msg.Type == PacketType.PartialMessage) { return(false); } if (State == SessionState.Connected && msg.Type == PacketType.UserData) { return(true); } Close("Unknown service packet"); return(false); }