Ejemplo n.º 1
0
        /// <summary>
        /// The read loop.
        /// </summary>
        private async void ReadLoop()
        {
            do
            {
                if (_client.State == WebSocketState.Open)
                {
                    // create the receive buffer
                    ArraySegment <byte> receiveBuffer = new ArraySegment <byte>(new byte[8192]);
                    MemoryStream        receiveStream = new MemoryStream();

                    while (_client.State == WebSocketState.Open)
                    {
                        // receive into buffer
                        WebSocketReceiveResult result = null;

                        try {
                            result = await _client.ReceiveAsync(receiveBuffer, default(CancellationToken)).ConfigureAwait(false);
                        } catch (Exception ex) {
                            Debug.WriteLine($"Failed to receive buffer from websocket: {ex.ToString()}");
                            break;
                        }

                        // check if close message
                        if (result.MessageType == WebSocketMessageType.Close)
                        {
                            break;
                        }

                        // append to stream
                        receiveStream.Write(receiveBuffer.Array, receiveBuffer.Offset, result.Count);

                        // if end of message process
                        if (result.EndOfMessage)
                        {
                            // get message data
                            byte[] messageBytes = receiveStream.ToArray();

                            // decode message
                            JObject message = null;

                            try {
                                message = JObject.Parse(Encoding.UTF8.GetString(messageBytes));
                            } catch (Exception ex) {
                                Debug.WriteLine($"Failed to parse buffer from websocket: {ex.ToString()}");
                                break;
                            }

                            // check message type
                            if (!message.TryGetValue("Type", out JToken typeToken) || typeToken.Type != JTokenType.String)
                            {
                                Debug.WriteLine($"Failed to parse buffer from websocket: Type is empty or invalid");
                                break;
                            }

                            // check message payload
                            if (!message.TryGetValue("Data", out JToken payloadToken) || payloadToken.Type != JTokenType.Object)
                            {
                                Debug.WriteLine($"Failed to parse buffer from websocket: Payload is empty or invalid");
                                break;
                            }

                            object data = null;
                            string type = ((string)typeToken);

                            if (type.Equals("Event", StringComparison.CurrentCultureIgnoreCase))
                            {
                                // deserialize event
                                try {
                                    data = payloadToken.ToObject <Event>();
                                } catch (Exception ex) {
                                    Debug.WriteLine($"Failed to parse deserialize event: {ex.ToString()}");
                                    break;
                                }

                                // deserialize event data
                                Event e = (Event)data;

                                try {
                                    e.Data = ((JObject)e.Data).ToObject(EventName.GetEntityType(((Event)data).Name));
                                } catch (Exception) {
                                    Debug.WriteLine($"Failed to parse buffer from websocket: Payload is empty or invalid");
                                }

                                // notify subscribers
                                OnReceived(new EventReceivedEventArgs(e, this));
                            }
                            else
                            {
                                Debug.WriteLine($"Unimplemented frame sent by server: {type}");
                            }

                            // prepare for next message
                            receiveStream = new MemoryStream();
                        }
                    }

                    // invoke disconnected
                    OnDisconnected(new EventArgs());
                }

                // try and auto reconnect
                try {
                    // ensure the client has been aborted
                    try {
                        _client.Abort();
                    } catch (Exception) { }

                    // try and reconnect
                    await ConnectAndAuthenticateAsync(default(CancellationToken), true).ConfigureAwait(false);
                    await ResubscribeAllAsync().ConfigureAwait(false);
                } catch {
                    await Task.Delay(5000).ConfigureAwait(false);
                }
            } while (_autoReconnect && !_reset);
        }