示例#1
0
        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);
        }
示例#2
0
        internal EngineIOSocket(string SID, EngineIOServer Server, EngineIOTransport Transport)
        {
            this.SID    = SID;
            this.Server = Server;

            Upgrading = false;
            Upgraded  = false;

            ReadyState = EngineIOReadyState.OPENING;

            SetTransport(Transport);
            OnOpen();
        }
示例#3
0
        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();
        }
示例#4
0
        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);
        }
示例#5
0
        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());
        }
示例#6
0
        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();
        }