Ejemplo n.º 1
0
 public void State(String socketId, WebSocketState state, String description)
 {
     if (IsEnabled())
     {
         State(socketId, state.ToString(), description ?? String.Empty);
     }
 }
Ejemplo n.º 2
0
 internal static string CheckIfAvailable(
     WebSocketState state,
     bool connecting = false,
     bool open       = true,
     bool closing    = false,
     bool closed     = false)
 {
     return((!connecting && state == WebSocketState.Connecting) ||
            (!open && state == WebSocketState.Open) ||
            (!closing && state == WebSocketState.Closing) ||
            (!closed && state == WebSocketState.Closed)
         ? "This operation isn't available in: " + state.ToString().ToLower()
         : null);
 }
Ejemplo n.º 3
0
        protected override void AbortInternal()
        {
            WebSocketState webSocketState = this.webSocket.State;

            if (!this.socketAborted && webSocketState != WebSocketState.Aborted)
            {
                Events.TransportAborted(this.correlationId);
                this.socketAborted = true;
                this.webSocket.Abort();
                this.webSocket.Dispose();
            }
            else
            {
                Events.TransportAlreadyClosedOrAborted(this.correlationId, webSocketState.ToString());
            }
        }
Ejemplo n.º 4
0
        private async void ClientHandler_ClientStateChanged(object sender, WebSocketState e)
        {
            DialogService.Toast("Client State Changed" + e.ToString());
            if (e == WebSocketState.Open)
            {
                await Task.Delay(2000);

                var res = await SendMessage(new ChatObject(MessageType.Subscribe)
                {
                    Message    = AppService.Token,
                    SenderName = AppService.CurrentUser
                });

                Debug.WriteLine(res);
            }
        }
Ejemplo n.º 5
0
        protected override bool CloseInternal()
        {
            WebSocketState webSocketState = this.webSocket.State;

            if (webSocketState != WebSocketState.Closed && webSocketState != WebSocketState.Aborted)
            {
                Events.TransportClosed(this.correlationId);

                this.CloseInternalAsync(TimeSpan.FromSeconds(30)).ContinueWith(
                    t => { Events.CloseException(this.correlationId, t.Exception); },
                    TaskContinuationOptions.OnlyOnFaulted);
            }
            else
            {
                Events.TransportAlreadyClosedOrAborted(this.correlationId, webSocketState.ToString());
            }

            return(true);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Sends binary <paramref name="data" /> using the WebSocket connection.
        /// </summary>
        /// <param name="data">An array of <see cref="byte" /> that represents the binary data to send.</param>
        /// <param name="opcode">The opcode.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// A task that represents the asynchronous of send
        /// binary data using websocket.
        /// </returns>
        public async Task SendAsync(byte[] data, Opcode opcode, CancellationToken cancellationToken = default)
        {
            if (_readyState != WebSocketState.Open)
            {
                throw new WebSocketException(CloseStatusCode.Normal, $"This operation isn\'t available in: {_readyState.ToString()}");
            }

            using (var stream = new WebSocketStream(data, opcode, Compression))
            {
                foreach (var frame in stream.GetFrames())
                {
                    await Send(frame).ConfigureAwait(false);
                }
            }
        }
 override public string ToString()
 {
     return(Connection.Id + ": " + WebSocketState.ToString());
 }
Ejemplo n.º 8
0
 private static string CheckIfAvailable(WebSocketState state, bool connecting, bool open, bool closing, bool closed)
 {
     return (!connecting && state == WebSocketState.Connecting) ||
            (!open && state == WebSocketState.Open) ||
            (!closing && state == WebSocketState.Closing) ||
            (!closed && state == WebSocketState.Closed)
         ? "This operation isn't available in: " + state.ToString().ToLower()
         : null;
 }
Ejemplo n.º 9
0
            // This task will run until the socket closes or is canceled, then it exits.
            private async Task Send(CancellationToken token)
            {
                bool exit = false;

                while (!exit)
                {
                    switch (_webSocket.State)
                    {
                    case WebSocketState.CloseSent:                              // Probably not allowed to send again after sending Close once.
                    case WebSocketState.Closed:
                    case WebSocketState.Aborted:
                    case WebSocketState.None:
                        exit = true;
                        break;

                    case WebSocketState.CloseReceived:
                        try
                        {
                            await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", token).ConfigureAwait(false);
                        }
                        catch (OperationCanceledException)                                  // not an error, flow control
                        {
                            exit = true;
                        }
                        catch (WebSocketException wse)
                        {
                            exit       = true;
                            _lastError = $"{_displayId} Send: [{_webSocket.State.ToString()}] {wse.Message}";
                            _logger?.Invoke(_lastError, 1);
                        }
                        break;

                    case WebSocketState.Connecting:
                    case WebSocketState.Open:
                    {
                        Tuple <string, byte[], long> msgBytes;

                        //-------------------
                        // Wait until the semaphore says we should wake up.  If it's set, we just run right through.
                        try
                        {
                            // Wait forever for a new message to be added or for the Recv task to tell us to give up due to websocket closure or abort
                            await _releaseSendThread.WaitAsync(token).ConfigureAwait(false);
                        }
                        catch (OperationCanceledException)                                  // not an error, flow control
                        {
                            exit = true;
                        }

                        //-------------------
                        // If there's anything to send, send it.
                        if (_outgoing.TryDequeue(out msgBytes))                                  // keep sending until we run dry, then block
                        {
                            long deltaTicks = (DateTime.UtcNow.Ticks - msgBytes.Item3);
                            _stats_msgQueuedTime += deltaTicks;                                      // this is the total time this message was queued
                            _logger?.Invoke($"{_displayId} msg queue time: {TimeSpan.FromTicks(deltaTicks).TotalSeconds}", 2);

                            try
                            {
                                if (msgBytes.Item2 == null)                                        // is text message
                                {
                                    byte[] rawMsgBytes = System.Text.Encoding.UTF8.GetBytes(msgBytes.Item1);
                                    await _webSocket.SendAsync(new ArraySegment <byte>(rawMsgBytes), WebSocketMessageType.Text, true, token).ConfigureAwait(false);

                                    // keep stats
                                    _stats_sentMsgs++;
                                    _stats_sentBytes += rawMsgBytes.Length;
                                }
                                else
                                {
                                    if (msgBytes.Item2.Equals(sCloseOutputAsync))                                              // we want to close
                                    {
                                        await _webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", token).ConfigureAwait(false);
                                    }
                                    else
                                    {
                                        await _webSocket.SendAsync(new ArraySegment <byte>(msgBytes.Item2), WebSocketMessageType.Binary, true, token).ConfigureAwait(false);

                                        // keep stats
                                        _stats_sentMsgs++;
                                        _stats_sentBytes += msgBytes.Item2.Length;
                                    }
                                }
                            }
                            catch (OperationCanceledException)                                      // not an error, flow control
                            {
                                exit = true;
                            }
                            catch (WebSocketException wse)
                            {
                                exit       = true;
                                _lastError = $"{_displayId} Send: [{_webSocket.State.ToString()}] {wse.Message}";
                                _logger?.Invoke(_lastError, 1);
                            }
                        }
                        break;
                    }
                    }
                }

                //-------------------

                try
                {
                    // Give the connection 5 seconds to close gracefully, then kill it with the token
                    if (await Task.WhenAny(_recvTask, Task.Delay(2000, _cancellationTokenSource.Token)) == _recvTask)
                    {
                        // This waits a second on the off-chance Send exits due to an exception of some sort and Recv keeps running.
                        await _recvTask;                          // make sure recv is exited before we do the disconnect callback.
                    }
                    else
                    {
                        _cancellationTokenSource.Cancel();
                    }
                }
                catch (Exception e)
                {
                    _logger?.Invoke($"Exception shutting down Send thread. {e.Message}", 0);
                }
                finally                  // must make sure we call _onDisconnectCallback, otherwise it's an infinite loop waiting for send threads to tear down
                {
                    _logger?.Invoke("enter the finally", 0);

                    WebSocketState finalState = _webSocket != null ? _webSocket.State : WebSocketState.None;

                    // Let the program know this socket is dead -- note this is on the Send thread, NOT main thread!!!
                    _onDisconnectCallback(this);

                    double totalSeconds = Math.Max(0.1, TimeSpan.FromTicks(DateTime.UtcNow.Ticks - _connectedAtTicks).TotalSeconds);
                    _logger?.Invoke($"{_displayId} ({finalState.ToString()}) SendExit Recv: {_stats_recvMsgs}/{Utilities.BytesToHumanReadable(_stats_recvBytes)}/{Utilities.BytesToHumanReadable((long)(_stats_recvBytes / totalSeconds))}/s Send: {_stats_sentMsgs}/{Utilities.BytesToHumanReadable(_stats_sentBytes)}/{Utilities.BytesToHumanReadable((long)(_stats_sentBytes / totalSeconds))}/s TotalMsgQTime: {TimeSpan.FromTicks(_stats_msgQueuedTime).TotalSeconds}", 0);
                }
            }