public void ConstructorTests_DefaultConstructor_MatchesLastError()
 {
     int error = Marshal.GetLastWin32Error();
     var exc = new WebSocketException();
     Assert.Equal(error, exc.NativeErrorCode);
     Assert.Equal(error, exc.ErrorCode);
 }
예제 #2
0
 public void ConstructorTests_WebSocketError_Success(WebSocketError error)
 {
     var wse = new WebSocketException(error);
     Assert.Equal(error, wse.WebSocketErrorCode);
     Assert.NotEqual("", wse.Message);
     Assert.Null(wse.InnerException);
 }
예제 #3
0
 public void ConstructorTests_WebSocketError_Message_Success(WebSocketError error)
 {
     const string Message = "Message";
     var wse = new WebSocketException(error, Message);
     Assert.Equal(error, wse.WebSocketErrorCode);
     Assert.Equal(Message, wse.Message);
     Assert.Null(wse.InnerException);
 }
예제 #4
0
 public void ConstructorTests_NativeError_Success(int nativeError, WebSocketError webSocketError, int expectedHResult)
 {
     var wse = new WebSocketException(nativeError);
     Assert.Equal(expectedHResult, wse.HResult);
     Assert.Equal(webSocketError, wse.WebSocketErrorCode);
     Assert.NotEqual("", wse.Message);
     Assert.Null(wse.InnerException);
 }
예제 #5
0
 public void ConstructorTests_NativeError_Success(int nativeError, WebSocketError webSocketError)
 {
     var wse = new WebSocketException(nativeError);
     Assert.Equal(wse.HResult, nativeError);
     Assert.Equal(wse.WebSocketErrorCode, webSocketError);
     Assert.NotEqual(wse.Message, "");
     Assert.Null(wse.InnerException);
 }
예제 #6
0
 public void ConstructorTests_WebSocketError_Exception_Success(WebSocketError error)
 {
     var inner = new Exception();
     var wse = new WebSocketException(error, inner);
     Assert.Equal(error, wse.WebSocketErrorCode);
     Assert.NotEqual("", wse.Message);
     Assert.Same(inner, wse.InnerException);
 }
예제 #7
0
 public void ConstructorTests_WebSocketError_Message_Exception_Success(WebSocketError error)
 {
     const string Message = "Message";
     var inner = new Exception();
     var wse = new WebSocketException(error, Message, inner);
     Assert.Equal(wse.WebSocketErrorCode, error);
     Assert.Equal(wse.Message, Message);
     Assert.Equal(wse.InnerException, inner);
 }
예제 #8
0
        private async Task ConnectAsyncJavaScript(Uri uri, CancellationToken cancellationToken)
        {
            var tcsConnect = new TaskCompletionSource <bool> ();

            // For Abort/Dispose.  Calling Abort on the request at any point will close the connection.
            cts.Token.Register(AbortRequest);

            // Wrap the cancellationToken in a using so that it can be disposed of whether
            // we successfully connected or failed trying.
            // Otherwise any timeout/cancellation would apply to the full session.
            // In the failure case we need to release the references and dispose of the objects.
            using (cancellationToken.Register(() => tcsConnect.TrySetCanceled())) {
                try {
                    Core.Array subProtocols = null;
                    if (Options.RequestedSubProtocols.Count > 0)
                    {
                        subProtocols = new Core.Array();
                        foreach (var item in Options.RequestedSubProtocols)
                        {
                            subProtocols.Push(item);
                        }
                    }
                    innerWebSocket = new HostObject("WebSocket", uri.ToString(), subProtocols);

                    subProtocols?.Dispose();

                    // Setup the onError callback
                    onError = new Action <JSObject> ((errorEvt) => {
                        errorEvt.Dispose();
                    });

                    // Attach the onError callback
                    innerWebSocket.SetObjectProperty("onerror", onError);

                    // Setup the onClose callback
                    onClose = new Action <JSObject> ((closeEvt) => {
                        innerWebSocketCloseStatus            = (WebSocketCloseStatus)closeEvt.GetObjectProperty("code");
                        innerWebSocketCloseStatusDescription = closeEvt.GetObjectProperty("reason")?.ToString();
                        var mess = new ReceivePayload(WebSocketHelpers.EmptyPayload, WebSocketMessageType.Close);
                        receiveMessageQueue.BufferPayload(mess);

                        if (!tcsConnect.Task.IsCanceled && !tcsConnect.Task.IsCompleted && !tcsConnect.Task.IsFaulted)
                        {
                            tcsConnect.SetException(new WebSocketException(WebSocketError.NativeError));
                        }
                        else
                        {
                            tcsClose?.SetResult(true);
                        }

                        closeEvt.Dispose();
                    });

                    // Attach the onClose callback
                    innerWebSocket.SetObjectProperty("onclose", onClose);

                    // Setup the onOpen callback
                    onOpen = new Action <JSObject> ((evt) => {
                        if (!cancellationToken.IsCancellationRequested)
                        {
                            // Change internal state to 'connected' to enable the other methods
                            if (Interlocked.CompareExchange(ref state, connected, connecting) != connecting)
                            {
                                // Aborted/Disposed during connect.
                                throw new ObjectDisposedException(GetType().FullName);
                            }

                            tcsConnect.SetResult(true);
                        }

                        evt.Dispose();
                    });

                    // Attach the onOpen callback
                    innerWebSocket.SetObjectProperty("onopen", onOpen);

                    // Setup the onMessage callback
                    onMessage = new Action <JSObject> ((messageEvent) => {
                        ThrowIfNotConnected();

                        // get the events "data"
                        var eventData = messageEvent.GetObjectProperty("data");

                        // If the messageEvent's data property is marshalled as a JSObject then we are dealing with
                        // binary data
                        if (eventData is JSObject)
                        {
                            // TODO: Handle ArrayBuffer binary type but have only seen 'blob' so far without
                            // changing the default websocket binary type manually.
                            if (innerWebSocket.GetObjectProperty("binaryType").ToString() == "blob")
                            {
                                Action <JSObject> loadend = null;
                                // Create a new "FileReader" object
                                using (var reader = new HostObject("FileReader")) {
                                    loadend = new Action <JSObject> ((loadEvent) => {
                                        using (var target = (JSObject)loadEvent.GetObjectProperty("target")) {
                                            if ((int)target.GetObjectProperty("readyState") == 2)
                                            {
                                                using (var binResult = (ArrayBuffer)target.GetObjectProperty("result")) {
                                                    var mess = new ReceivePayload(binResult, WebSocketMessageType.Binary);
                                                    receiveMessageQueue.BufferPayload(mess);
                                                    Runtime.FreeObject(loadend);
                                                }
                                            }
                                        }
                                        loadEvent.Dispose();
                                    });

                                    reader.Invoke("addEventListener", "loadend", loadend);

                                    using (var blobData = (JSObject)messageEvent.GetObjectProperty("data"))
                                        reader.Invoke("readAsArrayBuffer", blobData);
                                }
                            }
                            else
                            {
                                throw new NotImplementedException($"WebSocket bynary type '{innerWebSocket.GetObjectProperty ("binaryType").ToString ()}' not supported.");
                            }
                        }
                        else if (eventData is string)
                        {
                            var mess = new ReceivePayload(Encoding.UTF8.GetBytes(((string)eventData).ToString()), WebSocketMessageType.Text);
                            receiveMessageQueue.BufferPayload(mess);
                        }
                        messageEvent.Dispose();
                    });

                    // Attach the onMessage callaback
                    innerWebSocket.SetObjectProperty("onmessage", onMessage);

                    await tcsConnect.Task;
                } catch (Exception wse) {
                    ConnectExceptionCleanup();
                    WebSocketException wex = new WebSocketException("WebSocket connection failure.", wse);
                    throw wex;
                }
            }
        }
예제 #9
0
        private async Task EnsureWebSocketConnectionAsync(CancellationToken cancellationToken)
        {
            if (_webSocket != null)
            {
                return;
            }

            if (Interlocked.CompareExchange(ref _webSocket, new ClientWebSocket(), null) != null)
            {
                return;
            }

            _webSocket.Options.SetRequestHeader("Authorization", $"Bearer {_token}");
            await _webSocket.ConnectAsync(_webSocketBaseUri, cancellationToken).ConfigureAwait(false);

            _webSocketTask = Task.Run(async() =>
            {
                var bufferCapacity = 8192;
                var transferBuffer = new byte[bufferCapacity];
                var messageBuffer  = new MemoryStream(bufferCapacity);
                var messageLength  = 0;
                try
                {
                    while (_webSocket.State == WebSocketState.Open)
                    {
                        var buffer = new ArraySegment <byte>(transferBuffer);
                        var result = await _webSocket.ReceiveAsync(buffer, CancellationToken.None);

                        switch (result.MessageType)
                        {
                        case WebSocketMessageType.Close:
                            await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Ok",
                                                        CancellationToken.None);
                            StreamingClosed?.Invoke(this, EventArgs.Empty);
                            return;

                        case WebSocketMessageType.Text:
                            if (result.EndOfMessage)
                            {
                                StreamingResponse response;

                                // We can use buffer directly if we got a message without chunking
                                // This is almost always the case
                                if (messageLength == 0)
                                {
                                    response = JsonSerializer.Deserialize <StreamingResponse>(
                                        buffer.Array.AsSpan(0, result.Count),
                                        SerializationOptions.Instance);
                                }
                                else
                                {
                                    // ReSharper disable once AssignNullToNotNullAttribute
                                    messageBuffer.Write(buffer.Array, 0, result.Count);
                                    messageLength += result.Count;

                                    response = JsonSerializer.Deserialize <StreamingResponse>(
                                        messageBuffer.GetBuffer().AsSpan(0, messageLength),
                                        SerializationOptions.Instance);

                                    messageBuffer.Position = 0;
                                    messageLength          = 0;
                                }

                                OnStreamingEvent(response);
                            }
                            else
                            {
                                // ReSharper disable once AssignNullToNotNullAttribute
                                messageBuffer.Write(buffer.Array, 0, result.Count);
                                messageLength += result.Count;
                            }


                            break;
                        }
                    }
                }
                catch (WebSocketException e)
                {
                    WebSocketException?.Invoke(this, e);
                }
                finally
                {
                    _webSocket?.Dispose();
                    _webSocket = null;
                }
            });
        }
예제 #10
0
 public void ConstructorTests_Message_Exception_Success()
 {
     const string Message = "Message";
     var inner = new Exception();
     var wse = new WebSocketException(Message, inner);
     Assert.Equal(WebSocketError.Success, wse.WebSocketErrorCode);
     Assert.Equal(Message, wse.Message);
     Assert.Same(inner, wse.InnerException);
 }
예제 #11
0
 public void ConstructorTests_WebSocketError_NativeError_Message_Exception_Success(int nativeError, WebSocketError error, int expectedHResult)
 {
     const string Message = "Message";
     var inner = new Exception();
     var wse = new WebSocketException(error, nativeError, Message, inner);
     Assert.Equal(expectedHResult, wse.HResult);
     Assert.Equal(error, wse.WebSocketErrorCode);
     Assert.Equal(Message, wse.Message);
     Assert.Same(inner, wse.InnerException);
 }
예제 #12
0
 public void ConstructorTests_NativeError_Message_Success(int nativeError, WebSocketError webSocketError)
 {
     const string Message = "Message";
     var wse = new WebSocketException(nativeError, Message);
     Assert.Equal(wse.HResult, nativeError);
     Assert.Equal(wse.WebSocketErrorCode, webSocketError);
     Assert.Equal(wse.Message, Message);
     Assert.Null(wse.InnerException);
 }
예제 #13
0
        private async Task ConnectAsyncCore(Uri uri, CancellationToken cancellationToken)
        {
            HttpWebResponse response = null;
            CancellationTokenRegistration connectCancellation = new CancellationTokenRegistration();

            // Any errors from here on out are fatal and this instance will be disposed.
            try
            {
                HttpWebRequest request = CreateAndConfigureRequest(uri);
                if (Logging.On)
                {
                    Logging.Associate(Logging.WebSockets, this, request);
                }

                connectCancellation = cancellationToken.Register(AbortRequest, request, false);

                response = await request.GetResponseAsync().SuppressContextFlow() as HttpWebResponse;

                Contract.Assert(response != null, "Not an HttpWebResponse");

                if (Logging.On)
                {
                    Logging.Associate(Logging.WebSockets, this, response);
                }

                this.ResponseHeaders = response.Headers;
                string subprotocol = ValidateResponse(request, response);

                innerWebSocket = WebSocket.CreateClientWebSocket(response.GetResponseStream(), subprotocol,
                                                                 options.ReceiveBufferSize, options.SendBufferSize, options.KeepAliveInterval, false,
                                                                 options.GetOrCreateBuffer());

                if (Logging.On)
                {
                    Logging.Associate(Logging.WebSockets, this, innerWebSocket);
                }

                // Change internal state to 'connected' to enable the other methods
                if (Interlocked.CompareExchange(ref state, connected, connecting) != connecting)
                {
                    // Aborted/Disposed during connect.
                    throw new ObjectDisposedException(GetType().FullName);
                }
            }
            catch (WebException ex)
            {
                ConnectExceptionCleanup(response);
                WebSocketException wex = new WebSocketException(SR.GetString(SR.net_webstatus_ConnectFailure), ex);
                if (Logging.On)
                {
                    Logging.Exception(Logging.WebSockets, this, "ConnectAsync", wex);
                }
                throw wex;
            }
            catch (Exception ex)
            {
                ConnectExceptionCleanup(response);
                if (Logging.On)
                {
                    Logging.Exception(Logging.WebSockets, this, "ConnectAsync", ex);
                }
                throw;
            }
            finally
            {
                // We successfully connected (or failed trying), disengage from this token.
                // Otherwise any timeout/cancellation would apply to the full session.
                // In the failure case we need to release the reference to HWR.
                connectCancellation.Dispose();
            }
        }
예제 #14
0
        public void GetObjectData_Success()
        {
            var wse = new WebSocketException();

            wse.GetObjectData(new SerializationInfo(typeof(WebSocketException), new FormatterConverter()), new StreamingContext());
        }
예제 #15
0
        public async Task SendReceive_ConnectionClosedPrematurely_ReceiveAsyncFailsAndWebSocketStateUpdated()
        {
            var options = new LoopbackServer.Options {
                WebSocketEndpoint = true
            };

            Func <ClientWebSocket, LoopbackServer, Uri, Task> connectToServerThatAbortsConnection = async(clientSocket, server, url) =>
            {
                var pendingReceiveAsyncPosted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

                // Start listening for incoming connections on the server side.
                Task acceptTask = server.AcceptConnectionAsync(async connection =>
                {
                    // Complete the WebSocket upgrade. After this is done, the client-side ConnectAsync should complete.
                    Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection));

                    // Wait for client-side ConnectAsync to complete and for a pending ReceiveAsync to be posted.
                    await pendingReceiveAsyncPosted.Task.WaitAsync(TimeSpan.FromMilliseconds(TimeOutMilliseconds));

                    // Close the underlying connection prematurely (without sending a WebSocket Close frame).
                    connection.Socket.Shutdown(SocketShutdown.Both);
                    connection.Socket.Close();
                });

                // Initiate a connection attempt.
                var cts = new CancellationTokenSource(TimeOutMilliseconds);
                await clientSocket.ConnectAsync(url, cts.Token);

                // Post a pending ReceiveAsync before the TCP connection is torn down.
                var  recvBuffer          = new byte[100];
                var  recvSegment         = new ArraySegment <byte>(recvBuffer);
                Task pendingReceiveAsync = ReceiveAsync(clientSocket, recvSegment, cts.Token);
                pendingReceiveAsyncPosted.SetResult();

                // Wait for the server to close the underlying connection.
                await acceptTask.WaitAsync(cts.Token);

                WebSocketException pendingReceiveException = await Assert.ThrowsAsync <WebSocketException>(() => pendingReceiveAsync);

                Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode);

                if (PlatformDetection.IsInAppContainer)
                {
                    const uint WININET_E_CONNECTION_ABORTED = 0x80072EFE;

                    Assert.NotNull(pendingReceiveException.InnerException);
                    Assert.Equal(WININET_E_CONNECTION_ABORTED, (uint)pendingReceiveException.InnerException.HResult);
                }

                WebSocketException newReceiveException =
                    await Assert.ThrowsAsync <WebSocketException>(() => ReceiveAsync(clientSocket, recvSegment, cts.Token));

                Assert.Equal(
                    ResourceHelper.GetExceptionMessage("net_WebSockets_InvalidState", "Aborted", "Open, CloseSent"),
                    newReceiveException.Message);

                Assert.Equal(WebSocketState.Aborted, clientSocket.State);
                Assert.Null(clientSocket.CloseStatus);
            };

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (ClientWebSocket clientSocket = new ClientWebSocket())
                {
                    await connectToServerThatAbortsConnection(clientSocket, server, url);
                }
            }, options);
        }
예제 #16
0
        public WebSocketService(int port, IRouter <T> router, ISessionManager <T> sessions)
        {
            server = new WebSocketServer();

            server.NewMessageReceived += (sock, message) =>
            {
                T session = null;

                try
                {
                    session = Session(sock);
                    if (session != null)
                    {
                        router.Route(message, session);
                    }
                    else
                    {
                        sock.Close();
                    }
                }
                catch (Exception ex)
                {
                    if (session != null)
                    {
                        router.Error(ex, session);
                    }

                    sock.Close();
                }
            };

            server.SessionClosed += (sock, message) =>
            {
                T session = Session(sock);
                if (session != null)
                {
                    sessions.Remove(session);
                    session.Close();
                }
            };

            server.NewSessionConnected += (sock) =>
            {
                var session = sessions.Create(new WebSocketChannel(sock));
                if (session == null)
                {
                    sock.Close();
                }
                else
                {
                    sock.Items[SessionKey] = session;
                }
            };

            if (!server.Setup(new ServerConfig {
                Port = port, MaxConnectionNumber = 100000
            }) || !server.Start())
            {
                WebSocketException.ThrowServerError("Server setup failed. Turn on SuperWebSockets logging for more details.");
            }
        }
        private async Task EnsureWebSocketConnectionAsync()
        {
            if (_webSocket != null)
            {
                return;
            }

            if (Interlocked.CompareExchange(ref _webSocket, new ClientWebSocket(), null) != null)
            {
                return;
            }

            _webSocket.Options.SetRequestHeader("Authorization", $"Bearer {_token}");
            await _webSocket.ConnectAsync(_webSocketBaseUri, CancellationToken.None).ConfigureAwait(false);

            _webSocketTask = Task.Run(async() =>
            {
                var transferBuffer = new byte[8096];
                var messageBuffer  = new List <byte>();
                try
                {
                    while (_webSocket.State == WebSocketState.Open)
                    {
                        var buffer = new ArraySegment <byte>(transferBuffer);
                        var result = await _webSocket.ReceiveAsync(buffer, CancellationToken.None);

                        switch (result.MessageType)
                        {
                        case WebSocketMessageType.Close:
                            await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Ok",
                                                        CancellationToken.None);
                            StreamingClosed?.Invoke(this, EventArgs.Empty);
                            return;

                        case WebSocketMessageType.Text:
                            var receivedBytes = new byte[result.Count];
                            Array.ConstrainedCopy(buffer.Array, 0, receivedBytes, 0, result.Count);
                            messageBuffer.AddRange(receivedBytes);
                            if (result.EndOfMessage)
                            {
                                var data     = Encoding.UTF8.GetString(messageBuffer.ToArray());
                                var response = JsonConvert.DeserializeObject <StreamingResponse>(data);
                                OnStreamingEvent(response);
                                messageBuffer.Clear();
                            }

                            break;
                        }
                    }
                }
                catch (WebSocketException e)
                {
                    WebSocketException?.Invoke(this, e);
                }
                finally
                {
                    _webSocket?.Dispose();
                    _webSocket = null;
                }
            });
        }
예제 #18
0
        public async Task SendReceive_ConnectionClosedPrematurely_ReceiveAsyncFailsAndWebSocketStateUpdated()
        {
            var options = new LoopbackServer.Options {
                WebSocketEndpoint = true
            };

            Func <ClientWebSocket, Socket, Uri, Task> connectToServerThatAbortsConnection = async(clientSocket, server, url) =>
            {
                AutoResetEvent pendingReceiveAsyncPosted = new AutoResetEvent(false);

                // Start listening for incoming connections on the server side.
                Task <List <string> > acceptTask = LoopbackServer.AcceptSocketAsync(server, async(socket, stream, reader, writer) =>
                {
                    // Complete the WebSocket upgrade. After this is done, the client-side ConnectAsync should complete.
                    Assert.True(await LoopbackServer.WebSocketHandshakeAsync(socket, reader, writer));

                    // Wait for client-side ConnectAsync to complete and for a pending ReceiveAsync to be posted.
                    pendingReceiveAsyncPosted.WaitOne(TimeOutMilliseconds);

                    // Close the underlying connection prematurely (without sending a WebSocket Close frame).
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();

                    return(null);
                }, options);

                // Initiate a connection attempt.
                var cts = new CancellationTokenSource(TimeOutMilliseconds);
                await clientSocket.ConnectAsync(url, cts.Token);

                // Post a pending ReceiveAsync before the TCP connection is torn down.
                var  recvBuffer          = new byte[100];
                var  recvSegment         = new ArraySegment <byte>(recvBuffer);
                Task pendingReceiveAsync = clientSocket.ReceiveAsync(recvSegment, cts.Token);
                pendingReceiveAsyncPosted.Set();

                // Wait for the server to close the underlying connection.
                acceptTask.Wait(cts.Token);

                // Validate I/O errors and socket state.
                if (!PlatformDetection.IsWindows)
                {
                    _output.WriteLine("[Non-Windows] ManagedWebSocket-based implementation.");

                    WebSocketException pendingReceiveException = await Assert.ThrowsAsync <WebSocketException>(() => pendingReceiveAsync);

                    Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode);

                    WebSocketException newReceiveException =
                        await Assert.ThrowsAsync <WebSocketException>(() => clientSocket.ReceiveAsync(recvSegment, cts.Token));

                    Assert.Equal(WebSocketError.ConnectionClosedPrematurely, newReceiveException.WebSocketErrorCode);

                    Assert.Equal(WebSocketState.Open, clientSocket.State);
                    Assert.Null(clientSocket.CloseStatus);
                }
                else if (PlatformDetection.IsFullFramework)
                {
                    _output.WriteLine("[Windows] ManagedWebSocket-based implementation.");

                    WebSocketException pendingReceiveException = await Assert.ThrowsAsync <WebSocketException>(() => pendingReceiveAsync);

                    Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode);

                    WebSocketException newReceiveException =
                        await Assert.ThrowsAsync <WebSocketException>(() => clientSocket.ReceiveAsync(recvSegment, cts.Token));

                    Assert.Equal(WebSocketError.Success, newReceiveException.WebSocketErrorCode);
                    Assert.Equal(
                        ResourceHelper.GetExceptionMessage("net_WebSockets_InvalidState", "Aborted", "Open, CloseSent"),
                        newReceiveException.Message);

                    Assert.Equal(WebSocketState.Aborted, clientSocket.State);
                    Assert.Null(clientSocket.CloseStatus);
                }
                else if (PlatformDetection.IsUap)
                {
                    _output.WriteLine("WinRTWebSocket-based implementation.");

                    const uint WININET_E_CONNECTION_ABORTED = 0x80072EFE;

                    WebSocketException pendingReceiveException = await Assert.ThrowsAsync <WebSocketException>(() => pendingReceiveAsync);

                    Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode);
                    Assert.NotNull(pendingReceiveException.InnerException);
                    Assert.Equal(WININET_E_CONNECTION_ABORTED, (uint)pendingReceiveException.InnerException.HResult);

                    WebSocketException newReceiveException =
                        await Assert.ThrowsAsync <WebSocketException>(() => clientSocket.ReceiveAsync(recvSegment, cts.Token));

                    Assert.Equal(WebSocketError.Success, newReceiveException.WebSocketErrorCode);
                    Assert.Equal(
                        ResourceHelper.GetExceptionMessage("net_WebSockets_InvalidState", "Aborted", "Open, CloseSent"),
                        newReceiveException.Message);

                    Assert.Equal(WebSocketState.Aborted, clientSocket.State);
                    Assert.Null(clientSocket.CloseStatus);
                }
                else
                {
                    _output.WriteLine("WinHttpWebSocket-based implementation.");

                    const uint WININET_E_CONNECTION_RESET = 0x80072eff;

                    Win32Exception pendingReceiveException = await Assert.ThrowsAnyAsync <Win32Exception>(() => pendingReceiveAsync);

                    Assert.Equal(WININET_E_CONNECTION_RESET, (uint)pendingReceiveException.HResult);

                    Win32Exception newReceiveException =
                        await Assert.ThrowsAnyAsync <Win32Exception>(() => clientSocket.ReceiveAsync(recvSegment, cts.Token));

                    Assert.Equal(WININET_E_CONNECTION_RESET, (uint)newReceiveException.HResult);

                    Assert.Equal(WebSocketState.Open, clientSocket.State);
                    Assert.Null(clientSocket.CloseStatus);
                }
            };

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (ClientWebSocket clientSocket = new ClientWebSocket())
                {
                    await connectToServerThatAbortsConnection(clientSocket, server, url);
                }
            }, options);
        }
예제 #19
0
 private void WebSocketExceptionHandler(object sender, WebSocketException e)
 {
     _logger.LogError(e, "Web socket error occured");
 }
예제 #20
0
 public void ConstructorTests_WebSocketError_NativeError_Exception_Success(int nativeError, WebSocketError error)
 {
     var inner = new Exception();
     var wse = new WebSocketException(error, nativeError, inner);
     Assert.Equal(wse.HResult, nativeError);
     Assert.Equal(wse.WebSocketErrorCode, error);
     Assert.NotEqual(wse.Message, "");
     Assert.Equal(wse.InnerException, inner);
 }
예제 #21
0
 public void ConstructorTests_Message_Success()
 {
     const string Message = "Message";
     var wse = new WebSocketException(Message);
     Assert.Equal(wse.WebSocketErrorCode, WebSocketError.Success);
     Assert.Equal(wse.Message, Message);
     Assert.Null(wse.InnerException);
 }
예제 #22
0
 private async void OnWebSocketClosed(object sender, EventArgs e)
 {
     Exception ex;
     if (e is ClosedEventArgs)
         ex = new WebSocketException((e as ClosedEventArgs).Code, (e as ClosedEventArgs).Reason);
     else
         ex = new Exception("Connection lost");
     await _taskManager.SignalError(ex).ConfigureAwait(false);
     _waitUntilConnect.Set();
     _waitUntilDisconnect.Set();
 }
예제 #23
0
        private void WaitIncomingData()
        {
            do
            {
                TimeSpan timeout = TimeSpan.Zero;
                try
                {
                    if (this.connectEvent.WaitOne())
                    {
                        using (var webSocket = new ClientWebSocket())
                        {
                            string userName = null;
                            if (this.locker.TryEnterReadLock(timeout: LockTimeout))
                            {
                                userName = this.currentUser?.UserName;
                                this.locker.ExitReadLock();
                            }

                            webSocket.ConnectAsync(uri: new Uri(uriString: Settings.Default.WebSocketUri), cancellationToken: this.cancellationTokenSource.Token).Wait();
                            webSocket.SendAsync(
                                buffer: new ArraySegment <byte>(array: Encoding.UTF8.GetBytes(s: userName ?? string.Empty)),
                                messageType: WebSocketMessageType.Text,
                                endOfMessage: true,
                                cancellationToken: this.cancellationTokenSource.Token);

                            do
                            {
                                try
                                {
                                    if (this.Aborted)
                                    {
                                        this.logger.Write(logMessage: "Reading task is aborted ...");
                                        return;
                                    }

                                    var buffer = new List <byte>();
                                    this.TryReceiveData(webSocket: webSocket, readBytes: buffer);
                                    this.ParseReceivedData(buffer: buffer);
                                }
                                catch (AggregateException exception)
                                {
                                    WebSocketException socketException = exception.InnerExceptions.OfType <WebSocketException>().FirstOrDefault();
                                    if (socketException != null)
                                    {
                                        this.logger.Write(
                                            severity: SeverityLevel.Error,
                                            logMessage: "There are errors on websocket. Close it and recreate a new websocket");

                                        // There are an error. Adds seconds to wait.
                                        timeout = TimeSpan.FromSeconds(value: 30d);
                                        break;
                                    }

                                    if (!this.Aborted)
                                    {
                                        this.logger.WriteException(
                                            exception: exception,
                                            severity: SeverityLevel.Error,
                                            logMessage: "Unexpected error while running reading task");
                                    }
                                }
                                catch (Exception exception)
                                {
                                    if (!this.Aborted)
                                    {
                                        this.logger.WriteException(
                                            exception: exception,
                                            severity: SeverityLevel.Error,
                                            logMessage: "Unexpected error while running reading task");
                                    }
                                }
                            }while (!this.Aborted && !this.cancellationTokenSource.IsCancellationRequested);
                        }
                    }
                }
                catch (Exception exception)
                {
                    if (!this.Aborted)
                    {
                        this.logger.WriteException(
                            exception: exception,
                            severity: SeverityLevel.Error,
                            logMessage: "Unexpected error while openning socket. Retry to open in few time");
                    }

                    // There are an error. Adds seconds to wait.
                    timeout = TimeSpan.FromSeconds(value: 30d);
                }

                this.abortEvent.WaitOne(timeout: timeout);
            }while (!this.Aborted);
        }