protected bool sendHandshake() { BayeuxClientState bayeuxClientState = this.bayeuxClientState; if (isHandshaking(bayeuxClientState)) { IMutableMessage message = newMessage(); if (bayeuxClientState.handshakeFields != null) { foreach (KeyValuePair <String, Object> kvp in bayeuxClientState.handshakeFields) { message.Add(kvp.Key, kvp.Value); } } message.Channel = Channel_Fields.META_HANDSHAKE; message[Message_Fields.SUPPORTED_CONNECTION_TYPES_FIELD] = AllowedTransports; message[Message_Fields.VERSION_FIELD] = BayeuxClient.BAYEUX_VERSION; if (message.Id == null) { message.Id = newMessageId(); } //Console.WriteLine("Handshaking with extra fields {0}, transport {1}", Print.Dictionary(bayeuxClientState.handshakeFields), Print.Dictionary(bayeuxClientState.transport as IDictionary<String, Object>)); bayeuxClientState.send(handshakeListener, message); return(true); } return(false); }
/// <summary> /// Receives all of the message payloads. /// </summary> /// <param name="session"></param> /// <param name="message"></param> /// <returns></returns> /// <example> /// { /// "clientId": "2d71lgayxukaalrq17ryle2pyeeu6", /// "advice": { /// "interval": 0, /// "reconnect": "none" /// }, /// "channel": "/meta/connect", /// "id": "365", /// "error": "403::Unknown client", /// "successful": false, /// "action": "connect" /// } /// </example> public bool ReceiveMeta(IClientSession session, IMutableMessage message) { Console.WriteLine($"ReceiveMeta: {message}"); if (message.Successful) { OnConnectionSucess(message?.Json); } if (message.ContainsKey("exception")) { var ex = (Exception)message["exception"]; OnConnectionException(ex); } if (message.ContainsKey("error")) { OnConnectionError(message["error"].ToString()); //if (message["error"].ToString().ToLower() == "403::unknown client") //{ // this.OnConnectionError(message["error"].ToString()); //} } return(true); }
protected bool ExtendSend(IMutableMessage message) { if (message.Meta) { foreach (var extension in _extensions) { if (!extension.SendMeta(this, message)) { return(false); } } } else { foreach (var extension in _extensions) { if (!extension.Send(this, message)) { return(false); } } } return(true); }
public bool rcvMeta(IClientSession session, IMutableMessage message) { Dictionary <String, Object> ext = (Dictionary <String, Object>)message.getExt(false); if (ext != null) { Dictionary <String, Object> sync = (Dictionary <String, Object>)ext["timesync"]; if (sync != null) { long now = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; long tc = ObjectConverter.ToInt64(sync["tc"], 0); long ts = ObjectConverter.ToInt64(sync["ts"], 0); int p = ObjectConverter.ToInt32(sync["p"], 0); // final int a=((Number)sync.get("a")).intValue(); int l2 = (int)((now - tc - p) / 2); int o2 = (int)(ts - tc - l2); _lag = _lag == 0 ? l2 : (_lag + l2) / 2; _offset = _offset == 0 ? o2 : (_offset + o2) / 2; } } return(true); }
/// <summary> /// Receives the specified mutable message with each existing session extensions. /// </summary> public virtual bool ExtendReceive(IMutableMessage message) { if (null == message) { return(false); } if (message.IsMeta) { for (int i = 0; i < _extensions.Count; i++) { if (!_extensions[i].ReceiveMeta(this, message)) { return(false); } } } else { for (int i = 0; i < _extensions.Count; i++) { if (!_extensions[i].ReceiveMeta(this, message)) { return(false); } } } return(true); }
public void send(ITransportListener listener, IMutableMessage message) { IList <IMutableMessage> messages = new List <IMutableMessage>(); messages.Add(message); send(listener, messages); }
/// <summary> <p>Receives a message (from the server) and process it.</p> /// <p>Processing the message involves calling the receive {@link ClientSession.Extension extensions} /// and the channel {@link ClientSessionChannel.ClientSessionChannelListener listeners}.</p> /// </summary> /// <param name="message">the message received. /// </param> /// <param name="mutable">the mutable version of the message received /// </param> public void receive(IMutableMessage message) { String id = message.Channel; if (id == null) { throw new ArgumentException("Bayeux messages must have a channel, " + message); } if (!extendRcv(message)) { return; } AbstractSessionChannel channel = (AbstractSessionChannel)getChannel(id); ChannelId channelId = channel.ChannelId; channel.notifyMessageListeners(message); foreach (String channelPattern in channelId.Wilds) { ChannelId channelIdPattern = newChannelId(channelPattern); if (channelIdPattern.matches(channelId)) { AbstractSessionChannel wildChannel = (AbstractSessionChannel)getChannel(channelPattern); wildChannel.notifyMessageListeners(message); } } }
/* ------------------------------------------------------------ */ /// <summary> <p>Receives a message (from the server) and process it.</p> /// <p>Processing the message involves calling the receive {@link ClientSession.Extension extensions} /// and the channel {@link ClientSessionChannel.ClientSessionChannelListener listeners}.</p> /// </summary> /// <param name="message">the message received. /// </param> public void Receive(IMutableMessage message) { var id = message.Channel; if (id == null) { throw new ArgumentException("Bayeux messages must have a channel, " + message); } if (!ExtendRcv(message)) { return; } var channel = (AbstractSessionChannel)GetChannel(id); var channelId = channel.ChannelId; channel.NotifyMessageListeners(message); foreach (var channelPattern in channelId.Wilds) { var channelIdPattern = NewChannelId(channelPattern); if (channelIdPattern.Matches(channelId)) { var wildChannel = (AbstractSessionChannel)GetChannel(channelPattern); wildChannel.NotifyMessageListeners(message); } } }
protected bool sendConnect() { LogHelper.Log($"BayeauxClient: sendConnect()..."); BayeuxClientState bayeuxClientState = this.bayeuxClientState; if (isHandshook(bayeuxClientState)) { IMutableMessage message = newMessage(); message.Channel = Channel_Fields.META_CONNECT; message[Message_Fields.CONNECTION_TYPE_FIELD] = bayeuxClientState.transport.Name; if (bayeuxClientState.type == State.CONNECTING || bayeuxClientState.type == State.UNCONNECTED) { // First connect after handshake or after failure, add advice message.getAdvice(true)["timeout"] = 0; } bayeuxClientState.send(connectListener, message); LogHelper.Log($"BayeauxClient: sendConnect() returning true."); return(true); } LogHelper.Log($"BayeauxClient: sendConnect() returning false."); return(false); }
/// <summary> /// Callback method invoked every time a meta message is being sent. /// </summary> /// <returns>Always true.</returns> /// <exception cref="ArgumentNullException"><paramref name="message"/> is null.</exception> public override bool SendMeta(IClientSession session, IMutableMessage message) { if (message == null) { throw new ArgumentNullException("message"); } string channel = message.Channel; if (Channel.MetaHandshake.Equals(channel, StringComparison.OrdinalIgnoreCase)) { IDictionary <string, object> ext = message.GetExtension(true); lock (ext) ext[ExtensionField] = true; _ackId = -1; } else if (_serverSupportsAcks && Channel.MetaConnect.Equals(channel, StringComparison.OrdinalIgnoreCase)) { IDictionary <string, object> ext = message.GetExtension(true); lock (ext) ext[ExtensionField] = _ackId; } return(true); }
/// <summary> /// Callback method invoked every time a meta message is received. /// </summary> /// <returns>Always true.</returns> /// <exception cref="ArgumentNullException"><paramref name="message"/> is null.</exception> public override bool ReceiveMeta(IClientSession session, IMutableMessage message) { if (message == null) { throw new ArgumentNullException("message"); } string channel = message.Channel; if (Channel.MetaHandshake.Equals(channel, StringComparison.OrdinalIgnoreCase)) { IDictionary <string, object> ext = message.GetExtension(false); object val; _serverSupportsAcks = (ext != null && ext.TryGetValue(ExtensionField, out val) && ObjectConverter.ToPrimitive <bool>(val, false)); } else if (_serverSupportsAcks && message.IsSuccessful && Channel.MetaConnect.Equals(channel, StringComparison.OrdinalIgnoreCase)) { IDictionary <string, object> ext = message.GetExtension(false); object val; if (ext != null && ext.TryGetValue(ExtensionField, out val)) { _ackId = ObjectConverter.ToPrimitive <int>(val, _ackId); } } return(true); }
/// <summary> /// Callback method invoked every time a meta message is received. /// </summary> /// <returns>Always true.</returns> /// <exception cref="ArgumentNullException"><paramref name="message"/> is null.</exception> public override bool ReceiveMeta(IClientSession session, IMutableMessage message) { if (message == null) { throw new ArgumentNullException("message"); } IDictionary <string, object> ext = message.GetExtension(false); object val; if (ext != null && ext.TryGetValue(ExtensionField, out val)) { IDictionary <string, object> sync = ObjectConverter.ToObject <IDictionary <string, object> >(val); if (sync != null && // && sync.ContainsKey("a") sync.ContainsKey("tc") && sync.ContainsKey("ts") && sync.ContainsKey("p")) { long now = CurrentTimeMillis(); long tc = ObjectConverter.ToPrimitive <long>(sync["tc"], 0); long ts = ObjectConverter.ToPrimitive <long>(sync["ts"], 0); int p = ObjectConverter.ToPrimitive <int>(sync["p"], 0); //int a = ObjectConverter.ToPrimitive<int>(sync["a"], 0); int l2 = (int)((now - tc - p) / 2); int o2 = (int)(ts - tc - l2); _lag = (_lag == 0) ? l2 : ((_lag + l2) / 2); _offset = (_offset == 0) ? o2 : ((_offset + o2) / 2); } } return(true); }
/// <summary> /// Receives a message (from the server) and process it. /// </summary> /// <param name="message">The mutable version of the message received.</param> protected virtual void ProcessMessage(IMutableMessage message) { if (null != message) { _session.ProcessMessage(message); } }
public bool rcvMeta(IClientSession session, IMutableMessage message) { Dictionary<String, Object> ext = (Dictionary<String, Object>)message.getExt(false); if (ext != null) { Dictionary<String, Object> sync = (Dictionary<String, Object>)ext["timesync"]; if (sync != null) { long now = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; long tc = ObjectConverter.ToInt64(sync["tc"], 0); long ts = ObjectConverter.ToInt64(sync["ts"], 0); int p = ObjectConverter.ToInt32(sync["p"], 0); // final int a=((Number)sync.get("a")).intValue(); int l2 = (int)((now - tc - p) / 2); int o2 = (int)(ts - tc - l2); _lag = _lag == 0 ? l2 : (_lag + l2) / 2; _offset = _offset == 0 ? o2 : (_offset + o2) / 2; } } return true; }
public bool ReceiveMeta(IClientSession session, IMutableMessage message) { var ext = (Dictionary<string, object>)message.GetExt(false); if (ext != null) { var sync = (Dictionary<string, object>)ext["timesync"]; if (sync != null) { var now = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; var tc = ObjectConverter.ToInt64(sync["tc"], 0); var ts = ObjectConverter.ToInt64(sync["ts"], 0); var p = ObjectConverter.ToInt32(sync["p"], 0); // final int a=((Number)sync.get("a")).intValue(); var l2 = (int)((now - tc - p) / 2); var o2 = (int)(ts - tc - l2); Lag = Lag == 0 ? l2 : (Lag + l2) / 2; Offset = Offset == 0 ? o2 : (Offset + o2) / 2; } } return true; }
public override void execute() { IMutableMessage message = bayeuxClient.newMessage(); message.Channel = Channel_Fields.META_DISCONNECT; send(bayeuxClient.disconnectListener, message); }
public bool Receive(IClientSession session, IMutableMessage message) { // can retrieve actual replay ids for messages here if needed. // var ext = (Dictionary<string, object>)message.GetExt(false); // var e = ext[Message_Fields.EVENT_FIELD]; return(true); }
private static long?GetReplayId(IMutableMessage message) { var replayId = ((JObject)((JObject)message[MessageFields.DataField])?[MessageFields.EventField])?[MessageFields.ReplayIdField]; return(replayId != null ? (long)replayId : (long?)null); }
protected override void sendUnSubscribe() { IMutableMessage message = bayeuxClient.newMessage(); message.Channel = Channel_Fields.META_UNSUBSCRIBE; message[Message_Fields.SUBSCRIPTION_FIELD] = Id; bayeuxClient.enqueueSend(message); }
/// <summary> /// Callback method invoked every time a meta message is being sent. /// </summary> /// <returns>Always true.</returns> /// <exception cref="ArgumentNullException"><paramref name="message"/> is null.</exception> public override bool SendMeta(IClientSession session, IMutableMessage message) { if (message == null) throw new ArgumentNullException("message"); AddTimestamp(message); return true; }
/// <summary> /// Sends a new disconnecting command to the Bayeux server. /// </summary> public override void Execute() { IMutableMessage message = this.Session.NewMessage(); message.Channel = Channel.MetaDisconnect; this.Send(this.Session.DisconnectListener, message); }
public bool SendMeta(IClientSession session, IMutableMessage message) { var ext = (Dictionary<string, object>)message.GetExt(true); var now = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; // Changed JSON.Literal to string var timesync = "{\"tc\":" + now + ",\"l\":" + Lag + ",\"o\":" + Offset + "}"; ext["timesync"] = timesync; return true; }
protected void ProcessDisconnect(IMutableMessage disconnect) { UpdateBayeuxClientState( oldState => new DisconnectedState(this, oldState.Transport), delegate { Receive(disconnect); }); }
public void Send(ITransportListener listener, IMutableMessage message) { IList <IMutableMessage> messages = new List <IMutableMessage> { message }; Send(listener, messages); }
private static void AddTimestamp(IMutableMessage message) { lock (message) { // RFC 1123 DateTime Format "EEE, dd MMM yyyy HH:mm:ss 'GMT'" message[Message.TimestampField] = DateTime.Now.ToString("r", CultureInfo.GetCultureInfo(1033));// en-US } }
public bool sendMeta(IClientSession session, IMutableMessage message) { Dictionary<String, Object> ext = (Dictionary<String, Object>)message.getExt(true); long now = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; // Changed JSON.Literal to String String timesync = "{\"tc\":" + now + ",\"l\":" + _lag + ",\"o\":" + _offset + "}"; ext["timesync"] = timesync; return true; }
public void Send(ITransportListener listener, IMutableMessage message, int clientTimeout = ClientTransport.DEFAULT_TIMEOUT) { IList <IMutableMessage> messages = new List <IMutableMessage> { message }; Send(listener, messages, clientTimeout); }
public bool ReceiveMeta(IClientSession session, IMutableMessage message) { if (ChannelFields.META_HANDSHAKE.Equals(message.Channel)) { var ext = (Dictionary <string, object>)message.GetExt(false); _serverSupportsReplay = ext != null && true.Equals(ext[EXTENSION_NAME]); } return(true); }
public bool sendMeta(IClientSession session, IMutableMessage message) { Dictionary <String, Object> ext = (Dictionary <String, Object>)message.getExt(true); long now = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; // Changed JSON.Literal to String String timesync = "{\"tc\":" + now + ",\"l\":" + _lag + ",\"o\":" + _offset + "}"; ext["timesync"] = timesync; return(true); }
public bool ReceiveMeta(IClientSession session, IMutableMessage message) { if (ChannelFields.MetaHandshake.Equals(message.Channel)) { var ext = message.GetExt(false); _serverSupportsReplay = ext?[ExtField] != null; } return(true); }
protected override void ProcessMessage(IMutableMessage message) { if (ChannelFields.META_DISCONNECT.Equals(message.Channel)) { bayeuxClient.ProcessDisconnect(message); } else { base.ProcessMessage(message); } }
protected override void ProcessMessage(IMutableMessage message) { if (ChannelFields.META_HANDSHAKE.Equals(message.Channel)) { bayeuxClient.ProcessHandshake(message); } else { base.ProcessMessage(message); } }
public bool sendMeta(IClientSession session, IMutableMessage message) { if (Channel_Fields.META_HANDSHAKE.Equals(message.Channel)) { message.getExt(true)[EXT_FIELD] = true; _ackId = -1; } else if (_serverSupportsAcks && Channel_Fields.META_CONNECT.Equals(message.Channel)) { message.getExt(true)[EXT_FIELD] = _ackId; } return true; }
protected bool extendRcv(IMutableMessage message) { if (message.Meta) { foreach (IExtension extension in _extensions) if (!extension.rcvMeta(this, message)) return false; } else { foreach (IExtension extension in _extensions) if (!extension.rcv(this, message)) return false; } return true; }
public bool rcvMeta(IClientSession session, IMutableMessage message) { if (Channel_Fields.META_HANDSHAKE.Equals(message.Channel)) { Dictionary<String, Object> ext = (Dictionary<String, Object>)message.getExt(false); _serverSupportsAcks = ext != null && true.Equals(ext[EXT_FIELD]); } else if (_serverSupportsAcks && true.Equals(message[Message_Fields.SUCCESSFUL_FIELD]) && Channel_Fields.META_CONNECT.Equals(message.Channel)) { Dictionary<String, Object> ext = (Dictionary<String, Object>)message.getExt(false); if (ext != null) { Object ack; ext.TryGetValue(EXT_FIELD, out ack); _ackId = ObjectConverter.ToInt32(ack, _ackId); } } return true; }
protected void enqueueSend(IMutableMessage message) { if (canSend()) { IList<IMutableMessage> messages = new List<IMutableMessage>(); messages.Add(message); bool sent = sendMessages(messages); //Console.WriteLine("{0} message {1}", sent?"Sent":"Failed", message); } else { messageQueue.Enqueue(message); //Console.WriteLine("Enqueued message {0} (batching: {1})", message, this.Batching); } }
protected virtual void processMessage(IMutableMessage message) { bayeuxClient.processMessage(message); }
/// <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 processConnect(IMutableMessage connect) { updateBayeuxClientState( delegate(BayeuxClientState oldState) { IDictionary<String, Object> advice = connect.Advice; if (advice == null) advice = oldState.advice; String action = getAdviceAction(advice, Message_Fields.RECONNECT_RETRY_VALUE); if (connect.Successful) { if (Message_Fields.RECONNECT_RETRY_VALUE.Equals(action)) return new ConnectedState(this, oldState.handshakeFields, advice, oldState.transport, oldState.clientId); else if (Message_Fields.RECONNECT_NONE_VALUE.Equals(action)) // This case happens when the connect reply arrives after a disconnect // We do not go into a disconnected state to allow normal processing of the disconnect reply return new DisconnectingState(this, oldState.transport, oldState.clientId); } else { if (Message_Fields.RECONNECT_HANDSHAKE_VALUE.Equals(action)) return new RehandshakingState(this, oldState.handshakeFields, oldState.transport, 0); else if (Message_Fields.RECONNECT_RETRY_VALUE.Equals(action)) return new UnconnectedState(this, oldState.handshakeFields, advice, oldState.transport, oldState.clientId, oldState.nextBackoff()); else if (Message_Fields.RECONNECT_NONE_VALUE.Equals(action)) return new DisconnectedState(this, oldState.transport); } return null; }, delegate() { receive(connect); }); }
/// <summary> /// Receives a message (from the server) and process it. /// </summary> /// <param name="message">The mutable version of the message received.</param> protected virtual void ProcessMessage(IMutableMessage message) { if (null != message) _session.ProcessMessage(message); }
/// <summary> /// Processes the disconnecting message have just arrived. /// </summary> protected override void ProcessMessage(IMutableMessage message) { if (message != null && Channel.MetaDisconnect.Equals(message.Channel, StringComparison.OrdinalIgnoreCase)) { this.Session.ProcessDisconnect(message); } else { base.ProcessMessage(message); } }
/// <summary> /// Processes a disconnecting message have just arrived. /// </summary> public virtual void ProcessDisconnect(IMutableMessage disconnect) { if (null == disconnect) throw new ArgumentNullException("disconnect"); // DEBUG if (logger.IsDebugEnabled) logger.DebugFormat("Processing meta disconnect: {0}", disconnect); this.UpdateBayeuxClientState(oldState => { return (oldState == null) ? null : new DisconnectedState(this, oldState.Transport); }, () => { this.Receive(disconnect); }); }
/// <summary> /// Processes a connecting message have just arrived. /// </summary> public virtual void ProcessConnect(IMutableMessage connect) { if (null == connect) throw new ArgumentNullException("connect"); // TODO: Split "connected" state into ConnectSent + ConnectReceived ? // It may happen that the server replies to the meta connect with a delay // that exceeds the maxNetworkTimeout (for example because the server is // busy and the meta connect reply thread is starved). // In this case, it is possible that we issue 2 concurrent connects, one // for the response arrived late, and one from the unconnected state. // We should avoid this, although it is a very rare case. // DEBUG if (logger.IsDebugEnabled) logger.DebugFormat("Processing meta connect: {0}", connect); this.UpdateBayeuxClientState(oldState => { if (oldState != null) { IDictionary<string, object> advice = connect.Advice; if (advice == null) advice = oldState.Advice; string action = GetAdviceAction(advice, Message.ReconnectRetryValue); if (connect.IsSuccessful) { if (Message.ReconnectRetryValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { return new ConnectedState(this, oldState.HandshakeFields, advice, oldState.Transport, oldState.ClientId); } else if (Message.ReconnectNoneValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { // This case happens when the connect reply arrives after a disconnect // We do not go into a disconnected state to allow normal processing of the disconnect reply return new DisconnectingState(this, oldState.Transport, oldState.ClientId); } } else // Try to re-handshake / re-connect when an error message was arrived { if (Message.ReconnectHandshakeValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { return new ReHandshakingState(this, oldState.HandshakeFields, oldState.Transport, 0); } else if (Message.ReconnectRetryValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { return new UnconnectedState(this, oldState.HandshakeFields, advice, oldState.Transport, oldState.ClientId, oldState.NextBackOff); } else if (Message.ReconnectNoneValue.Equals(action, StringComparison.OrdinalIgnoreCase)) { return new DisconnectedState(this, oldState.Transport); } } } return null; }, () => { this.Receive(connect); }); }
/// <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); }); } }
/// <summary> /// Multiple threads can call this method concurrently (for example /// a batched Publish() is executed exactly when a message arrives /// and a listener also performs a batched Publish() in response to /// the message). /// The queue must be drained atomically, otherwise we risk that the /// same message is drained twice. /// </summary> public virtual IMutableMessage[] TakeMessages() { IMutableMessage[] messages; lock (_messagesQueue) { messages = new IMutableMessage[_messagesQueue.Count]; _messagesQueue.CopyTo(messages, 0); _messagesQueue.Clear(); } return messages; }
protected void processMessage(IMutableMessage message) { // logger.debug("Processing message {}", message); receive(message); }
protected void processDisconnect(IMutableMessage disconnect) { updateBayeuxClientState( delegate(BayeuxClientState oldState) { return new DisconnectedState(this, oldState.transport); }, delegate() { receive(disconnect); }); }
/// <summary> /// <p>Receives a message (from the server) and process it.</p> /// <p>Processing the message involves calling the receive extensions and the channel listeners.</p> /// </summary> /// <param name="message">The mutable version of the message received.</param> public virtual void Receive(IMutableMessage message) { if (null == message) throw new ArgumentNullException("message"); string id = message.Channel; if (String.IsNullOrEmpty(id)) throw new ArgumentException("Bayeux messages must have a channel, " + message); if (!this.ExtendReceive(message)) return; ChannelId channelId; IClientSessionChannel channel = this.GetChannel(id, false); if (null != channel) { channelId = channel.ChannelId; channel.NotifyMessageListeners(message); } else channelId = message.ChannelId; foreach (string wildChannelName in channelId.Wilds) { //channelIdPattern = this.NewChannelId(channelPattern); //if (channelIdPattern != null && channelIdPattern.Matches(channelId)) //{ channel = this.GetChannel(wildChannelName, false);// Wild channel if (channel != null) channel.NotifyMessageListeners(message); //} } }
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> /// Receives the specified mutable message with each existing session extensions. /// </summary> public virtual bool ExtendReceive(IMutableMessage message) { if (null == message) return false; if (message.IsMeta) { for (int i = 0; i < _extensions.Count; i++) { if (!_extensions[i].ReceiveMeta(this, message)) return false; } } else { for (int i = 0; i < _extensions.Count; i++) { if (!_extensions[i].ReceiveMeta(this, message)) return false; } } return true; }
public void send(ITransportListener listener, IMutableMessage message) { IList<IMutableMessage> messages = new List<IMutableMessage>(); messages.Add(message); send(listener, messages); }
protected override void processMessage(IMutableMessage message) { if (Channel_Fields.META_DISCONNECT.Equals(message.Channel)) bayeuxClient.processDisconnect(message); else base.processMessage(message); }
/* ------------------------------------------------------------ */ /// <summary> <p>Receives a message (from the server) and process it.</p> /// <p>Processing the message involves calling the receive {@link ClientSession.Extension extensions} /// and the channel {@link ClientSessionChannel.ClientSessionChannelListener listeners}.</p> /// </summary> /// <param name="message">the message received. /// </param> /// <param name="mutable">the mutable version of the message received /// </param> public void receive(IMutableMessage message) { String id = message.Channel; if (id == null) { throw new ArgumentException("Bayeux messages must have a channel, " + message); } if (!extendRcv(message)) return; AbstractSessionChannel channel = (AbstractSessionChannel)getChannel(id); ChannelId channelId = channel.ChannelId; channel.notifyMessageListeners(message); foreach (String channelPattern in channelId.Wilds) { ChannelId channelIdPattern = newChannelId(channelPattern); if (channelIdPattern.matches(channelId)) { AbstractSessionChannel wildChannel = (AbstractSessionChannel)getChannel(channelPattern); wildChannel.notifyMessageListeners(message); } } }
protected override void processMessage(IMutableMessage message) { if (Channel_Fields.META_HANDSHAKE.Equals(message.Channel)) bayeuxClient.processHandshake(message); else base.processMessage(message); }
public bool send(IClientSession session, IMutableMessage message) { return true; }
/// <summary> /// Receives a normal message. /// </summary> public virtual void ProcessMessage(IMutableMessage message) { if (null == message) throw new ArgumentNullException("message"); // DEBUG if (logger.IsDebugEnabled) logger.DebugFormat("Processing message: {0}", message); this.Receive(message); }