protected void processHandshake(IMutableMessage handshake) { if (handshake.Successful) { // @@ax: I think this should be able to return a list of objects? Object serverTransportObject; handshake.TryGetValue(Message_Fields.SUPPORTED_CONNECTION_TYPES_FIELD, out serverTransportObject); IList <Object> serverTransports = serverTransportObject as IList <Object>; //Console.WriteLine("Supported transport: {0}", serverTransport); //IList<Object> serverTransports = new List<Object>(); //serverTransports.Add(serverTransport); IList <ClientTransport> negotiatedTransports = transportRegistry.Negotiate(serverTransports, BAYEUX_VERSION); ClientTransport newTransport = negotiatedTransports.Count == 0 ? null : negotiatedTransports[0]; if (newTransport == null) { updateBayeuxClientState( delegate(BayeuxClientState oldState) { return(new DisconnectedState(this, oldState.transport)); }, delegate() { receive(handshake); }); // Signal the failure String error = "405:c" + transportRegistry.AllowedTransports + ",s" + serverTransports.ToString() + ":no transport"; handshake.Successful = false; handshake[Message_Fields.ERROR_FIELD] = error; // TODO: also update the advice with reconnect=none for listeners ? } else { updateBayeuxClientState( delegate(BayeuxClientState oldState) { if (newTransport != oldState.transport) { oldState.transport.reset(); newTransport.init(); } String action = getAdviceAction(handshake.Advice, Message_Fields.RECONNECT_RETRY_VALUE); if (Message_Fields.RECONNECT_RETRY_VALUE.Equals(action)) { return(new ConnectingState(this, oldState.handshakeFields, handshake.Advice, newTransport, handshake.ClientId)); } else if (Message_Fields.RECONNECT_NONE_VALUE.Equals(action)) { return(new DisconnectedState(this, oldState.transport)); } return(null); }, delegate() { receive(handshake); }); } } else { updateBayeuxClientState( delegate(BayeuxClientState oldState) { String action = getAdviceAction(handshake.Advice, Message_Fields.RECONNECT_HANDSHAKE_VALUE); if (Message_Fields.RECONNECT_HANDSHAKE_VALUE.Equals(action) || Message_Fields.RECONNECT_RETRY_VALUE.Equals(action)) { return(new RehandshakingState(this, oldState.handshakeFields, oldState.transport, oldState.nextBackoff())); } else if (Message_Fields.RECONNECT_NONE_VALUE.Equals(action)) { return(new DisconnectedState(this, oldState.transport)); } return(null); }, delegate() { receive(handshake); }); } }
/// <summary> /// Processes a handshaking message have just arrived. /// </summary> public virtual void ProcessHandshake(IMutableMessage handshake) { if (null == handshake) throw new ArgumentNullException("handshake"); // DEBUG if (logger.IsDebugEnabled) logger.DebugFormat("Processing meta handshake: {0}", handshake); if (handshake.IsSuccessful) { object field; object[] serverTransports = handshake.TryGetValue(Message.SupportedConnectionTypesField, out field) ? ObjectConverter.ToObject<object[]>(field) : null; IList<ClientTransport> negotiatedTransports = (serverTransports != null && serverTransports.Length > 0) ? _transportRegistry.Negotiate(Array.ConvertAll<object, string>( serverTransports, o => (null == o) ? null : o.ToString()), BayeuxVersion) : null; ClientTransport newTransport = (negotiatedTransports != null && negotiatedTransports.Count > 0) ? negotiatedTransports[0] : null; if (newTransport == null) { // Signal the failure string error = String.Format(CultureInfo.InvariantCulture, "405:c{0},s{1}:No transport", ObjectConverter.Serialize(this.AllowedTransports), ObjectConverter.Serialize(serverTransports)); handshake.IsSuccessful = false; handshake[Message.ErrorField] = error; // TODO: Also update the advice with reconnect=none for listeners ? this.UpdateBayeuxClientState(oldState => { return (oldState == null) ? null : new DisconnectedState(this, oldState.Transport); }, () => { this.Receive(handshake); }); } else // Has a valid transport ? { this.UpdateBayeuxClientState(oldState => { if (oldState != null) { if (!newTransport.Equals(oldState.Transport)) { oldState.Transport.Reset(); newTransport.Init(); } string action = GetAdviceAction(handshake.Advice, Message.ReconnectRetryValue); if (Message.ReconnectRetryValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { return new ConnectingState(this, oldState.HandshakeFields, handshake.Advice, newTransport, handshake.ClientId); } else if (Message.ReconnectNoneValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { return new DisconnectedState(this, oldState.Transport); } } return null; }, () => { this.Receive(handshake); }); } } else // Try to re-handshake when an error message was arrived { this.UpdateBayeuxClientState(oldState => { if (oldState != null) { string action = GetAdviceAction(handshake.Advice, Message.ReconnectHandshakeValue); if (Message.ReconnectHandshakeValue.Equals(action, StringComparison.OrdinalIgnoreCase) || Message.ReconnectRetryValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { return new ReHandshakingState(this, oldState.HandshakeFields, oldState.Transport, oldState.NextBackOff); } else if (Message.ReconnectNoneValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { return new DisconnectedState(this, oldState.Transport); } } return null; }, () => { this.Receive(handshake); }); } }
protected void processHandshake(IMutableMessage handshake) { if (handshake.Successful) { // @@ax: I think this should be able to return a list of objects? Object serverTransportObject; handshake.TryGetValue(Message_Fields.SUPPORTED_CONNECTION_TYPES_FIELD, out serverTransportObject); IList<Object> serverTransports = serverTransportObject as IList<Object>; //Console.WriteLine("Supported transport: {0}", serverTransport); //IList<Object> serverTransports = new List<Object>(); //serverTransports.Add(serverTransport); IList<ClientTransport> negotiatedTransports = transportRegistry.Negotiate(serverTransports, BAYEUX_VERSION); ClientTransport newTransport = negotiatedTransports.Count == 0 ? null : negotiatedTransports[0]; if (newTransport == null) { updateBayeuxClientState( delegate(BayeuxClientState oldState) { return new DisconnectedState(this, oldState.transport); }, delegate() { receive(handshake); }); // Signal the failure String error = "405:c" + transportRegistry.AllowedTransports + ",s" + serverTransports.ToString() + ":no transport"; handshake.Successful = false; handshake[Message_Fields.ERROR_FIELD] = error; // TODO: also update the advice with reconnect=none for listeners ? } else { updateBayeuxClientState( delegate(BayeuxClientState oldState) { if (newTransport != oldState.transport) { oldState.transport.reset(); newTransport.init(); } String action = getAdviceAction(handshake.Advice, Message_Fields.RECONNECT_RETRY_VALUE); if (Message_Fields.RECONNECT_RETRY_VALUE.Equals(action)) return new ConnectingState(this, oldState.handshakeFields, handshake.Advice, newTransport, handshake.ClientId); else if (Message_Fields.RECONNECT_NONE_VALUE.Equals(action)) return new DisconnectedState(this, oldState.transport); return null; }, delegate() { receive(handshake); }); } } else { updateBayeuxClientState( delegate(BayeuxClientState oldState) { String action = getAdviceAction(handshake.Advice, Message_Fields.RECONNECT_HANDSHAKE_VALUE); if (Message_Fields.RECONNECT_HANDSHAKE_VALUE.Equals(action) || Message_Fields.RECONNECT_RETRY_VALUE.Equals(action)) return new RehandshakingState(this, oldState.handshakeFields, oldState.transport, oldState.nextBackoff()); else if (Message_Fields.RECONNECT_NONE_VALUE.Equals(action)) return new DisconnectedState(this, oldState.transport); return null; }, delegate() { receive(handshake); }); } }
/// <summary> /// En-queues or sends a channel message. /// </summary> public virtual void EnqueueSend(IMutableMessage message) { if (null == message) return; if (this.CanSend) { bool sent = this.SendMessages(message); // DEBUG if (logger.IsDebugEnabled) logger.DebugFormat("{0} message: {1}", sent ? "Sent" : "Failed", message); } else { bool found = false; lock (_messagesQueue) { // Check existence of the message before enqueue object field1, field2; foreach (IMutableMessage m in _messagesQueue) { if (String.Compare(m.Channel, message.Channel, StringComparison.OrdinalIgnoreCase) == 0 && ((m.TryGetValue(Message.SubscriptionField, out field1) && message.TryGetValue(Message.SubscriptionField, out field2) && field1 != null && field2 != null && field1.Equals(field2)) || (m.Data != null && message.Data != null && m.Data.Equals(message.Data))) ) { found = true; break; } } // Ignores duplicate messages if (!found) _messagesQueue.Add(message); } // DEBUG if (!found && logger.IsDebugEnabled) logger.DebugFormat("Enqueued message {0} (batching: {1})", message, this.IsBatching); } }
protected void ProcessHandshake(IMutableMessage handshake) { if (handshake.Successful) { handshake.TryGetValue(MessageFields.SupportedConnectionTypesField, out var serverTransportObject); var serverTransports = JsonConvert.DeserializeObject <IList <object> >(serverTransportObject.ToString()); var negotiatedTransports = _transportRegistry.Negotiate(serverTransports, BayeuxVersion); var newTransport = negotiatedTransports.Count == 0 ? null : negotiatedTransports[0]; if (newTransport == null) { UpdateBayeuxClientState( oldState => new DisconnectedState(this, oldState.Transport), delegate { Receive(handshake); }); // Signal the failure var error = "405:c" + _transportRegistry.AllowedTransports + ",s" + serverTransports + ":no transport"; handshake.Successful = false; handshake[MessageFields.ErrorField] = error; } else { UpdateBayeuxClientState( delegate(BayeuxClientState oldState) { if (newTransport != oldState.Transport) { oldState.Transport.Reset(); newTransport.Init(); } var action = GetAdviceAction(handshake.Advice, MessageFields.ReconnectRetryValue); if (MessageFields.ReconnectRetryValue.Equals(action)) { return(new ConnectingState(this, oldState.HandshakeFields, handshake.Advice, newTransport, handshake.ClientId)); } if (MessageFields.ReconnectNoneValue.Equals(action)) { return(new DisconnectedState(this, oldState.Transport)); } return(null); }, delegate { Receive(handshake); }); } } else { UpdateBayeuxClientState( delegate(BayeuxClientState oldState) { var action = GetAdviceAction(handshake.Advice, MessageFields.ReconnectHandshakeValue); if (MessageFields.ReconnectHandshakeValue.Equals(action) || MessageFields.ReconnectRetryValue.Equals(action)) { return(new RehandshakingState(this, oldState.HandshakeFields, oldState.Transport, oldState.NextBackoff())); } if (MessageFields.ReconnectNoneValue.Equals(action)) { return(new DisconnectedState(this, oldState.Transport)); } return(null); }, delegate { Receive(handshake); }); } }