void IManager.TryToReconnect()
        {
            if (this.State == SocketManager.States.Reconnecting || this.State == SocketManager.States.Closed)
            {
                return;
            }
            if (!this.Options.Reconnection)
            {
                ((IManager)this).EmitAll(EventNames.GetNameFor(SocketIOEventTypes.Disconnect), new object[0]);
                this.Close();
                return;
            }
            if (++this.ReconnectAttempts >= this.Options.ReconnectionAttempts)
            {
                ((IManager)this).EmitEvent("reconnect_failed", new object[0]);
                this.Close();
                return;
            }
            Random random = new Random();
            int    num    = (int)this.Options.ReconnectionDelay.TotalMilliseconds * this.ReconnectAttempts;

            this.ReconnectAt = DateTime.UtcNow + TimeSpan.FromMilliseconds((double)Math.Min(random.Next((int)((float)num - (float)num * this.Options.RandomizationFactor), (int)((float)num + (float)num * this.Options.RandomizationFactor)), (int)this.Options.ReconnectionDelayMax.TotalMilliseconds));
            ((IManager)this).Close(false);
            this.State = SocketManager.States.Reconnecting;
            for (int i = 0; i < this.Sockets.Count; i++)
            {
                ((ISocket)this.Sockets[i]).Open();
            }
            HTTPManager.Heartbeats.Subscribe(this);
            HTTPManager.Logger.Information("SocketManager", "Reconnecting");
        }
        void IHeartbeat.OnHeartbeatUpdate(TimeSpan dif)
        {
            switch (this.State)
            {
            case SocketManager.States.Opening:
                if (DateTime.UtcNow - this.ConnectionStarted >= this.Options.Timeout)
                {
                    ((IManager)this).EmitEvent("connect_error", new object[0]);
                    ((IManager)this).EmitEvent("connect_timeout", new object[0]);
                    ((IManager)this).TryToReconnect();
                }
                break;

            case SocketManager.States.Open:
            {
                ITransport transport;
                if (this.Transport != null && this.Transport.State == TransportStates.Open)
                {
                    transport = this.Transport;
                }
                else
                {
                    transport = this.Poller;
                }
                if (transport == null || transport.State != TransportStates.Open)
                {
                    return;
                }
                transport.Poll();
                this.SendOfflinePackets();
                if (this.LastHeartbeat == DateTime.MinValue)
                {
                    this.LastHeartbeat = DateTime.UtcNow;
                    return;
                }
                if (DateTime.UtcNow - this.LastHeartbeat > this.Handshake.PingInterval)
                {
                    ((IManager)this).SendPacket(new Packet(TransportEventTypes.Ping, SocketIOEventTypes.Unknown, "/", string.Empty, 0, 0));
                    this.LastHeartbeat = DateTime.UtcNow;
                }
                if (DateTime.UtcNow - this.LastPongReceived > this.Handshake.PingTimeout)
                {
                    ((IManager)this).EmitAll(EventNames.GetNameFor(SocketIOEventTypes.Disconnect), new object[0]);
                    ((IManager)this).TryToReconnect();
                }
                break;
            }

            case SocketManager.States.Reconnecting:
                if (this.ReconnectAt != DateTime.MinValue && DateTime.UtcNow >= this.ReconnectAt)
                {
                    ((IManager)this).EmitEvent("reconnect_attempt", new object[0]);
                    ((IManager)this).EmitEvent("reconnecting", new object[0]);
                    this.Open();
                }
                break;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Internal constructor.
        /// </summary>
        internal Socket(string nsp, SocketManager manager)
        {
            this.Context = new LoggingContext(this);
            this.Context.Add("nsp", nsp);

            this.Namespace       = nsp;
            this.Manager         = manager;
            this.IsOpen          = false;
            this.TypedEventTable = new TypedEventTable(this);

            this.On <ConnectResponse>(EventNames.GetNameFor(SocketIOEventTypes.Connect), OnConnected);
        }
Beispiel #4
0
        /// <summary>
        /// Last call of the OnPacket chain(Transport -> Manager -> Socket), we will dispatch the event if there is any callback
        /// </summary>
        void ISocket.OnPacket(Packet packet)
        {
            // Some preprocessing of the the packet
            switch (packet.SocketIOEvent)
            {
            case SocketIOEventTypes.Disconnect:
                if (IsOpen)
                {
                    IsOpen = false;
                    EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Disconnect), packet);
                    Disconnect();
                }
                break;

            // Create an Error object from the server-sent json string
            case SocketIOEventTypes.Error:
                bool success = false;
                var  errDict = JSON.Json.Decode(packet.Payload, ref success) as Dictionary <string, object>;
                if (success)
                {
                    Error err = new Error((SocketIOErrors)Convert.ToInt32(errDict["code"]),
                                          errDict["message"] as string);

                    EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Error), packet, err);

                    return;
                }
                break;
            }

            // Dispatch the event to all subscriber
            EventCallbacks.Call(packet);

            // call Ack callbacks
            if ((packet.SocketIOEvent == SocketIOEventTypes.Ack || packet.SocketIOEvent == SocketIOEventTypes.BinaryAck) && AckCallbacks != null)
            {
                SocketIOAckCallback ackCallback = null;
                if (AckCallbacks.TryGetValue(packet.Id, out ackCallback) &&
                    ackCallback != null)
                {
                    try
                    {
                        ackCallback(this, packet, packet.Decode(Manager.Encoder));
                    }
                    catch (Exception ex)
                    {
                        HTTPManager.Logger.Exception("Socket", "ackCallback", ex);
                    }
                }

                AckCallbacks.Remove(packet.Id);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Called from a ITransport implemetation when an error occures and we may have to try to reconnect.
        /// </summary>
        void IManager.TryToReconnect()
        {
            if (State == States.Reconnecting ||
                State == States.Closed)
            {
                return;
            }

            if (!Options.Reconnection)
            {
                (this as IManager).EmitAll(EventNames.GetNameFor(SocketIOEventTypes.Disconnect));
                Close();

                return;
            }

            if (++ReconnectAttempts >= Options.ReconnectionAttempts)
            {
                (this as IManager).EmitEvent("reconnect_failed");
                Close();

                return;
            }

            Random rand = new Random();

            int delay = (int)Options.ReconnectionDelay.TotalMilliseconds * ReconnectAttempts;

            ReconnectAt = DateTime.UtcNow +
                          TimeSpan.FromMilliseconds(Math.Min(rand.Next(/*rand min:*/ (int)(delay - (delay * Options.RandomizationFactor)),
                                                                       /*rand max:*/ (int)(delay + (delay * Options.RandomizationFactor))),
                                                             (int)Options.ReconnectionDelayMax.TotalMilliseconds));

            (this as IManager).Close(false);

            State = States.Reconnecting;

            for (int i = 0; i < Sockets.Count; ++i)
            {
                (Sockets[i] as ISocket).Open();
            }

            // In the Close() function we unregistered
            HTTPManager.Heartbeats.Subscribe(this);

            HTTPManager.Logger.Information("SocketManager", "Reconnecting");
        }
Beispiel #6
0
        void ISocket.OnPacket(Packet packet)
        {
            switch (packet.SocketIOEvent)
            {
            case SocketIOEventTypes.Disconnect:
                if (this.IsOpen)
                {
                    this.IsOpen = false;
                    this.Disconnect();
                }
                break;

            case SocketIOEventTypes.Error:
            {
                bool flag = false;
                Dictionary <string, object> dictionary = Json.Decode(packet.Payload, ref flag) as Dictionary <string, object>;
                if (flag)
                {
                    Error error = new Error((SocketIOErrors)Convert.ToInt32(dictionary["code"]), dictionary["message"] as string);
                    this.EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Error), packet, new object[]
                        {
                            error
                        });
                    return;
                }
                break;
            }
            }
            this.EventCallbacks.Call(packet);
            if ((packet.SocketIOEvent == SocketIOEventTypes.Ack || packet.SocketIOEvent == SocketIOEventTypes.BinaryAck) && this.AckCallbacks != null)
            {
                SocketIOAckCallback socketIOAckCallback = null;
                if (this.AckCallbacks.TryGetValue(packet.Id, out socketIOAckCallback) && socketIOAckCallback != null)
                {
                    try
                    {
                        socketIOAckCallback(this, packet, packet.Decode(this.Manager.Encoder));
                    }
                    catch (Exception ex)
                    {
                        HTTPManager.Logger.Exception("Socket", "ackCallback", ex);
                    }
                }
                this.AckCallbacks.Remove(packet.Id);
            }
        }
Beispiel #7
0
        void ISocket.OnPacket(Packet packet)
        {
            switch (packet.SocketIOEvent)
            {
            case SocketIOEventTypes.Disconnect:
                if (IsOpen)
                {
                    IsOpen = false;
                    EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Disconnect), packet);
                    Disconnect();
                }
                break;

            case SocketIOEventTypes.Error:
            {
                bool success = false;
                Dictionary <string, object> dictionary = Json.Decode(packet.Payload, ref success) as Dictionary <string, object>;
                if (success)
                {
                    Error error = new Error((SocketIOErrors)Convert.ToInt32(dictionary["code"]), dictionary["message"] as string);
                    EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Error), packet, error);
                    return;
                }
                break;
            }
            }
            EventCallbacks.Call(packet);
            if ((packet.SocketIOEvent == SocketIOEventTypes.Ack || packet.SocketIOEvent == SocketIOEventTypes.BinaryAck) && AckCallbacks != null)
            {
                SocketIOAckCallback value = null;
                if (AckCallbacks.TryGetValue(packet.Id, out value) && value != null)
                {
                    try
                    {
                        value(this, packet, packet.Decode(Manager.Encoder));
                    }
                    catch (Exception ex)
                    {
                        HTTPManager.Logger.Exception("Socket", "ackCallback", ex);
                    }
                }
                AckCallbacks.Remove(packet.Id);
            }
        }
Beispiel #8
0
        public IncomingPacket(TransportEventTypes transportEvent, SocketIOEventTypes packetType, string nsp, int id)
        {
            this.TransportEvent = transportEvent;
            this.SocketIOEvent  = packetType;
            this.Namespace      = nsp;
            this.Id             = id;

            this.AttachementCount = 0;
            //this.ReceivedAttachements = 0;
            this.Attachements = null;

            if (this.SocketIOEvent != SocketIOEventTypes.Unknown)
            {
                this.EventName = EventNames.GetNameFor(this.SocketIOEvent);
            }
            else
            {
                this.EventName = EventNames.GetNameFor(this.TransportEvent);
            }

            this.DecodedArg = this.DecodedArgs = null;
        }
Beispiel #9
0
        public void On(SocketIOEventTypes type, SocketIOCallback callback, bool autoDecodePayload)
        {
            string nameFor = EventNames.GetNameFor(type);

            EventCallbacks.Register(nameFor, callback, onlyOnce: false, autoDecodePayload);
        }
Beispiel #10
0
        /// <summary>
        /// Last call of the OnPacket chain(Transport -> Manager -> Socket), we will dispatch the event if there is any callback
        /// </summary>
        void ISocket.OnPacket(Packet packet)
        {
            // Some preprocessing of the packet
            switch (packet.SocketIOEvent)
            {
            case SocketIOEventTypes.Connect:
                this.Id = this.Namespace != "/" ? this.Namespace + "#" + this.Manager.Handshake.Sid : this.Manager.Handshake.Sid;
                break;

            case SocketIOEventTypes.Disconnect:
                if (IsOpen)
                {
                    IsOpen = false;
                    EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Disconnect), packet);
                    Disconnect();
                }
                break;

            // Create an Error object from the server-sent json string
            case SocketIOEventTypes.Error:
                bool   success = false;
                object result  = JSON.Json.Decode(packet.Payload, ref success);
                if (success)
                {
                    var   errDict = result as Dictionary <string, object>;
                    Error err;

                    if (errDict != null && errDict.ContainsKey("code"))
                    {
                        err = new Error((SocketIOErrors)Convert.ToInt32(errDict["code"]), errDict["message"] as string);
                    }
                    else
                    {
                        err = new Error(SocketIOErrors.Custom, packet.Payload);
                    }

                    EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Error), packet, err);

                    return;
                }
                break;
            }

            // Dispatch the event to all subscriber
            EventCallbacks.Call(packet);

            // call Ack callbacks
            if ((packet.SocketIOEvent == SocketIOEventTypes.Ack || packet.SocketIOEvent == SocketIOEventTypes.BinaryAck) && AckCallbacks != null)
            {
                SocketIOAckCallback ackCallback = null;
                if (AckCallbacks.TryGetValue(packet.Id, out ackCallback) &&
                    ackCallback != null)
                {
                    try
                    {
                        ackCallback(this, packet, this.AutoDecodePayload ? packet.Decode(Manager.Encoder) : null);
                    }
                    catch (Exception ex)
                    {
                        HTTPManager.Logger.Exception("Socket", "ackCallback", ex);
                    }
                }

                AckCallbacks.Remove(packet.Id);
            }
        }
Beispiel #11
0
 /// <summary>
 /// Remove the specified callback.
 /// </summary>
 public void Off(SocketIOEventTypes type, SocketIOCallback callback)
 {
     EventCallbacks.Unregister(EventNames.GetNameFor(type), callback);
 }
Beispiel #12
0
 /// <summary>
 /// Removes all callbacks to the given event.
 /// </summary>
 public void Off(SocketIOEventTypes type)
 {
     Off(EventNames.GetNameFor(type));
 }
Beispiel #13
0
 public void Once(SocketIOEventTypes type, SocketIOCallback callback, bool autoDecodePayload)
 {
     EventCallbacks.Register(EventNames.GetNameFor(type), callback, true, autoDecodePayload);
 }
Beispiel #14
0
        public void On(SocketIOEventTypes type, SocketIOCallback callback, bool autoDecodePayload)
        {
            string eventName = EventNames.GetNameFor(type);

            EventCallbacks.Register(eventName, callback, false, autoDecodePayload);
        }
Beispiel #15
0
        /// <summary>
        /// Last call of the OnPacket chain(Transport -> Manager -> Socket), we will dispatch the event if there is any callback
        /// </summary>
        void ISocket.OnPacket(Packet packet)
        {
            // Some preprocessing of the packet
            switch (packet.SocketIOEvent)
            {
            case SocketIOEventTypes.Connect:
                if (this.Manager.Options.ServerVersion != SupportedSocketIOVersions.v3)
                {
                    this.Id = this.Namespace != "/" ? this.Namespace + "#" + this.Manager.Handshake.Sid : this.Manager.Handshake.Sid;
                }
                else
                {
                    var data = JSON.Json.Decode(packet.Payload) as Dictionary <string, object>;
                    this.Id = data["sid"].ToString();
                }
                this.IsOpen = true;
                break;

            case SocketIOEventTypes.Disconnect:
                if (IsOpen)
                {
                    IsOpen = false;
                    EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Disconnect), packet);
                    Disconnect();
                }
                break;

            // Create an Error object from the server-sent json string
            case SocketIOEventTypes.Error:
                bool   success = false;
                object result  = JSON.Json.Decode(packet.Payload, ref success);
                if (success)
                {
                    var   errDict = result as Dictionary <string, object>;
                    Error err     = null;

                    if (errDict != null)
                    {
                        object tmpObject = null;
                        string code      = null;
                        if (errDict.TryGetValue("code", out tmpObject))
                        {
                            code = tmpObject.ToString();
                        }

                        int errorCode;
                        if (code != null && int.TryParse(code, out errorCode) && errorCode >= 0 && errorCode <= 7)
                        {
                            errDict.TryGetValue("message", out tmpObject);
                            err = new Error((SocketIOErrors)errorCode, tmpObject != null ? tmpObject.ToString() : string.Empty);
                        }
                    }

                    if (err == null)
                    {
                        err = new Error(SocketIOErrors.Custom, packet.Payload);
                    }

                    EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Error), packet, err);

                    return;
                }
                break;
            }

            // Dispatch the event to all subscriber
            EventCallbacks.Call(packet);

            // call Ack callbacks
            if ((packet.SocketIOEvent == SocketIOEventTypes.Ack || packet.SocketIOEvent == SocketIOEventTypes.BinaryAck) && AckCallbacks != null)
            {
                SocketIOAckCallback ackCallback = null;
                if (AckCallbacks.TryGetValue(packet.Id, out ackCallback) &&
                    ackCallback != null)
                {
                    try
                    {
                        ackCallback(this, packet, this.AutoDecodePayload ? packet.Decode(Manager.Encoder) : null);
                    }
                    catch (Exception ex)
                    {
                        HTTPManager.Logger.Exception("Socket", "ackCallback", ex);
                    }
                }

                AckCallbacks.Remove(packet.Id);
            }
        }
Beispiel #16
0
 public void On(SocketIOEventTypes eventType, Action callback)
 {
     this.TypedEventTable.Register(EventNames.GetNameFor(eventType), null, _ => callback());
 }
Beispiel #17
0
        /// <summary>
        /// Called from the HTTPManager's OnUpdate function every frame. It's main function is to send out heartbeat messages.
        /// </summary>
        void IHeartbeat.OnHeartbeatUpdate(TimeSpan dif)
        {
            switch (State)
            {
            case States.Opening:
                if (DateTime.UtcNow - ConnectionStarted >= Options.Timeout)
                {
                    (this as IManager).EmitEvent("connect_error");
                    (this as IManager).EmitEvent("connect_timeout");
                    (this as IManager).TryToReconnect();
                }

                break;

            case States.Reconnecting:
                if (ReconnectAt != DateTime.MinValue && DateTime.UtcNow >= ReconnectAt)
                {
                    (this as IManager).EmitEvent("reconnect_attempt");
                    (this as IManager).EmitEvent("reconnecting");

                    Open();
                }
                break;

            case States.Open:
                ITransport trans = null;

                // Select transport to use
                if (Transport != null && Transport.State == TransportStates.Open)
                {
                    trans = Transport;
                }
                else
                {
                    trans = Poller;
                }

                // not yet open?
                if (trans == null || trans.State != TransportStates.Open)
                {
                    return;
                }

                // Start to poll the server for events
                trans.Poll();

                // Start to send out unsent packets
                SendOfflinePackets();

                // First time we reached this point. Set the LastHeartbeat to the current time, 'cause we are just opened.
                if (LastHeartbeat == DateTime.MinValue)
                {
                    LastHeartbeat = DateTime.UtcNow;
                    return;
                }

                // It's time to send out a ping event to the server
                if (DateTime.UtcNow - LastHeartbeat > Handshake.PingInterval)
                {
                    (this as IManager).SendPacket(new Packet(TransportEventTypes.Ping, SocketIOEventTypes.Unknown, "/", string.Empty));

                    LastHeartbeat = DateTime.UtcNow;
                }

                // No pong event received in the given time, we are disconnected.
                if (DateTime.UtcNow - LastPongReceived > Handshake.PingTimeout)
                {
                    (this as IManager).EmitAll(EventNames.GetNameFor(SocketIOEventTypes.Disconnect));

                    (this as IManager).TryToReconnect();
                }

                break;                         // case States.Open:
            }
        }
Beispiel #18
0
 void ISocket.EmitEvent(SocketIOEventTypes type, params object[] args)
 {
     ((ISocket)this).EmitEvent(EventNames.GetNameFor(type), args);
 }
Beispiel #19
0
 public void On <T>(SocketIOEventTypes eventType, Action <T> callback)
 {
     this.TypedEventTable.Register(EventNames.GetNameFor(eventType), new Type[] { typeof(T) }, (args) => callback((T)args[0]));
 }
 /// <summary>
 /// Emits an internal packet-less event to the root namespace without creating it if it isn't exists yet.
 /// </summary>
 void IManager.EmitEvent(SocketIOEventTypes type, params object[] args)
 {
     (this as IManager).EmitEvent(EventNames.GetNameFor(type), args);
 }
Beispiel #21
0
        public void On(SocketIOEventTypes type, SocketIOCallback callback)
        {
            string nameFor = EventNames.GetNameFor(type);

            this.EventCallbacks.Register(nameFor, callback, false, this.AutoDecodePayload);
        }