Ejemplo n.º 1
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();
        }
Ejemplo n.º 2
0
        internal void UpgradeTransport(EngineIOWebSocket Transport)
        {
            void OnTransportPacket(object Argument)
            {
                EngineIOPacket Packet = Argument as EngineIOPacket;

                if (Packet.Type == EngineIOPacketType.PING)
                {
                    Transport.Send(EngineIOPacket.CreatePongPacket(Packet.Data));
                    Emit(Event.UPGRADING);

                    ResetCheckTimer();
                }
                else
                {
                    Cleanup();

                    if (Packet.Type == EngineIOPacketType.UPGRADE && ReadyState != EngineIOReadyState.CLOSED)
                    {
                        this.Transport.Discard();
                        Upgraded = true;

                        ClearTransport();
                        SetTransport(Transport);

                        Emit(Event.UPGRADE);

                        ResetPingTimer();
                        Flush();

                        if (ReadyState == EngineIOReadyState.CLOSING)
                        {
                            this.Transport.Close(() =>
                            {
                                this.OnClose("Forced close.");
                            });
                        }
                    }
                    else
                    {
                        Transport.Close();
                    }
                }
            }

            void Cleanup()
            {
                Upgrading = false;

                StopCheckTimer();
                StopUpgradeTimer();

                Transport.Off(EngineIOTransport.Event.PACKET, OnTransportPacket);
                Transport.Off(EngineIOTransport.Event.CLOSE, OnTransportClose);
                Transport.Off(EngineIOTransport.Event.ERROR, OnTransportError);
            }

            void OnTransportError(object Exception)
            {
                EngineIOLogger.Error(this, Exception as Exception);

                Cleanup();
                Transport.Close();
            }

            void OnTransportClose()
            {
                OnTransportError(new EngineIOException("Transport closed."));
            }

            void OnClose()
            {
                OnTransportError(new EngineIOException("Socket closed."));
            }

            Upgrading = true;
            StartUpgradeTimer(() =>
            {
                Cleanup();

                if (Transport.ReadyState == EngineIOReadyState.OPEN)
                {
                    Transport.Close();
                }
            });

            Transport.On(EngineIOTransport.Event.PACKET, OnTransportPacket);
            Transport.Once(EngineIOTransport.Event.CLOSE, OnTransportClose);
            Transport.Once(EngineIOTransport.Event.ERROR, OnTransportError);

            Once(Event.CLOSE, OnClose);
        }