Beispiel #1
0
        /// <summary>
        /// Reads the complete next text message from the websocket
        /// </summary>
        /// <returns>The text message, or null if socket was closed</returns>
        private async Task <string> ReceiveNextMessageAsync(IClientWebSocketProxy ws)
        {
            _receiveStream.Position = 0;
            WebSocketReceiveResult result;

            do
            {
                result = await ws.ReceiveAsync(new ArraySegment <byte>(_readBuffer), _cancellationToken.Token);

                if (result == null || result.Count == 0 || result.MessageType == WebSocketMessageType.Close)
                {
                    return(null);
                }
                if (ws.CloseStatus.HasValue)
                {
                    return(null);
                }
                Debug.Assert(result.MessageType == WebSocketMessageType.Text);
                if (result.EndOfMessage && _receiveStream.Position == 0)
                {
                    return(Encoding.UTF8.GetString(_readBuffer, 0, result.Count));                    // No need to use memory stream
                }
                _receiveStream.Write(_readBuffer, 0, result.Count);
            }while (!result.EndOfMessage);

            return(Encoding.UTF8.GetString(_receiveStream.GetBuffer(), 0, (int)_receiveStream.Position));
        }
Beispiel #2
0
        /// <summary>
        /// Try connecting to the specified websocket url once.
        /// If the connection is successful, it will complete the function and you don't have to worry
        /// about reconnects
        /// </summary>
        public async Task <bool> TryConnectAsync(Func <string> resolveUrl, string accessToken, Func <Task> postConnectFunc)
        {
            if (resolveUrl == null)
            {
                throw new ArgumentNullException(nameof(resolveUrl));
            }
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(JsonRpcWebSocket));
            }

            // Local function that will try to reconnect forever
            async Task reconnect()
            {
                while (true)
                {
                    // Connection lost, wait a little and try again
                    await Task.Delay(GetReconnectDelay(), _cancellationToken.Token);

                    await connect();

                    if (_ws != null)
                    {
                        return;
                    }
                }
            }

            // Local function used for connect and re-connects
            async Task connect()
            {
                _ws = null;
                var url = resolveUrl();

                try
                {
                    var ws = CreateWebSocket(accessToken);

                    // Connect the websocket
                    _logger.LogInformation("Connecting to {0}", url);
                    await ws.ConnectAsync(new Uri(url), _cancellationToken.Token).OrTimeout(CONNECT_TIMEOUT);

                    _logger.LogInformation("Connected to {0}", url);
                    _ws = ws;

                    await EatWelcomeMessageAsync().OrTimeout(10000);

                    // start receiving data
                    _receiverTask = Task.Factory.StartNew(() => ReceiverTask(reconnect), TaskCreationOptions.LongRunning);

                    if (postConnectFunc != null)
                    {
                        await postConnectFunc();
                    }
                }
                catch (Exception e)
                {
                    _ws = null;
                    _logger.LogWarning("Connection to '{0}' failed: {1}", url, e.Message);
                }
            }

            // Do the first time connect
            await connect();

            return(_ws != null);
        }