/// <summary>Inlet content</summary> /// <param name="content">Content</param> internal void Inlet(Content content) { // Last receipt time LastReceiptTime = (uint)Stopwatch.ElapsedMilliseconds; // Unreliable content if ((content.Protocol & Content.IDENTIFIABLE) == 0) { // Channel unreliable Unreliable.Inlet(content); } // Reliable content else { // Measure latency if (content.Protocol == Content.RESPONSE) { MeasureLatency(content.Timestamp); } // Channel reliable Reliable.Inlet(content); } }
public void Broadcast(byte[] buf, int offset, int size, bool reliable = true) { if (reliable) { Reliable.Broadcast(buf, offset, size); } else { Unreliable.Broadcast(buf, offset, size); } }
/// <summary>Outlet content</summary> /// <param name="content">Content</param> internal void Outlet(Content content) { if (content == null) { return; } if (content.Protocol != Content.PONG) { content.Timestamp = (uint)Stopwatch.ElapsedMilliseconds; } // Channel unreliable Unreliable.Outlet(content); // Channel reliable Reliable.Outlet(content); }
/// <summary> /// Generically sends a datagram to the specified end points, either reliable or unreliable. /// </summary> /// <param name="message">The message to send</param> /// <param name="isReliable">Whether the handler should ensure /// the message reaches its intended recipient</param> /// <param name="endPoints">The client(s) to send the datagram to</param> public void SendDatagram(string message, bool isReliable) { byte[] msgBytes; if (isReliable) { if (_resolverBuffer.Count >= 100) { return; } // Append the ack index count to the message, to communicate to the // client what reliable datagram count it represents msgBytes = Encoding.ASCII.GetBytes(Reliable.CreateString(_ackCurrentIndex, message)); // Add a new AckResolver to the resolver buffer, which will // resend the datagram if the timeout is reached // before receiving an ACK AddAckResolver( new AckResolver() { AckIndex = _ackCurrentIndex, TicksStart = DateTime.Now.Ticks, Message = message } ); _ackCurrentIndex += 1; } else { msgBytes = Encoding.ASCII.GetBytes(Unreliable.CreateString(message)); } try { _client.Send(msgBytes, msgBytes.Length); } catch (SocketException) { _displayDisconnection.Display(); } }
/// <summary>Timeout</summary> internal void Timeout() { // Time var time = (uint)Stopwatch.ElapsedMilliseconds; // Channel unreliable Unreliable.Timeout(time); // Channel reliable Reliable.Timeout(time); // Disconnecting if ( ( Reliable.Muted() || Unreliable.Muted() ) || ( CheckStatus(Status.Close | Status.Wait) && Unreliable.Released() && Reliable.Released() ) ) { // Change status ChangeStatus(Status.Close | Status.Done); if (Reliable.Muted() || Reliable.Muted()) { Network.Raise(EventType.Unlinked, Reason.Muted, this); } else { Network.Raise(EventType.Unlinked, Reason.Unlinked, this); } return; } // Settings var downtime = Network.Settings.Downtime; var pingInterval = Network.Settings.PingInterval; // Downtime if ((time - LastReceiptTime) > downtime) { // Timeout if ( CheckStatus(Status.Connect | Status.Wait) || CheckStatus(Status.Connect | Status.Done) ) { Network.Raise(EventType.Unlinked, Reason.Timeout, this); } // Host not accessible else if (CheckStatus(Status.Connect)) { Network.Raise(EventType.Failed, Failure.NotAccessible, this); } // Change status ChangeStatus(Status.Close | Status.Done); } // Ping if ( CheckStatus(Status.Connect | Status.Done) && (time - LastPingTime) > pingInterval ) { // Last ping interval LastPingTime = time; // Ping var content = Content.Unreliable(); content.Protocol = Content.PING; // Set the current timestamp and pack content.Timestamp = time; content.Packing(); // Send immediately var size = (uint)Network.Outlet(content, this); // Statistics Statistics.PacketSent(size, false); Network.Statistics.PacketSent(size, false); } }
public PacketProcessor(string ip, int port, bool isListener) { _connection = new Connection(ip, port, isListener); _unreliable = new Unreliable(); _reliableFast = new ReliableFast(); }