public async Task Ping(CancellationToken token)
        {
            var payload    = Guid.NewGuid().ToByteArray();
            var pongSource = new TaskCompletionSource <object>();

            token.Register(() => pongSource.TrySetCanceled());

            EventHandler <ControlFrameEventArgs> completionTrigger = (sender, e) => {
                if ((e.ControlFrame.FrameType == ControlFrame.Type.Pong) &&
                    payload.SequenceEqual(e.ControlFrame.Payload))
                {
                    pongSource.TrySetResult(null);
                }
            };

            OnControlFrame += completionTrigger;

            await WebSocketProtocol.SendControlFrame(OutputStream, new ControlFrame {
                Payload   = payload,
                FrameType = ControlFrame.Type.Ping,
            });

            // either wait until they read it for us
            // or aquire the readlock and read it on our own
            var readLockAcquire = InputStream.ManualAcquire();
            var pongTask        = pongSource.Task;

            if (pongTask == await Task.WhenAny(readLockAcquire.Task, pongTask))
            {
                System.Diagnostics.Debug.WriteLine("nice, they read it for us");
                readLockAcquire.Cancel();
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("welp, our work");
                using (var readLock = await readLockAcquire.Task)
                    await WebSocketProtocol.ReadFrameGroupLockAcquired(readLock, HandleControlFrame, token, false);

                // pls tell me that this was the frame we needed
                if (!pongTask.IsCompleted)
                {
                    throw new InvalidDataException("we pinged and they sent something else. welp.");
                }
            }

            OnControlFrame -= completionTrigger;
        }
        private async Task HandleControlFrame(ControlFrame frame)
        {
            var eventargs         = new ControlFrameEventArgs(frame);
            var controlFrameEvent = OnControlFrame;

            if (controlFrameEvent != null)
            {
                await Task.Factory.FromAsync(controlFrameEvent.BeginInvoke,
                                             controlFrameEvent.EndInvoke, this, eventargs, null);
            }

            if (!eventargs.SuppressAutoResponse && AutoPong && (frame.FrameType == ControlFrame.Type.Ping))
            {
                await WebSocketProtocol.SendControlFrame(OutputStream,
                                                         new ControlFrame { FrameType = ControlFrame.Type.Pong, Payload = frame.Payload });
            }
        }
Beispiel #3
0
 private async Task <bool> CheckEndOfFrame(CancellationToken token)
 {
     System.Diagnostics.Debug.WriteLineIf(FrameOffset >= FrameHeader.PayloadLength, FrameHeader.GroupIsComplete, "WSIS: end of frame, is group complete?");
     if (FrameOffset >= FrameHeader.PayloadLength)
     {
         // end of frame
         if (FrameHeader.GroupIsComplete)
         {
             return(true);
         }
         else
         {
             // read another header and continue with the next group:
             BeginReadingFrame(await WebSocketProtocol.ReadFrameHeader(Underlying, token));
         }
     }
     return(false);
 }
 public Task SendStream(Stream stream)
 {
     return(WebSocketProtocol.SendStream(OutputStream, stream, Masking));
 }
 public Task SendBinaryMessage(byte[] data, int offset, int length)
 {
     return(WebSocketProtocol.SendByteArrayFrame(OutputStream, data, offset, length, Masking));
 }
 public Task SendTextMessage(string message)
 {
     return(WebSocketProtocol.SendTextFrame(OutputStream, message, Masking));
 }
 void IDisposable.Dispose()
 {
     WebSocketProtocol.SendControlFrame(OutputStream, new ControlFrame {
         FrameType = ControlFrame.Type.Close,
     }).Wait();
 }
 public Task <object> ReceiveAnyMessage(CancellationToken token = default(CancellationToken))
 {
     return(WebSocketProtocol.ReadFrameGroup(InputStream, HandleControlFrame, token));
 }