Exemplo n.º 1
0
        public PubSubClient(
            Config.BotConfiguration botConfig,
            ICommunication communication,
            IRedemptionSystem redemptionHandler,
            ErrorHandler errorHandler)
        {
            this.botConfig         = botConfig;
            this.communication     = communication;
            this.errorHandler      = errorHandler;
            this.redemptionHandler = redemptionHandler;

            pingMessage = new BasicPubSubMessage("PING");
            pongMessage = new BasicPubSubMessage("PONG");
        }
Exemplo n.º 2
0
        private async void ReadMessages()
        {
            WebSocketReceiveResult webSocketReceiveResult = null;
            string lastMessage = null;

            try
            {
                readers.AddCount();

                while (true)
                {
                    await CheckConnectionOrWait();

                    bool readCompleted = false;

                    try
                    {
                        webSocketReceiveResult = await clientWebSocket.ReceiveAsync(incomingData, readerTokenSource.Token);

                        readCompleted = true;
                    }
                    catch (TaskCanceledException) { /* swallow */ }
                    catch (ThreadAbortException) { /* swallow */ }
                    catch (ObjectDisposedException) { /* swallow */ }
                    catch (OperationCanceledException) { /* swallow */ }
                    catch (WebSocketException)
                    {
                        communication.SendWarningMessage($"PubSub Websocket closed unexpectedly.");
                    }
                    catch (Exception ex)
                    {
                        communication.SendErrorMessage($"PubSub Exception: {ex.GetType().Name}");
                        errorHandler.LogMessageException(ex, "");
                    }

                    if (generalTokenSource.IsCancellationRequested)
                    {
                        //We are quitting
                        break;
                    }

                    if ((readerTokenSource?.IsCancellationRequested ?? true) || !readCompleted)
                    {
                        //We are just restarting reader, since it was intercepted with an exception or the reader token source was cancelled
                        continue;
                    }

                    if (webSocketReceiveResult.Count < 1)
                    {
                        await Task.Delay(100, generalTokenSource.Token);

                        continue;
                    }

                    lastMessage = Encoding.UTF8.GetString(incomingData, 0, webSocketReceiveResult.Count);

                    while (!webSocketReceiveResult.EndOfMessage)
                    {
                        readCompleted = false;
                        try
                        {
                            webSocketReceiveResult = await clientWebSocket.ReceiveAsync(incomingData, readerTokenSource.Token);

                            readCompleted = true;
                        }
                        catch (TaskCanceledException) { /* swallow */ }
                        catch (ThreadAbortException) { /* swallow */ }
                        catch (ObjectDisposedException) { /* swallow */ }
                        catch (OperationCanceledException) { /* swallow */ }
                        catch (WebSocketException)
                        {
                            communication.SendWarningMessage($"PubSub Websocket closed unexpectedly.");
                        }
                        catch (Exception ex)
                        {
                            communication.SendErrorMessage($"PubSub Exception: {ex.GetType().Name}");
                            errorHandler.LogMessageException(ex, "");
                        }

                        if (generalTokenSource.IsCancellationRequested)
                        {
                            //We are quitting
                            break;
                        }

                        if ((readerTokenSource?.IsCancellationRequested ?? true) || !readCompleted)
                        {
                            //We are just restarting reader, since it was intercepted with an exception or the reader token source was cancelled
                            break;
                        }

                        if (webSocketReceiveResult.Count < 1)
                        {
                            communication.SendWarningMessage($"WebSocketMessage returned no characters despite not being at end.  {lastMessage}");
                            break;
                        }

                        lastMessage += Encoding.UTF8.GetString(incomingData, 0, webSocketReceiveResult.Count);
                    }


                    if (generalTokenSource.IsCancellationRequested)
                    {
                        //We are quitting
                        break;
                    }

                    if ((readerTokenSource?.IsCancellationRequested ?? true) || !readCompleted)
                    {
                        //We are just restarting reader, since it was intercepted with an exception or the reader token source was cancelled
                        continue;
                    }

                    BasicPubSubMessage message = JsonSerializer.Deserialize <BasicPubSubMessage>(lastMessage);

                    switch (message.TypeString)
                    {
                    case "PONG":
                        pongReceived = true;
                        break;

                    case "PING":
                        await SendMessage(pongMessage);

                        break;

                    case "RECONNECT":
                        communication.SendDebugMessage($"PubSub Reconnect Message Received");
                        breakConnection = true;
                        break;

                    case "RESPONSE":
                    {
                        PubSubResponseMessage response    = JsonSerializer.Deserialize <PubSubResponseMessage>(lastMessage);
                        PubSubMessage         sentMessage = sentMessages.Where(x => x.Nonce == response.Nonce).FirstOrDefault();

                        if (!string.IsNullOrEmpty(response.ErrorString))
                        {
                            if (sentMessage is not null)
                            {
                                communication.SendErrorMessage($"Error with message {JsonSerializer.Serialize(sentMessage)}: {response.ErrorString}");
                            }
                            else
                            {
                                communication.SendErrorMessage($"Error with message <Unable To Locate>: {response.ErrorString}");
                            }
                        }

                        if (sentMessage is not null)
                        {
                            sentMessages.Remove(sentMessage);
                        }
                    }
                    break;

                    case "MESSAGE":
                    {
                        ListenResponse listenResponse = JsonSerializer.Deserialize <ListenResponse>(lastMessage);

                        BaseMessageData messageData = JsonSerializer.Deserialize <BaseMessageData>(listenResponse.Data.Message);

                        switch (messageData.TypeString)
                        {
                        case "reward-redeemed":
                            ChannelPointMessageData channelPointMessageData = JsonSerializer.Deserialize <ChannelPointMessageData>(listenResponse.Data.Message);
                            redemptionHandler.HandleRedemption(channelPointMessageData.Data);
                            break;

                        default:
                            communication.SendErrorMessage($"Unsupported PubSub Message: {messageData.TypeString} - {listenResponse.Data.Message}");
                            break;
                        }
                    }
                    break;

                    default:
                        communication.SendErrorMessage($"Unsupported PubSub Message Type: {message.TypeString} - {lastMessage}");
                        break;
                    }
                }
            }
            catch (TaskCanceledException) { /* swallow */ }
            catch (ThreadAbortException) { /* swallow */ }
            catch (ObjectDisposedException) { /* swallow */ }
            catch (OperationCanceledException) { /* swallow */ }
            catch (Exception ex)
            {
                communication.SendErrorMessage($"PubSub Exception: {ex.GetType().Name}");
                if (lastMessage is not null)
                {
                    communication.SendErrorMessage($"Last PubSub Message: {lastMessage}");
                }

                errorHandler.LogMessageException(ex, "");
            }
            finally
            {
                readers.Signal();
            }
        }