public PendingSend(TaskCompletionSource<bool> tcs, WebSocketMessageType type, ArraySegment<byte> buffer, CancellationToken cancellationToken) { Type = type; _tcs = tcs; Buffer = buffer; CancellationToken = cancellationToken; }
public virtual Task SendAsync(ArraySegment<byte> message, WebSocketMessageType messageType, bool endOfMessage = true) { if (WebSocket.State != WebSocketState.Open) { return TaskAsyncHelper.Empty; } var sendContext = new SendContext(this, message, messageType, endOfMessage); return _sendQueue.Enqueue(async state => { var context = (SendContext)state; if (context.Handler.WebSocket.State != WebSocketState.Open) { return; } try { await context.Handler.WebSocket.SendAsync(context.Message, context.MessageType, context.EndOfMessage, CancellationToken.None); } catch (Exception ex) { // Swallow exceptions on send Trace.TraceError("Error while sending: " + ex); } }, sendContext); }
internal WebSocketMessageProperty(WebSocketContext context, string subProtocol, WebSocketMessageType incomingMessageType, ReadOnlyDictionary<string, object> properties) { this.context = context; this.subProtocol = subProtocol; this.messageType = incomingMessageType; this.properties = properties; }
public override Task OnMessageReceived(ArraySegment<byte> message, WebSocketMessageType type) { if (this.MessageReceived != null) this.MessageReceived(this, new SocketMessage(this.Id, new UTF8Encoding().GetString(message.Array))); return base.OnMessageReceived(message, type); }
public SendContext(ArraySegment<byte> buffer, bool endOfMessage, WebSocketMessageType type, CancellationToken cancelToken) { this.Buffer = buffer; this.EndOfMessage = endOfMessage; this.Type = type; this.CancelToken = cancelToken; }
private void TestChatHanlder_OnReceive(WebSocket Socket, WebSocketMessageType Type, byte[] ReceiveMessage) { //並行廣播給所有使用者,也可以轉發給指定使用者 Parallel.ForEach(WebSocketList, async socket => { await socket.SendAsync(new ArraySegment<byte>(ReceiveMessage), Type, true, CancellationToken.None); }); }
public WebSocketMessageWriteRfc6455Stream(WebSocketRfc6455 client, WebSocketMessageType messageType, WebSocketExtensionFlags extensionFlags) : this(client, messageType) { ExtensionFlags.Rsv1 = extensionFlags.Rsv1; ExtensionFlags.Rsv2 = extensionFlags.Rsv2; ExtensionFlags.Rsv3 = extensionFlags.Rsv3; }
internal static Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE GetWinHttpMessageType(WebSocketMessageType messageType, bool endOfMessage) { switch (messageType) { case WebSocketMessageType.Binary: if (endOfMessage) { return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE; } else { return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE; } case WebSocketMessageType.Text: if (endOfMessage) { return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE; } else { return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE; } case WebSocketMessageType.Close: return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE; default: Debug.Fail("Unknown WebSocketMessageType."); return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE; } }
public Task SendAsync( ArraySegment<byte> bytes, WebSocketMessageType webSocketMessageType, bool endOfMessage, CancellationToken cancellationToken) { return this.socket.SendAsync(bytes, webSocketMessageType, endOfMessage, cancellationToken); }
public Task SendAsync( ArraySegment<byte> bytes, WebSocketMessageType webSocketMessageType, bool endOfMessage, CancellationToken cancellationToken) { return Task.Run(() => this.socket.Send(new[] { bytes }), cancellationToken); }
public WebSocketReceiveResult (int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string closeStatusDescription) { throw new NotImplementedException (); }
public WebSocketMessageWriteRfc6455Stream(WebSocketRfc6455 webSocket, WebSocketMessageType messageType) { Guard.ParameterCannotBeNull(webSocket, "webSocket"); _internalUsedBufferLength = 0; _messageType = messageType; _webSocket = webSocket; }
public Task SendAsync( ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { return _webSocket.SendAsync(buffer, messageType, endOfMessage, cancellationToken); }
public Task SendAsync( ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { throw new PlatformNotSupportedException(SR.net_WebSockets_UnsupportedPlatform); }
public WebSocketMessageWriteRfc6455Stream(WebSocketRfc6455 webSocket, WebSocketMessageType messageType) { if (webSocket == null) throw new ArgumentNullException("webSocket"); _internalUsedBufferLength = 0; _messageType = messageType; _webSocket = webSocket; }
public void ConstructorTest_Success(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string closeStatusDescription) { var wsrr = new WebSocketReceiveResult(count, messageType, endOfMessage, closeStatus, closeStatusDescription); Assert.Equal(wsrr.Count, count); Assert.Equal(wsrr.MessageType, messageType); Assert.Equal(wsrr.EndOfMessage, endOfMessage); Assert.Equal(wsrr.CloseStatus, closeStatus); Assert.Equal(wsrr.CloseStatusDescription, closeStatusDescription); }
public static int GetOpCode(WebSocketMessageType messageType) { switch (messageType) { case WebSocketMessageType.Text: return Constants.OpCodes.TextFrame; case WebSocketMessageType.Binary: return Constants.OpCodes.BinaryFrame; case WebSocketMessageType.Close: return Constants.OpCodes.CloseFrame; default: throw new NotImplementedException(messageType.ToString()); } }
public override WebSocketMessageWriteStream CreateMessageWriter(WebSocketMessageType messageType) { Connection.BeginWritting(); WebSocketMessageWriteStream writer = new WebSocketMessageWriteRfc6455Stream(this, messageType); foreach (var extension in _extensions) writer = extension.ExtendWriter(writer); return writer; }
private Message CreateMessage(byte[] message, WebSocketMessageType type = WebSocketMessageType.Binary) { Message channelMessage = ByteStreamMessage.CreateMessage(new ArraySegment<byte>(message)); channelMessage.Properties[webSocketMessageProperty] = new WebSocketMessageProperty { MessageType = type }; return channelMessage; }
public WebSocketMessageReadRfc6455Stream(WebSocketRfc6455 webSocket) { Guard.ParameterCannotBeNull(webSocket, "webSocket"); _webSocket = webSocket; _messageType = (WebSocketMessageType)_webSocket.Connection.CurrentHeader.Flags.Option; _flags = GetExtensionFlags(_webSocket.Connection.CurrentHeader.Flags); _hasPendingFrames = !_webSocket.Connection.CurrentHeader.Flags.FIN; if (_webSocket.Connection.CurrentHeader.Flags.Option != WebSocketFrameOption.Binary && _webSocket.Connection.CurrentHeader.Flags.Option != WebSocketFrameOption.Text) throw new WebSocketException("WebSocketMessageReadNetworkStream can only start with a Text or Binary frame, not " + _webSocket.Connection.CurrentHeader.Flags.Option.ToString()); }
/// <summary> /// Initializes a new instance of the <see cref="WebSocketReceiveResult" /> class. /// </summary> /// <param name="count">The count.</param> /// <param name="messageType">Type of the message.</param> /// <param name="endOfMessage">if set to <c>true</c> [end of message].</param> public WebSocketReceiveResult(int count, WebSocketMessageType messageType, bool endOfMessage) { if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } Count = count; EndOfMessage = endOfMessage; MessageType = messageType; }
public Task Send(ArraySegment<byte> data, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancelToken) { var sendContext = new SendContext(data, endOfMessage, messageType, cancelToken); return this.mSendQueue.Enqueue( async s => { await this.mSendAsync(s.Buffer, MessageTypeEnumToOpCode(s.Type), s.EndOfMessage, s.CancelToken); }, sendContext); }
/// <summary> /// Sends data to the client /// </summary> /// <param name="buffer">Data to send</param> /// <param name="endOfMessage">End of the message?</param> /// <param name="type">Message type of the data</param> /// <returns>Task to send the data</returns> public Task SendAsync(ArraySegment<byte> buffer, bool endOfMessage, WebSocketMessageType type) { var sendContext = new SendContext { Buffer = buffer, EndOfMessage = endOfMessage, Type = type }; return mSendQueue.Enqueue( async s => { await mWebSocket.SendAsync(s.Buffer, s.Type, s.EndOfMessage, CancellationToken.None); }, sendContext); }
public WebSocketReceiveResult (int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string closeStatusDescription) { MessageType = messageType; CloseStatus = closeStatus; CloseStatusDescription = closeStatusDescription; Count = count; EndOfMessage = endOfMessage; }
public override WebSocketMessageWriteStream CreateMessageWriter(WebSocketMessageType messageType) { if (!Connection.IsConnected) throw new WebSocketException("The connection is closed"); Connection.BeginWritting(); WebSocketMessageWriteStream writer = new WebSocketMessageWriteRfc6455Stream(this, messageType); foreach (var extension in _extensions) writer = extension.ExtendWriter(writer); return writer; }
public override Task OnMessageReceived(ArraySegment<byte> message, WebSocketMessageType type) { if (message.Count > 0) { var bytes = new UTF8Encoding(true).GetString(message.Array, 0, message.Count); var streamEvent = JsonConvert.DeserializeObject<ProcessStreamEvent>(bytes); if (streamEvent.MessageType == "run" && streamEvent.ApiProcessSpec != null) { runService.Run(this, streamEvent.ApiProcessSpec); } } return Task.Delay(0); }
public WebSocketReceiveResult(int count, WebSocketMessageType messageType, bool endOfMessage, Nullable<WebSocketCloseStatus> closeStatus, string closeStatusDescription) { if (count < 0) { throw new ArgumentOutOfRangeException("count"); } this.Count = count; this.EndOfMessage = endOfMessage; this.MessageType = messageType; this.CloseStatus = closeStatus; this.CloseStatusDescription = closeStatusDescription; }
internal Task SendAsync(byte[] message, WebSocketMessageType messageType) { if (_isClosed) { return TaskAsyncHelper.Empty; } return _sendQueue.Enqueue(() => { if (_isClosed) { return TaskAsyncHelper.Empty; } return WebSocket.SendAsync(new ArraySegment<byte>(message), messageType, true /* endOfMessage */, CancellationToken.None); }); }
public WebSocketReceiveResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string closeStatusDescription) { if (count < 0) { throw new ArgumentOutOfRangeException("count"); } Count = count; EndOfMessage = endOfMessage; MessageType = messageType; CloseStatus = closeStatus; CloseStatusDescription = closeStatusDescription; }
public static async Task TestEcho( Uri server, WebSocketMessageType type, int timeOutMilliseconds, ITestOutputHelper output) { var cts = new CancellationTokenSource(timeOutMilliseconds); string message = "Hello WebSockets!"; string closeMessage = "Good bye!"; var receiveBuffer = new byte[100]; var receiveSegment = new ArraySegment<byte>(receiveBuffer); using (ClientWebSocket cws = await GetConnectedWebSocket(server, timeOutMilliseconds, output)) { output.WriteLine("TestEcho: SendAsync starting."); await cws.SendAsync(WebSocketData.GetBufferFromText(message), type, true, cts.Token); output.WriteLine("TestEcho: SendAsync done."); Assert.Equal(WebSocketState.Open, cws.State); output.WriteLine("TestEcho: ReceiveAsync starting."); WebSocketReceiveResult recvRet = await cws.ReceiveAsync(receiveSegment, cts.Token); output.WriteLine("TestEcho: ReceiveAsync done."); Assert.Equal(WebSocketState.Open, cws.State); Assert.Equal(message.Length, recvRet.Count); Assert.Equal(type, recvRet.MessageType); Assert.Equal(true, recvRet.EndOfMessage); Assert.Equal(null, recvRet.CloseStatus); Assert.Equal(null, recvRet.CloseStatusDescription); var recvSegment = new ArraySegment<byte>(receiveSegment.Array, receiveSegment.Offset, recvRet.Count); Assert.Equal(message, WebSocketData.GetTextFromBuffer(recvSegment)); output.WriteLine("TestEcho: CloseAsync starting."); Task taskClose = cws.CloseAsync(WebSocketCloseStatus.NormalClosure, closeMessage, cts.Token); Assert.True( (cws.State == WebSocketState.Open) || (cws.State == WebSocketState.CloseSent) || (cws.State == WebSocketState.CloseReceived) || (cws.State == WebSocketState.Closed), "State immediately after CloseAsync : " + cws.State); await taskClose; output.WriteLine("TestEcho: CloseAsync done."); Assert.Equal(WebSocketState.Closed, cws.State); Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus); Assert.Equal(closeMessage, cws.CloseStatusDescription); } }
private async Task <bool> MessageWriteAsync(ClientMetadata client, byte[] data, WebSocketMessageType messageType) { try { #region Send-Message // Cannot have two simultaneous SendAsync calls so use a // semaphore to block the second until the first has completed await client.SendAsyncLock.WaitAsync(client.KillToken.Token); try { await client.Ws.SendAsync(new ArraySegment <byte>(data, 0, data.Length), messageType, true, client.KillToken.Token); } finally { client.SendAsyncLock.Release(); } return(true); #endregion } catch (Exception e) { Log("*** MessageWriteAsync " + client.IpPort() + " disconnected due to exception " + e); return(false); } }
private void _startReceiveTask() { Task.Run(async() => { var token = _wsTokenSource.Token; // If cancelled, disconnect and get out if (token.IsCancellationRequested) { await Disconnect(); } else { while (_ws.State == WebSocketState.Open) { var buffer = new byte[1024]; var bytes = new List <byte>(); var str = ""; // First read all the message bytes WebSocketMessageType messageType = WebSocketMessageType.Close; bool endOfMessage = false; do { try { var result = await _ws.ReceiveAsync(new ArraySegment <byte>(buffer), token); if (result != null) { endOfMessage = result.EndOfMessage; var newBytes = new byte[result.Count]; Array.Copy(buffer, newBytes, result.Count); bytes.AddRange(newBytes); messageType = result.MessageType; } } catch (Exception e) { Logger.Error(e, "Exception processing message from web socket."); endOfMessage = true; } } while (!endOfMessage && _ws.State == WebSocketState.Open); // Now process the message switch (messageType) { case WebSocketMessageType.Close: await Disconnect(); break; case WebSocketMessageType.Text: str += Encoding.UTF8.GetString(buffer).TrimEnd('\0'); EmitMessage(new MessageEvent(str)); break; case WebSocketMessageType.Binary: EmitBinaryMessage(new BinaryMessageEvent(bytes.ToArray())); break; default: throw new ArgumentOutOfRangeException(); } } } return(Task.CompletedTask); }, _wsTokenSource.Token); }
public WebSocketMessageProperty() { this.messageType = WebSocketDefaults.DefaultWebSocketMessageType; }
public WebSocketReceiveResult Receive() { try { // we may receive control frames so reading needs to happen in an infinite loop while (true) { // allow this operation to be cancelled from iniside OR outside this instance WebSocketFrame frame = null; try { frame = WebSocketFrameReader.Read(_stream, _receiveBuffer); _logger("websocket.ReceivedFrame: " + frame.OpCode + ", " + frame.IsFinBitSet + ", " + frame.Count); } catch (InternalBufferOverflowException ex) { CloseOutputAutoTimeout(WebSocketCloseStatus.MessageTooBig, "Frame too large to fit in buffer. Use message fragmentation", ex); throw; } catch (ArgumentOutOfRangeException ex) { CloseOutputAutoTimeout(WebSocketCloseStatus.ProtocolError, "Payload length out of range", ex); throw; } catch (EndOfStreamException ex) { CloseOutputAutoTimeout(WebSocketCloseStatus.InvalidPayloadData, "Unexpected end of stream encountered", ex); throw; } catch (OperationCanceledException ex) { CloseOutputAutoTimeout(WebSocketCloseStatus.EndpointUnavailable, "Operation cancelled", ex); throw; } catch (Exception ex) { CloseOutputAutoTimeout(WebSocketCloseStatus.InternalServerError, "Error reading WebSocket frame", ex); throw; } switch (frame.OpCode) { case WebSocketOpCode.ConnectionClose: return(RespondToCloseFrame(frame, _receiveBuffer)); case WebSocketOpCode.Ping: ArraySegment <byte> pingPayload = new ArraySegment <byte>(_receiveBuffer.Array, _receiveBuffer.Offset, frame.Count); SendPong(pingPayload); break; case WebSocketOpCode.Pong: ArraySegment <byte> pongBuffer = new ArraySegment <byte>(_receiveBuffer.Array, frame.Count, _receiveBuffer.Offset); if (pongBuffer.Array.SequenceEqual(_pingPayload)) { } LastPingPong = DateTime.UtcNow; NeedsPing = true; break; case WebSocketOpCode.TextFrame: if (!frame.IsFinBitSet) { // continuation frames will follow, record the message type Text _continuationFrameMessageType = WebSocketMessageType.Text; } return(new WebSocketReceiveResult(frame.Count, WebSocketMessageType.Text, frame.IsFinBitSet, _receiveBuffer)); case WebSocketOpCode.BinaryFrame: if (!frame.IsFinBitSet) { // continuation frames will follow, record the message type Binary _continuationFrameMessageType = WebSocketMessageType.Binary; } return(new WebSocketReceiveResult(frame.Count, WebSocketMessageType.Binary, frame.IsFinBitSet, _receiveBuffer)); case WebSocketOpCode.ContinuationFrame: return(new WebSocketReceiveResult(frame.Count, _continuationFrameMessageType, frame.IsFinBitSet, _receiveBuffer)); default: Exception ex = new NotSupportedException($"Unknown WebSocket opcode {frame.OpCode}"); CloseOutputAutoTimeout(WebSocketCloseStatus.ProtocolError, ex.Message, ex); throw ex; } } } catch (Exception catchAll) { // Most exceptions will be caught closer to their source to send an appropriate close message (and set the WebSocketState) // However, if an unhandled exception is encountered and a close message not sent then send one here if (_state == WebSocketState.Open) { CloseOutputAutoTimeout(WebSocketCloseStatus.InternalServerError, "Unexpected error reading from WebSocket", catchAll); } throw; } }
public WebSocketMessage(object data, WebSocketMessageType messageType) { Data = data; MessageType = messageType; }
public WebSocketResponseEventArgs(WebSocketMessageType type, byte[] data) { MessageType = type; Data = data; }
static byte[] PrepareWebSocketHeader(int bufferLength, WebSocketMessageType webSocketMessageType) { byte[] octet; if (bufferLength < MediumSizeFrame) { // Handle small payloads and control frames octet = new byte[6]; // Octet0 octet[0] = PrepareOctet0(webSocketMessageType); // Octet 1 octet[1] = (byte)(bufferLength | Mask); // Octets 2-5 (Masking Key) octet[2] = maskingKey[0]; octet[3] = maskingKey[1]; octet[4] = maskingKey[2]; octet[5] = maskingKey[3]; } else if (bufferLength <= UInt16.MaxValue) { // Handle medium payloads octet = new byte[8]; // Octet 0 octet[0] = PrepareOctet0(webSocketMessageType); // Octet 1 octet[1] = MediumSizeFrame | Mask; // Octet 2-3 Payload Length octet[2] = (byte)((bufferLength >> 8) & 0x00FF); octet[3] = (byte)(bufferLength & 0x00FF); // Octets 4-7 (Masking Key) octet[4] = maskingKey[0]; octet[5] = maskingKey[1]; octet[6] = maskingKey[2]; octet[7] = maskingKey[3]; } else { // Handle large payloads octet = new byte[14]; // Octet 0 octet[0] = PrepareOctet0(webSocketMessageType); // Octet 1 octet[1] = LargeSizeFrame | Mask; // Octet 2-9 Payload Length // ignore anything larger than a 32-bit number // octet[2] = octet[3] = octet[4] = octet[5] = 0; These are already set to 0 octet[6] = (byte)((bufferLength >> 24) & 0x00FF); octet[7] = (byte)((bufferLength >> 16) & 0x00FF); octet[8] = (byte)((bufferLength >> 8) & 0x00FF); octet[9] = (byte)(bufferLength & 0x00FF); // Octets 10-13 (Masking Key) octet[10] = maskingKey[0]; octet[11] = maskingKey[1]; octet[12] = maskingKey[2]; octet[13] = maskingKey[3]; } return(octet); }
public static void MessageReceived(ILogger logger, WebSocketMessageType type, int size, bool endOfMessage) { _messageReceived(logger, type, size, endOfMessage, null); }
public Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken token) { return(mSocket.SendAsync(buffer, messageType, endOfMessage, token)); }
public override Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { throw new NotImplementedException(); }
protected override Task SendAsync(WebSocket ws, ArraySegment <byte> arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) => ws.SendAsync(arraySegment, messageType, endOfMessage, cancellationToken);
public virtual ValueTask SendAsync(ReadOnlyMemory <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) => MemoryMarshal.TryGetArray(buffer, out ArraySegment <byte> arraySegment) ? new ValueTask(SendAsync(arraySegment, messageType, endOfMessage, cancellationToken)) : SendWithArrayPoolAsync(buffer, messageType, endOfMessage, cancellationToken);
public abstract Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken);
public async Task SendAsync_InvalidMessageType_ThrowsArgumentNullException(WebSocketMessageType messageType) { HttpListenerWebSocketContext context = await GetWebSocketContext(); await AssertExtensions.ThrowsAsync <ArgumentException>("messageType", () => context.WebSocket.SendAsync(new ArraySegment <byte>(), messageType, false, new CancellationToken())); }
internal static async Task SendAsync(this WebSocket webSocket, byte[] buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) => await webSocket.SendAsync(new ArraySegment <byte>(buffer), messageType, endOfMessage, cancellationToken).ConfigureAwait(false);
public override Task <WebSocketReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken) { EnsureWebSocketConnected(); ValidateArraySegment(buffer); return(Task.Run(() => { EnsureWebSocketState(WebSocketState.Open, WebSocketState.CloseSent); bool isLast; long length; if (remaining == 0) { // First read the two first bytes to know what we are doing next connection.Read(req, headerBuffer, 0, 2); isLast = (headerBuffer[0] >> 7) > 0; var isMasked = (headerBuffer[1] >> 7) > 0; int mask = 0; currentMessageType = WireToMessageType((byte)(headerBuffer[0] & 0xF)); length = headerBuffer[1] & 0x7F; int offset = 0; if (length == 126) { offset = 2; connection.Read(req, headerBuffer, 2, offset); length = (headerBuffer[2] << 8) | headerBuffer[3]; } else if (length == 127) { offset = 8; connection.Read(req, headerBuffer, 2, offset); length = 0; for (int i = 2; i <= 9; i++) { length = (length << 8) | headerBuffer[i]; } } if (isMasked) { connection.Read(req, headerBuffer, 2 + offset, 4); for (int i = 0; i < 4; i++) { var pos = i + offset + 2; mask = (mask << 8) | headerBuffer[pos]; } } } else { isLast = (headerBuffer[0] >> 7) > 0; currentMessageType = WireToMessageType((byte)(headerBuffer[0] & 0xF)); length = remaining; } if (currentMessageType == WebSocketMessageType.Close) { state = WebSocketState.Closed; var tmpBuffer = new byte[length]; connection.Read(req, tmpBuffer, 0, tmpBuffer.Length); var closeStatus = (WebSocketCloseStatus)(tmpBuffer[0] << 8 | tmpBuffer[1]); var closeDesc = tmpBuffer.Length > 2 ? Encoding.UTF8.GetString(tmpBuffer, 2, tmpBuffer.Length - 2) : string.Empty; return new WebSocketReceiveResult((int)length, currentMessageType, isLast, closeStatus, closeDesc); } else { var readLength = (int)(buffer.Count < length ? buffer.Count : length); connection.Read(req, buffer.Array, buffer.Offset, readLength); remaining = length - readLength; return new WebSocketReceiveResult((int)readLength, currentMessageType, isLast && remaining == 0); } })); }
/// <summary> /// Receive web socket result /// </summary> /// <param name="buffer">The buffer to copy data into</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>The web socket result details</returns> public override async Task <WebSocketReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken) { try { // we may receive control frames so reading needs to happen in an infinite loop while (true) { // allow this operation to be cancelled from iniside OR outside this instance using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_internalReadCts.Token, cancellationToken)) { WebSocketFrame frame = null; try { frame = await WebSocketFrameReader.ReadAsync(_stream, buffer, linkedCts.Token); Events.Log.ReceivedFrame(_guid, frame.OpCode, frame.IsFinBitSet, frame.Count); } catch (InternalBufferOverflowException ex) { await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.MessageTooBig, "Frame too large to fit in buffer. Use message fragmentation", ex); throw; } catch (ArgumentOutOfRangeException ex) { await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.ProtocolError, "Payload length out of range", ex); throw; } catch (EndOfStreamException ex) { await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.InvalidPayloadData, "Unexpected end of stream encountered", ex); throw; } catch (OperationCanceledException ex) { await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.EndpointUnavailable, "Operation cancelled", ex); throw; } catch (Exception ex) { await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.InternalServerError, "Error reading WebSocket frame", ex); throw; } switch (frame.OpCode) { case WebSocketOpCode.ConnectionClose: return(await RespondToCloseFrame(frame, buffer, linkedCts.Token)); case WebSocketOpCode.Ping: ArraySegment <byte> pingPayload = new ArraySegment <byte>(buffer.Array, buffer.Offset, frame.Count); await SendPongAsync(pingPayload, linkedCts.Token); break; case WebSocketOpCode.Pong: ArraySegment <byte> pongBuffer = new ArraySegment <byte>(buffer.Array, frame.Count, buffer.Offset); Pong?.Invoke(this, new PongEventArgs(pongBuffer)); break; case WebSocketOpCode.TextFrame: if (!frame.IsFinBitSet) { // continuation frames will follow, record the message type Text _continuationFrameMessageType = WebSocketMessageType.Text; } return(new WebSocketReceiveResult(frame.Count, WebSocketMessageType.Text, frame.IsFinBitSet)); case WebSocketOpCode.BinaryFrame: if (!frame.IsFinBitSet) { // continuation frames will follow, record the message type Binary _continuationFrameMessageType = WebSocketMessageType.Binary; } return(new WebSocketReceiveResult(frame.Count, WebSocketMessageType.Binary, frame.IsFinBitSet)); case WebSocketOpCode.ContinuationFrame: return(new WebSocketReceiveResult(frame.Count, _continuationFrameMessageType, frame.IsFinBitSet)); default: Exception ex = new NotSupportedException($"Unknown WebSocket opcode {frame.OpCode}"); await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.ProtocolError, ex.Message, ex); throw ex; } } } } catch (Exception catchAll) { // Most exceptions will be caught closer to their source to send an appropriate close message (and set the WebSocketState) // However, if an unhandled exception is encountered and a close message not sent then send one here if (_state == WebSocketState.Open) { await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.InternalServerError, "Unexpected error reading from WebSocket", catchAll); } throw; } }
public override Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { return(_sendAsync(buffer, EnumToOpCode(messageType), endOfMessage, cancellationToken)); }
public Task Send(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken?cancellationToken = null) => _w?.SendAsync(buffer, messageType, endOfMessage, cancellationToken ?? CancellationToken.None) ?? throw new ObjectDisposedException(nameof(_w));
public Task SendAsync(ArraySegment <byte> data, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancel) { return(mSendAsync(data, ConvertMessageTypeToInt(messageType), endOfMessage, cancel)); }
public virtual ValueTask SendAsync(ReadOnlyMemory <byte> buffer, WebSocketMessageType messageType, WebSocketMessageFlags messageFlags, CancellationToken cancellationToken = default) { return(SendAsync(buffer, messageType, messageFlags.HasFlag(WebSocketMessageFlags.EndOfMessage), cancellationToken)); }
internal WebSocketMessageProperty(WebSocketContext context, string subProtocol, WebSocketMessageType incomingMessageType, ReadOnlyDictionary <string, object> properties) { WebSocketContext = context; SubProtocol = subProtocol; MessageType = incomingMessageType; this.properties = properties; }
/// <summary> /// Sends the async. /// </summary> /// <param name="bytes">The bytes.</param> /// <param name="type">The type.</param> /// <param name="endOfMessage">if set to <c>true</c> [end of message].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken) { UserContext.Send(bytes); return(_cachedTask); }
public ValueWebSocketReceiveResult GetResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus?closeStatus, string?closeDescription) => new ValueWebSocketReceiveResult(count, messageType, endOfMessage); // closeStatus/closeDescription are ignored
public static async Task <WebSocketMessage> ReadMessageAsync(WebSocket webSocket, int bufferSize, int?maxMessageSize, CancellationToken disconnectToken) { WebSocketMessage message; // Read the first time with an empty array WebSocketReceiveResult receiveResult = await webSocket.ReceiveAsync(_emptyArraySegment, disconnectToken).PreserveCultureNotContext(); if (TryGetMessage(receiveResult, null, out message)) { return(message); } var buffer = new byte[bufferSize]; // Now read with the real buffer var arraySegment = new ArraySegment <byte>(buffer); receiveResult = await webSocket.ReceiveAsync(arraySegment, disconnectToken).PreserveCultureNotContext(); if (TryGetMessage(receiveResult, buffer, out message)) { return(message); } else { // for multi-fragment messages, we need to coalesce ByteBuffer bytebuffer = new ByteBuffer(maxMessageSize); bytebuffer.Append(BufferSliceToByteArray(buffer, receiveResult.Count)); WebSocketMessageType originalMessageType = receiveResult.MessageType; while (true) { // loop until an error occurs or we see EOF receiveResult = await webSocket.ReceiveAsync(arraySegment, disconnectToken).PreserveCultureNotContext(); if (receiveResult.MessageType == WebSocketMessageType.Close) { return(WebSocketMessage.CloseMessage); } if (receiveResult.MessageType != originalMessageType) { throw new InvalidOperationException("Incorrect message type"); } bytebuffer.Append(BufferSliceToByteArray(buffer, receiveResult.Count)); if (receiveResult.EndOfMessage) { switch (receiveResult.MessageType) { case WebSocketMessageType.Binary: return(new WebSocketMessage(bytebuffer.GetByteArray(), WebSocketMessageType.Binary)); case WebSocketMessageType.Text: return(new WebSocketMessage(bytebuffer.GetString(), WebSocketMessageType.Text)); default: throw new InvalidOperationException("Unknown message type"); } } } } }
public override ValueTask SendAsync(ReadOnlyMemory <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { return(SendPrivateAsync(buffer, messageType, endOfMessage, cancellationToken)); }
public abstract WebSocketMessageWriteStream CreateMessageWriter(WebSocketMessageType messageType);
private async Task <bool> MessageWriteAsync(byte[] data, WebSocketMessageType msgType, CancellationToken token) { bool disconnectDetected = false; using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_Token, token)) { try { if (_ClientWs == null || _ClientWs.State != WebSocketState.Open) { Logger?.Invoke(_Header + "not connected"); disconnectDetected = true; return(false); } await _SendLock.WaitAsync(_Token); try { await _ClientWs.SendAsync(new ArraySegment <byte>(data, 0, data.Length), msgType, true, token); } finally { _SendLock.Release(); } _Stats.IncrementSentMessages(); _Stats.AddSentBytes(data.Length); return(true); } catch (TaskCanceledException) { if (_Token.IsCancellationRequested) { Logger?.Invoke(_Header + "canceled"); disconnectDetected = true; } else if (token.IsCancellationRequested) { Logger?.Invoke(_Header + "message send canceled"); } return(false); } catch (OperationCanceledException) { if (_Token.IsCancellationRequested) { Logger?.Invoke(_Header + "canceled"); disconnectDetected = true; } else if (token.IsCancellationRequested) { Logger?.Invoke(_Header + "message send canceled"); } return(false); } catch (WebSocketException) { Logger?.Invoke(_Header + "websocket disconnected"); disconnectDetected = true; return(false); } catch (ObjectDisposedException) { Logger?.Invoke(_Header + "disposed"); disconnectDetected = true; return(false); } catch (SocketException) { Logger?.Invoke(_Header + "socket disconnected"); disconnectDetected = true; return(false); } catch (InvalidOperationException) { Logger?.Invoke(_Header + "disconnected due to invalid operation"); disconnectDetected = true; return(false); } catch (IOException) { Logger?.Invoke(_Header + "IO disconnected"); disconnectDetected = true; return(false); } catch (Exception e) { Logger?.Invoke(_Header + "exception: " + Environment.NewLine + e.ToString()); disconnectDetected = true; return(false); } finally { if (disconnectDetected) { Dispose(); ServerDisconnected?.Invoke(this, EventArgs.Empty); } } } }
protected abstract Task SendAsync(WebSocket ws, ArraySegment <byte> arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken);
public override Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { ThrowIfNotConnected(); return(_innerWebSocket.SendAsync(buffer, messageType, endOfMessage, cancellationToken)); }