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 }); } }
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)); }