private void OnPacket(EngineIOPacket Packet) { if (ReadyState == EngineIOReadyState.OPEN) { Emit(Event.PACKET, Packet); ResetPongTimer(Server.Option.PingInterval + Server.Option.PingTimeout); ResetPingTimer(); switch (Packet.Type) { case EngineIOPacketType.PING: Send(EngineIOPacket.CreatePongPacket(Packet.Data)); Emit(Event.HEARTBEAT); break; case EngineIOPacketType.PONG: SimpleMutex.Lock(PongMutex, () => Pong++); Emit(Event.HEARTBEAT); break; case EngineIOPacketType.MESSAGE: Emit(Event.MESSAGE, Packet); break; case EngineIOPacketType.UNKNOWN: OnClose(string.Format("Parse error : {0}", Packet.Data)); break; } } }
public TChildClass Emit(TEvent Event, [Optional] TArgument Argument) { if (Event != null) { if (this.Listeners.TryGetValue(Event, out List <Listener <TArgument> > Listeners)) { SimpleMutex.Lock(EventMutex, () => { for (int i = 0; i < Listeners.Count; i++) { Listener <TArgument> Listener = Listeners[i]; if (Listener.Once) { Listeners.RemoveAt(i--); } Listener.Invoke(Argument); } }); } } return(this as TChildClass); }
private void Flush() { if (ReadyState != EngineIOReadyState.CLOSED && Transport.Writable && !Upgrading && PacketBuffer.Count > 0) { EngineIOPacket[] Packets = null; SimpleMutex.Lock(BufferMutex, () => { Packets = PacketBuffer.ToArray(); PacketBuffer.Clear(); }); if ((Packets?.Length ?? 0) > 0) { Emit(Event.FLUSH, Packets); Server.Emit(EngineIOServer.Event.FLUSH, Packets); SentCallback.Enqueue(PacketCallback); PacketCallback.Clear(); Transport.Send(Packets); Emit(Event.DRAIN, Packets); Server.Emit(EngineIOServer.Event.DRAIN, Packets); } } }
public SocketIOAck CreateAck(Action <JToken[]> Callback = null) { if (Callback != null) { SocketIOAck Result = null; SimpleMutex.Lock(AckMutex, () => { for (int i = 0; true; i++) { if (i < AckList.Count) { if (AckList[i] == null) { Result = AckList[i] = new SocketIOAck(i, Callback); } } else { SocketIOAck Ack = new SocketIOAck(AckList.Count, Callback); AckList.Add(Ack); Result = Ack; } } }); return(Result); } else { return(null); } }
private void Flush() { if (ReadyState != EngineIOReadyState.CLOSED && !Upgrading && PacketBuffer.Count > 0 && !Flushing) { Flushing = true; ThreadPool.QueueUserWorkItem((_) => { try { while (!Transport.Writable) { Thread.Sleep(0); } SimpleMutex.Lock(BufferMutex, () => Transport.Send(PacketBuffer.ToArray())); PreviousBufferSize = PacketBuffer.Count; Emit(Event.FLUSH); Flushing = false; } catch (Exception Exception) { OnError(Exception); } }); } }
public void Remove(int PacketID) { SimpleMutex.Lock(AckMutex, () => { if (AckList.Count > PacketID) { AckList[PacketID] = null; } }); }
public Tunnel(IMessageHandler messageHandler, string friendlyName = "Cactus Fantastico", int port = 14804) { MessageHandler = messageHandler; FriendlyName = friendlyName; _socket = SockLib.UdpConnect(port); _messageQueue = new ConcurrentQueue <Message>(); _hbMutex = new SimpleMutex(); _id = _tunnelCounter++; }
private void StartPingTimer() { SimpleMutex.Lock(PingMutex, () => { PingTimer = new EngineIOTimeout(() => { Send(EngineIOPacket.CreatePingPacket()); ResetPongTimer(Server.Option.PingTimeout); }, Server.Option.PingInterval * 1.1); }); }
internal void Send(EngineIOPacket Packet, Action Callback = null) { if (ReadyState == EngineIOReadyState.OPENING || ReadyState == EngineIOReadyState.OPEN) { Emit(Event.PACKET_CREATE, Packet); SimpleMutex.Lock(BufferMutex, () => PacketBuffer.Enqueue(Packet)); Once(Event.FLUSH, Callback); Flush(); } }
private void StartHeartbeat() { SimpleMutex.Lock(PingMutex, () => { if (PingTimer == null && Handshake != null) { ulong PingInterval = Handshake.PingInterval; PingTimer = new Timer(PingInterval / 2.0); PingTimer.Elapsed += (_, __) => { SimpleMutex.Lock(PingMutex, () => { PingTimer.Interval = PingInterval; Send(EngineIOPacket.CreatePingPacket()); SimpleMutex.Lock(PongMutex, () => { if (PongTimer == null && Handshake != null) { PongTimer = new Timer(Handshake.PingTimeout); PongTimer.Elapsed += (___, ____) => { SimpleMutex.Lock(PongMutex, () => { if (Pong > 0) { Pong = 0; } else { OnClose("Heartbeat timeout"); } }); }; PongTimer.AutoReset = false; } if (!PongTimer.Enabled) { PongTimer.Start(); } }); }); }; PingTimer.AutoReset = true; PingTimer.Start(); } }); }
private void StopHeartbeat() { SimpleMutex.Lock(PingMutex, () => { PingTimer?.Stop(); PingTimer = null; }); SimpleMutex.Lock(PongMutex, () => { PongTimer?.Stop(); PongTimer = null; }); }
public void Invoke(int PacketID, params JToken[] Data) { SimpleMutex.Lock(AckMutex, () => { if (AckList.Count > PacketID && AckList[PacketID] != null) { AckList[PacketID].Invoke(Data); if (AutoRemove) { AckList[PacketID] = null; } } }); }
public List <Delegate> GetListenerList(TEvent Event) { List <Delegate> Result = new List <Delegate>(); if (Event != null && this.Listeners.TryGetValue(Event, out List <Listener <TArgument> > Listeners)) { SimpleMutex.Lock(EventMutex, () => { foreach (Listener <TArgument> Listener in Listeners) { Result.Add(Listener.Callback); } }); } return(Result); }
private void StartCheckTimer() { SimpleMutex.Lock(CheckMutex, () => { CheckTimer = new Timer(100); CheckTimer.Elapsed += (_, __) => { if (Transport is EngineIOPolling && Transport.Writable) { Transport.Send(EngineIOPacket.CreateNoopPacket()); } }; CheckTimer.AutoReset = true; CheckTimer.Start(); }); }
internal SocketIOAckManager() { SetTimeout(TimeoutInMillis); UseAckTimeout = false; AckTimer.Elapsed += (sender, e) => { SimpleMutex.Lock(AckMutex, () => { for (int i = 0; UseAckTimeout && i < AckList.Count; i++) { if (AckList[i] != null && DateTime.UtcNow.Subtract(AckList[i].RequestedTime).TotalMilliseconds > TimeoutInMillis) { AckList[i] = null; } } }); }; }
private TChildClass RemoveListener(TEvent Event, Delegate Callback, bool Backward) { if (Event != null) { if (Callback == null) { Listeners.TryRemove(Event, out _); } else { if (this.Listeners.TryGetValue(Event, out List <Listener <TArgument> > Listeners)) { SimpleMutex.Lock(EventMutex, () => { if (!Backward) { for (int i = 0; i < Listeners.Count; i++) { if (Listeners[i].Callback.Equals(Callback)) { Listeners.RemoveAt(i); break; } } } else { for (int i = Listeners.Count - 1; i >= 0; i--) { if (Listeners[i].Callback.Equals(Callback)) { Listeners.RemoveAt(i); break; } } } }); } } } return(this as TChildClass); }
private void OnClose(string Message, Exception Description = null) { if (ReadyState != EngineIOReadyState.CLOSED) { ReadyState = EngineIOReadyState.CLOSED; StopTimers(); PacketCallback.Clear(); SentCallback.Clear(); ClearTransport(); Emit(Event.CLOSE, new object[] { Message, Description }); ThreadPool.QueueUserWorkItem((_) => { Thread.Sleep(0); SimpleMutex.Lock(BufferMutex, PacketBuffer.Clear); }); } }
private void OnConnection(EngineIOSocket EngineIOSocket) { SocketIOSocket Socket = new SocketIOSocket(EngineIOSocket, this); SimpleMutex.Lock(ClientMutex, () => { _Clients.Add(Socket); Socket.On(SocketIOEvent.DISCONNECT, () => { SimpleMutex.Lock(ClientMutex, () => { _Clients.Remove(Socket); }); }); Socket.Emit(SocketIOPacket.CreateConnectionPacket()); ConnectionHandlerManager.Emit(SocketIOEvent.CONNECTION, Socket); }); }
private TChildClass AddListener(TEvent Event, Delegate Callback, bool Once) { bool IsGenericAction = Callback is Action <TArgument>; if (Event != null && (IsGenericAction || Callback is Action)) { Listener <TArgument> Listener = IsGenericAction ? new Listener <TArgument>(Callback as Action <TArgument>, Once) : new Listener <TArgument>(Callback as Action, Once); Listeners.AddOrUpdate(Event, (_) => new List <Listener <TArgument> >() { Listener }, (_, Listeners) => { SimpleMutex.Lock(EventMutex, () => Listeners.Add(Listener)); return(Listeners); }); } return(this as TChildClass); }
public static string Generate() { string Key = null; SimpleMutex.Lock(GeneratorMutex, () => { Key = Encode((long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds); if (!Key.Equals(PreviousKey)) { Seed = 0; PreviousKey = Key; } else { Key = string.Format("{0}.{1}", Key, Encode(Seed++)); } }); return(Key); }
private void OnPacket(EngineIOPacket Packet) { if (ReadyState != EngineIOReadyState.CLOSED) { Emit(Event.PACKET, Packet); switch (Packet.Type) { case EngineIOPacketType.OPEN: Emit(Event.HANDSHAKE); Handshake = new EngineIOHandshake(Packet.Data); Option.Query.Add("sid", Handshake.SID); OnOpen(); if (ReadyState != EngineIOReadyState.CLOSED) { StartHeartbeat(); } break; case EngineIOPacketType.PING: Send(EngineIOPacket.CreatePongPacket(Packet.Data)); break; case EngineIOPacketType.PONG: SimpleMutex.Lock(PongMutex, () => Pong++); break; case EngineIOPacketType.MESSAGE: Emit(Event.MESSAGE, Packet); break; case EngineIOPacketType.UNKNOWN: OnError(new EngineIOException(string.Format("Parse error : {0}", Packet.Data))); break; } } }
private void StartPongTimer(ulong PingTimeout) { SimpleMutex.Lock(PongMutex, () => { PongTimer = new EngineIOTimeout(() => { SimpleMutex.Lock(PongMutex, () => { if (ReadyState != EngineIOReadyState.CLOSED) { if (Pong > 0) { Pong = 0; ThreadPool.QueueUserWorkItem((_) => StartPongTimer(PingTimeout)); } else { OnClose("Ping timeout"); } } }); }, PingTimeout); }); }
private void StopCheckTimer() { SimpleMutex.Lock(CheckMutex, () => CheckTimer?.Stop()); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(SimpleMutex obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
private void StartUpgradeTimer(Action Callback) { SimpleMutex.Lock(CheckMutex, () => UpgradeTimer = new EngineIOTimeout(Callback, Server.Option.UpgradeTimeout)); }
private void StopUpgradeTimer() { SimpleMutex.Lock(UpgradeMutex, () => UpgradeTimer?.Stop()); }
private void StopPongTimer() { SimpleMutex.Lock(PongMutex, () => PongTimer?.Stop()); }