public WebSocketHttpServerHandler(OSHttpRequest preq, IHttpClientContext pContext, int bufferlen) : base(preq.HttpMethod, preq.Url.OriginalString) { _request = preq; _networkContext = pContext.GiveMeTheNetworkStreamIKnowWhatImDoing(); _clientContext = pContext; _bufferLength = bufferlen; _buffer = new byte[_bufferLength]; }
public WebSocketHttpServerHandler(OSHttpRequest preq, IHttpClientContext pContext, int bufferlen) : base(preq.HttpMethod, preq.Url.OriginalString) { //preq. _request = preq; pContext.EndWhenDone = false; _networkContext = pContext.GiveMeTheNetworkStreamIKnowWhatImDoing(); _networkContext.Stream.ReadTimeout = _defaultReadTimeout; _clientContext = pContext; _bufferLength = bufferlen; _buffer = new byte[_bufferLength]; }
/// <summary> /// This is our ugly Async OnReceive event handler. /// This chunks the input stream based on the length of the provided buffer and processes out /// as many frames as it can. It then moves the unprocessed data to the beginning of the buffer. /// </summary> /// <param name="ar">Our Async State from beginread</param> private void OnReceive(IAsyncResult ar) { WebSocketState _socketState = ar.AsyncState as WebSocketState; try { int bytesRead = _networkContext.Stream.EndRead(ar); if (bytesRead == 0) { // Do Disconnect _networkContext.Stream.Dispose(); _networkContext = null; return; } _bufferPosition += bytesRead; if (_bufferPosition > _bufferLength) { // Message too big for chunksize.. not sure how this happened... //Close(string.Empty); } int offset = 0; bool headerread = true; int headerforwardposition = 0; while (headerread && offset < bytesRead) { if (_socketState.FrameComplete) { WebsocketFrameHeader pheader = WebsocketFrameHeader.ZeroHeader; headerread = WebSocketReader.TryReadHeader(_buffer, offset, _bufferPosition - offset, out pheader, out headerforwardposition); offset += headerforwardposition; if (headerread) { _socketState.FrameComplete = false; if (pheader.PayloadLen > (ulong)_maxPayloadBytes) { Close("Invalid Payload size"); return; } if (pheader.PayloadLen > 0) { if ((int)pheader.PayloadLen > _bufferPosition - offset) { byte[] writebytes = new byte[_bufferPosition - offset]; Buffer.BlockCopy(_buffer, offset, writebytes, 0, (int)_bufferPosition - offset); _socketState.ExpectedBytes = (int)pheader.PayloadLen; _socketState.ReceivedBytes.AddRange(writebytes); _socketState.Header = pheader; // We need to add the header so that we can unmask it offset += (int)_bufferPosition - offset; } else { byte[] writebytes = new byte[pheader.PayloadLen]; Buffer.BlockCopy(_buffer, offset, writebytes, 0, (int)pheader.PayloadLen); WebSocketReader.Mask(pheader.Mask, writebytes); pheader.IsMasked = false; _socketState.FrameComplete = true; _socketState.ReceivedBytes.AddRange(writebytes); _socketState.Header = pheader; offset += (int)pheader.PayloadLen; } } else { pheader.Mask = 0; _socketState.FrameComplete = true; _socketState.Header = pheader; } if (_socketState.FrameComplete) { ProcessFrame(_socketState); _socketState.Header.SetDefault(); _socketState.ReceivedBytes.Clear(); _socketState.ExpectedBytes = 0; } } } else { WebsocketFrameHeader frameHeader = _socketState.Header; int bytesleft = _socketState.ExpectedBytes - _socketState.ReceivedBytes.Count; if (bytesleft > _bufferPosition) { byte[] writebytes = new byte[_bufferPosition]; Buffer.BlockCopy(_buffer, offset, writebytes, 0, (int)_bufferPosition); _socketState.ReceivedBytes.AddRange(writebytes); _socketState.Header = frameHeader; // We need to add the header so that we can unmask it offset += (int)_bufferPosition; } else { byte[] writebytes = new byte[_bufferPosition]; Buffer.BlockCopy(_buffer, offset, writebytes, 0, (int)_bufferPosition); _socketState.FrameComplete = true; _socketState.ReceivedBytes.AddRange(writebytes); _socketState.Header = frameHeader; offset += (int)_bufferPosition; } if (_socketState.FrameComplete) { ProcessFrame(_socketState); _socketState.Header.SetDefault(); _socketState.ReceivedBytes.Clear(); _socketState.ExpectedBytes = 0; // do some processing } } } if (offset > 0) { // If the buffer is maxed out.. we can just move the cursor. Nothing to move to the beginning. if (offset < _buffer.Length) { Buffer.BlockCopy(_buffer, offset, _buffer, 0, _bufferPosition - offset); } _bufferPosition -= offset; } if (_networkContext.Stream != null && _networkContext.Stream.CanRead && !_closing) { _networkContext.Stream.BeginRead(_buffer, _bufferPosition, _bufferLength - _bufferPosition, OnReceive, _socketState); } else { // We can't read the stream anymore... } } catch (IOException) { Close(string.Empty); } catch (ObjectDisposedException) { Close(string.Empty); } }