Beispiel #1
0
 private static bool IsAnythingReceived(SocketReceiveResult result)
 => result != null && result.ContentBytes != null && result.ContentBytes.Length != 0;
Beispiel #2
0
        private async Task ConnectionLoopAsync()
        {
            Exception closeException = null;

            try
            {
                _lastMessageID = 7;
                _connectionCts = new CancellationTokenSource();
                ArraySegment <byte> buffer = new ArraySegment <byte>(new byte[1024]);

                while (_connectionCts?.Token.IsCancellationRequested != true)
                {
                    // read from stream
                    SocketReceiveResult receivedMessage = await ReceiveAsync(buffer, _connectionCts.Token).ConfigureAwait(false);

                    if (!IsAnythingReceived(receivedMessage))
                    {
                        continue;
                    }

                    // parse the message
                    if (receivedMessage.MessageType == WebSocketMessageType.Text)
                    {
                        SocketMessage msg = SocketMessage.Parse(this.MessageEncoding.GetString(receivedMessage.ContentBytes));

                        // if message is binary, read them from stream as well
                        List <byte[]> binaryMessages = new List <byte[]>(msg.BinaryMessagesCount);
                        for (int i = 0; i < msg.BinaryMessagesCount; i++)
                        {
                            SocketReceiveResult receivedBinaryMessage = await ReceiveAsync(buffer, _connectionCts.Token).ConfigureAwait(false);

                            if (!IsAnythingReceived(receivedBinaryMessage))
                            {
                                continue;
                            }
                            if (receivedBinaryMessage.MessageType == WebSocketMessageType.Text)
                            {
                                throw new InvalidDataException("Received a text message while a binary message was expected");
                            }
                            binaryMessages.Add(receivedBinaryMessage.ContentBytes);
                        }
                        // raise event
                        OnTextMessageReceived(msg, binaryMessages);
                    }
                    else
                    {
                        throw new InvalidDataException("Received a binary message while a text message was expected");
                    }
                }
            }
            catch (Exception ex)
            {
                closeException = ex;
                // ignore premature close and task cancellations
                // these should be treated as normal close event, not an error
                if (!IsClosedPrematurelyException(ex) && !(ex is OperationCanceledException))
                {
                    ErrorRaised?.Invoke(this, new UnhandledExceptionEventArgs(ex, true));
                }
            }
            finally
            {
                // craft closed event, keeping the exception in mind
                WebSocketCloseStatus status = _websocketClient?.CloseStatus ??                                                       // websocketclient reported status has priority
                                              (IsClosedPrematurelyException(closeException) ? WebSocketCloseStatus.ProtocolError :   // if premature close, report as protocol error
                                               (closeException is OperationCanceledException) ? WebSocketCloseStatus.NormalClosure : // if operation canceled, report as normal closure
                                               WebSocketCloseStatus.Empty);                                                          // otherwise report unknown status
                string message = _websocketClient?.CloseStatusDescription ?? closeException?.Message;

                // clear cancels and nulls cts, so IsConnected will start returning false
                this.Clear();
                Disconnected?.Invoke(this, new SocketClosedEventArgs(status, message, closeException));
            }
        }