Example #1
0
        /// <summary>
        /// Closes the connection and shuts down the transport.
        /// </summary>
        public void Close()
        {
            if (this.State == ConnectionStates.Closed)
                return;

            this.State = ConnectionStates.Closed;

            ReconnectStartedAt = null;
            TransportConnectionStartedAt = null;

            if (Transport != null)
            {
                Transport.Abort();
                Transport = null;
            }

            NegotiationResult = null;

            HTTPManager.Heartbeats.Unsubscribe(this);

            LastReceivedMessage = null;

            if (Hubs != null)
                for (int i = 0; i < Hubs.Length; ++i)
                    (Hubs[i] as IHub).Close();

            if (BufferedMessages != null)
            {
                BufferedMessages.Clear();
                BufferedMessages = null;
            }

            if (OnClosed != null)
            {
                try
                {
                    OnClosed(this);
                }
                catch (Exception ex)
                {
                    HTTPManager.Logger.Exception("SignalR Connection", "OnClosed", ex);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Called when we receive a message from the server
        /// </summary>
        void IConnection.OnMessage(IServerMessage msg)
        {
            if (this.State == ConnectionStates.Closed)
                return;

            // Store messages that we receive while we are connecting
            if (this.State == ConnectionStates.Connecting)
            {
                if (BufferedMessages == null)
                    BufferedMessages = new List<IServerMessage>();

                BufferedMessages.Add(msg);

                return;
            }

            LastMessageReceivedAt = DateTime.UtcNow;

            switch(msg.Type)
            {
                case MessageTypes.Multiple:
                    LastReceivedMessage = msg as MultiMessage;

                    // Not received in the reconnect process, so we can't rely on it
                    if (LastReceivedMessage.IsInitialization)
                        HTTPManager.Logger.Information("SignalR Connection", "OnMessage - Init");

                    if (LastReceivedMessage.GroupsToken != null)
                        GroupsToken = LastReceivedMessage.GroupsToken;

                    if (LastReceivedMessage.ShouldReconnect)
                    {
                        HTTPManager.Logger.Information("SignalR Connection", "OnMessage - Should Reconnect");

                        Reconnect();

                        // Should we return here not processing the messages that may come with it?
                        //return;
                    }

                    if (LastReceivedMessage.Data != null)
                        for (int i = 0; i < LastReceivedMessage.Data.Count; ++i)
                            (this as IConnection).OnMessage(LastReceivedMessage.Data[i]);

                    break;

                case MessageTypes.MethodCall:
                    MethodCallMessage methodCall = msg as MethodCallMessage;

                    Hub hub = this[methodCall.Hub];

                    if (hub != null)
                        (hub as IHub).OnMethod(methodCall);
                    else
                        HTTPManager.Logger.Warning("SignalR Connection", string.Format("Hub \"{0}\" not found!", methodCall.Hub));

                    break;

                case MessageTypes.Result:
                case MessageTypes.Failure:
                case MessageTypes.Progress:
                    UInt64 id = (msg as IHubMessage).InvocationId;
                    hub = FindHub(id);
                    if (hub != null)
                        (hub as IHub).OnMessage(msg);
                    else
                        HTTPManager.Logger.Warning("SignalR Connection", string.Format("No Hub found for Progress message! Id: {0}", id.ToString()));
                    break;

                case MessageTypes.Data:
                    if (OnNonHubMessage != null)
                        OnNonHubMessage(this, (msg as DataMessage).Data);
                    break;

                case MessageTypes.KeepAlive:
                    break;

                default:
                    HTTPManager.Logger.Warning("SignalR Connection", "Unknown message type received: " + msg.Type.ToString());
                    break;
            }
        }
        /// <summary>
        /// When the json string is successfully parsed will return with an IServerMessage implementation.
        /// </summary>
        public static IServerMessage Parse(IJsonEncoder encoder, string json)
        {
            // Nothing to parse?
            if (string.IsNullOrEmpty(json))
            {
                HTTPManager.Logger.Error("MessageFactory", "Parse - called with empty or null string!");
                return null;
            }

            // We don't have to do further decoding, if it's an empty json object, then it's a KeepAlive message from the server
            if (json.Length == 2 && json == "{}")
                return new KeepAliveMessage();

            IDictionary<string, object> msg = null;

            try
            {
                // try to decode the json message with the encoder
                msg = encoder.DecodeMessage(json);
            }
            catch(Exception ex)
            {
                HTTPManager.Logger.Exception("MessageFactory", "Parse - encoder.DecodeMessage", ex);
                return null;
            }

            if (msg == null)
            {
                HTTPManager.Logger.Error("MessageFactory", "Parse - Json Decode failed for json string: \"" + json + "\"");
                return null;
            }

            // "C" is for message id
            IServerMessage result = null;
            if (!msg.ContainsKey("C"))
            {
                // If there are no ErrorMessage in the object, then it was a success
                if (!msg.ContainsKey("E"))
                    result = new ResultMessage();
                else
                    result = new FailureMessage();
            }
            else
              result = new MultiMessage();

            result.Parse(msg);

            return result;
        }