private void Handshake(string SID, EngineIOTransport Transport) { if (Option.SetCookie) { Transport.On(EngineIOTransport.Event.HEADERS, (Headers) => { List <string> Cookies = new List <string>(); foreach (string Key in Option.Cookies.Keys) { string Cookie = Key; string Value = Option.Cookies[Key]; if (!string.IsNullOrWhiteSpace(Value)) { Cookie += ('=' + Value); } Cookies.Add(Cookie); } (Headers as NameValueCollection)["Set-Cookie"] = string.Join("; ", Cookies); }); } EngineIOSocket Socket = new EngineIOSocket(SID, this, Transport); _Clients.TryAdd(SID, Socket.Once(EngineIOSocket.Event.CLOSE, () => _Clients.TryRemove(SID, out _))); Emit(Event.CONNECTION, Socket); }
internal EngineIOSocket(string SID, EngineIOServer Server, EngineIOTransport Transport) { this.SID = SID; this.Server = Server; Upgrading = false; Upgraded = false; ReadyState = EngineIOReadyState.OPENING; SetTransport(Transport); OnOpen(); }
private void SetTransport(EngineIOTransport Transport) { if (this.Transport != null) { this.Transport.Off(); } this.Transport = Transport .On(EngineIOTransport.Event.DRAIN, OnDrain) .On(EngineIOTransport.Event.PACKET, (Packet) => OnPacket(Packet as EngineIOPacket)) .On(EngineIOTransport.Event.ERROR, (Exception) => OnError(Exception as Exception)) .On(EngineIOTransport.Event.CLOSE, () => OnClose("Transport close.")) .Open(); }
public EngineIOClient Connect() { if (ReadyState == EngineIOReadyState.CLOSED) { EngineIOTransport Transport; ReadyState = EngineIOReadyState.OPENING; if (Option.WebSocket && (!Option.Polling || (Option.RemeberUpgrade && PriorWebsocketSuccess))) { Transport = new EngineIOWebSocket(Option); } else { Transport = new EngineIOPolling(Option); } SetTransport(Transport); } return(this); }
private void SetTransport(EngineIOTransport Transport) { this.Transport = Transport .On(EngineIOTransport.Event.DRAIN, Flush) .On(EngineIOTransport.Event.DRAIN, OnDrain) .On(EngineIOTransport.Event.PACKET, (Packet) => OnPacket(Packet as EngineIOPacket)) .Once(EngineIOTransport.Event.ERROR, (Exception) => OnError(Exception as Exception)) .Once(EngineIOTransport.Event.CLOSE, (Argument) => { object[] Temp = Argument as object[]; if (Temp != null) { OnClose(Temp[0] as string, Temp[1] as Exception); } else { OnClose("Transport closed"); } }); Cleanup.Enqueue(() => this.Transport.Off()); }
private void Probe() { EngineIOWebSocket Transport = new EngineIOWebSocket(Option); bool Failed = PriorWebsocketSuccess = false; void OnTransportOpen() { string Message = "probe"; Transport.Send(EngineIOPacket.CreatePingPacket(Message)); Transport.Once(EngineIOTransport.Event.PACKET, (Packet) => { if (!Failed) { EngineIOPacket Temp = Packet is EngineIOPacket ? Packet as EngineIOPacket : EngineIOPacket.CreateClosePacket(); if (Temp.Type == EngineIOPacketType.PONG && Temp.Data.Equals(Message)) { Upgrading = true; Emit(Event.UPGRADING, Transport); PriorWebsocketSuccess = true; (this.Transport as EngineIOPolling).Pause(() => { if (!Failed && ReadyState != EngineIOReadyState.CLOSED) { CleanUp(); SetTransport(Transport); Transport.Send(EngineIOPacket.CreateUpgradePacket()); Emit(Event.UPGRADE, Transport); Upgrading = false; Flush(); } }); } else { Emit(Event.UPGRADE_ERROR, new EngineIOException("Probe error")); } } }); } void OnTransportClose() { OnTransportError(new EngineIOException("Transport closed")); } void OnTransportError(object Exception) { string Message = "Probe error"; Exception = Exception is Exception ? new EngineIOException(Message, Exception as Exception) : new EngineIOException(Message); FreezeTransport(); Emit(Event.UPGRADE_ERROR, Exception as Exception); } void FreezeTransport() { if (!Failed) { Failed = true; CleanUp(); Transport.Close(); Transport = null; } } void OnClose() { OnError(new EngineIOException("Client closed")); } void OnUpgrade() { if (!(Transport is EngineIOWebSocket)) { FreezeTransport(); } } void CleanUp() { Transport.Off(EngineIOTransport.Event.OPEN, OnTransportOpen); Transport.Off(EngineIOTransport.Event.ERROR, OnTransportError); Transport.Off(EngineIOTransport.Event.CLOSE, OnTransportClose); Off(Event.CLOSE, OnClose); Off(Event.UPGRADING, OnUpgrade); } Transport.Once(EngineIOTransport.Event.OPEN, OnTransportOpen); Transport.Once(EngineIOTransport.Event.ERROR, OnTransportError); Transport.Once(EngineIOTransport.Event.CLOSE, OnTransportClose); Once(Event.CLOSE, OnClose); Once(Event.UPGRADING, OnUpgrade); Transport.Open(); }