Beispiel #1
0
        private Task SendAsync(bool isBinary, byte[] bytes, int offset, int length, CancellationToken cancellationToken)
        {
            var task   = TaskAsyncHelper.Empty;
            var max    = MaxFrameDataLength;
            var opcode = isBinary ? WebSocketOpcode.Binary : WebSocketOpcode.Text;

            while (length > 0)
            {
                var size = Math.Min(length, max);
                length -= size;

                var frame = new WebSocketClientFrame
                {
                    Opcode = opcode,
                    IsFin  = length == 0,
                };
                frame.Payload = new WebSocketPayload(frame, bytes, offset, size);
                offset       += size;
                opcode        = WebSocketOpcode.Continuation;

                task = task.Then(f => SendAsync(f, cancellationToken), frame);
            }
            return(task);
        }
Beispiel #2
0
        private async void ReceiveLoop()
        {
            _cts = new CancellationTokenSource();

            WebSocketMessage currentMessage = null;

            while (!_cts.IsCancellationRequested)
            {
                try
                {
                    var frame = await _webSocket.ReceiveFrameAsync(_cts.Token);

                    if (frame == null)
                    {
                        throw new Exception("null frame");
                        break;
                    }

                    OnFrameReceived(frame);

                    if (frame.Opcode == WebSocketOpcode.Close)
                    {
                        if (Closed != null)
                        {
                            await CloseAsync();
                        }
                        break;
                    }
                    if (frame.IsControlFrame)
                    {
                        // Handle ping frame
                        if (frame.Opcode == WebSocketOpcode.Ping && this.AutoSendPongResponse)
                        {
                            var pongFrame = new WebSocketClientFrame
                            {
                                Opcode  = WebSocketOpcode.Pong,
                                Payload = frame.Payload
                            };
                            await SendAsync(pongFrame, _cts.Token);
                        }
                    }
                    else if (frame.IsDataFrame)
                    {
                        if (currentMessage != null)
                        {
                            throw new WebSocketException(WebSocketErrorCode.CloseInconstistentData);
                        }
                        currentMessage = new WebSocketMessage();
                        currentMessage.AddFrame(frame);
                    }
                    else if (frame.Opcode == WebSocketOpcode.Continuation)
                    {
                        if (currentMessage == null)
                        {
                            throw new WebSocketException(WebSocketErrorCode.CloseInconstistentData);
                        }
                        currentMessage.AddFrame(frame);
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine(String.Format("Other frame received: {0}", frame.Opcode));
                        this.LogDebug("Other frame received: {0}", frame.Opcode);
                    }

                    if (currentMessage != null && currentMessage.IsComplete)
                    {
                        OnMessageReceived(currentMessage);
                        currentMessage = null;
                    }
                }
                catch (WebSocketException wsex)
                {
                    break;
                }
                catch (ObjectDisposedException ex)
                {
                    //https://github.com/rdavisau/sockets-for-pcl/issues/34
                    break;
                }
                catch (TaskCanceledException ex)
                {
                    break;
                }
                catch (Exception ex)
                {
                    this.LogError("An unexpected error occurred.", ex);
                    this.OnError(ex);
                    break;
                }
            }
        }