/// <summary> /// Salesforce disconnects at random the client and the client must be re-connected and also re-subscribed. /// </summary> /// <param name="sender"></param> /// <param name="message"></param> private void ErrorExtension_ConnectionError(object sender, string message) { // authentication failure if (message.ToLower() == "403::Handshake denied" || message.ToLower() == "403:denied_by_security_policy:create_denied" || message.ToLower() == "403::unknown client" ) { _logger.LogError($"Handled CometD Exception: {message}"); _logger.LogDebug($"Re-authenticating BayeuxClient..."); // 1. Disconnect Disconnect(); _logger.LogDebug($"Disconnecting {nameof(BayeuxClient)}..."); // 2. try (x) times to re-authenticate Reauthenticate(); _logger.LogDebug($"Re-authenticating {nameof(BayeuxClient)}..."); // 3. populate a new transport with new security headers. InitBayeuxClient(); _logger.LogDebug($"Re-Init {nameof(BayeuxClient)}..."); // invoke event Reconnect?.Invoke(this, true); } else { _logger.LogError($"{nameof(StreamingClient)} failed with the following message: {message}"); } }
private void ErrorExtension_ConnectionError( object sender, string e) { // authentication failure if (string.Equals(e, "403::Handshake denied", StringComparison.OrdinalIgnoreCase) || string.Equals(e, "403:denied_by_security_policy:create_denied", StringComparison.OrdinalIgnoreCase) || string.Equals(e, "403::unknown client", StringComparison.OrdinalIgnoreCase) ) { _logger.LogWarning("Handled CometD Exception: {message}", e); // 1. Disconnect existing client. Disconnect(); // 2. Invalidate the access token. _tokenResponse.Invalidate(); _logger.LogDebug("Invalidate token for {name} ...", nameof(BayeuxClient)); // 3. Recreate BayeuxClient and populate it with a new transport with new security headers. CreateBayeuxClient(); // 4. Invoke the Reconnect Event Reconnect?.Invoke(this, true); } else { _logger.LogError("{name} failed with the following message: {message}", nameof(ResilientStreamingClient), e); } }
protected virtual void ErrorExtension_ConnectionError( object sender, string e) { // authentication failure if (string.Equals(e, "403::Handshake denied", StringComparison.OrdinalIgnoreCase) || string.Equals(e, "403:denied_by_security_policy:create_denied", StringComparison.OrdinalIgnoreCase) || string.Equals(e, "403::unknown client", StringComparison.OrdinalIgnoreCase) || string.Equals(e, "401::Authentication invalid", StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning("Handled CometD Exception: {message}", e); // 1. Disconnect existing client. Disconnect(); // 2. Invalidate the access token. _tokenResponse.Invalidate(); _logger.LogDebug("Invalidate token for {name} ...", nameof(BayeuxClient)); // 3. Recreate BayeuxClient and populate it with a new transport with new security headers. CreateBayeuxClient(); // 4. Invoke the Reconnect Event Reconnect?.Invoke(this, true); } else if (e.Contains("you provided was invalid")) { var start = e.IndexOf('{'); var end = e.IndexOf('}'); var replayIdString = e.Substring(start + 1, end - (start + 1)); if (int.TryParse(replayIdString, out var replayId)) { InvalidReplayIdStrategy(replayId); } } else { _logger.LogError("{name} failed with the following message: {message}", nameof(ResilientStreamingClient), e); } }
private void HandleEvent(PubsubPayload evnt) { switch (evnt.Operation) { case PubsubOperation.Ping: SendHeartbeatAck(); Heartbeat?.Invoke(); break; case PubsubOperation.Pong: HeartbeatAck?.Invoke(); break; case PubsubOperation.Reconnect: Reconnect?.Invoke(); throw new TimeoutException("Server requested a reconnect"); case PubsubOperation.Message: HandleDispatchEvent(evnt); break; } }
void ProcessMessage(IrcMessage message) { if (message.Command == $":{message.Source}" && message.Arguments.Length > 0) { // twitch seems to have issues building proper irc messages ProcessMessage(new IrcMessage(message.Arguments[0], message.Arguments.Skip(1).ToArray())); return; } string channelname; switch (message.Command) { case "CAP": if (message.Arguments.Length < 3) { break; } if (message.Arguments[1] == "ACK") { CapAcknowledged?.Invoke(message.Arguments[2]); } break; case "PING": SendMessage(new IrcMessage("PONG", message.Arguments)); break; case "JOIN": channelname = GetChannelName(message.Arguments[0]); if (message.ExtractUser().ToLower() == user.ToLower()) { JoinChannel(channelname); } SendChannelMessage(channelname, message); break; case "PART": channelname = GetChannelName(message.Arguments[0]); SendChannelMessage(channelname, message); if (message.ExtractUser().ToLower() == user.ToLower()) { ChatChannel channel; lock (channellock) { if (channels.TryGetValue(channelname, out channel)) { channels.Remove(channelname); } } if (channel != null) { ChannelLeft?.Invoke(channel); } } break; case "tmi.twitch.tv RECONNECT": case "RECONNECT": Reconnect?.Invoke(); break; case "001": case "002": case "003": case "004": // connection success break; case "372": case "375": // message of the day break; case "376": connectionwait.Set(); // end of message of the day break; case "353": GetChannel(message.Arguments[2])?.OnMessage(message); break; case "366": GetChannel(message.Arguments[1])?.OnMessage(message); break; case "ROOMSTATE": case "PRIVMSG": case "USERNOTICE": case "NOTICE": case "USERSTATE": SendChannelMessage(message.Arguments[0], message); break; case "HOSTTARGET": if (!message.Arguments[1].StartsWith("-")) { TrySendChannelMessage(message.Arguments[0], message); TrySendChannelMessage(message.Arguments[1].Split(' ')[0], message); } break; case "MODE": // channel or user mode ... not that important for now break; default: Logger.Warning(this, "Unprocessed message", message.ToString()); break; } }
internal void OnReconnect(object t, EventArgs e) { Reconnect?.Invoke(t, e); }