/// <summary> /// Clear WebSocket send/receive buffers /// </summary> public void ClearWsBuffers() { lock (WsReceiveLock) { WsReceived = false; WsHeaderSize = 0; WsPayloadSize = 0; WsReceiveBuffer.Clear(); Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length); } lock (WsSendLock) { WsSendBuffer.Clear(); Array.Clear(WsSendMask, 0, WsSendMask.Length); } }
/// <summary> /// Prepare WebSocket send frame /// </summary> /// <param name="buffer">Buffer to send</param> /// <param name="offset">Buffer offset</param> /// <param name="size">Buffer size</param> public void PrepareReceiveFrame(byte[] buffer, long offset, long size) { lock (WsReceiveLock) { var index = 0; // Clear received data after WebSocket frame was processed if (WsReceived) { WsReceived = false; WsHeaderSize = 0; WsPayloadSize = 0; WsReceiveBuffer.Clear(); Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length); } while (size > 0) { // Clear received data after WebSocket frame was processed if (WsReceived) { WsReceived = false; WsHeaderSize = 0; WsPayloadSize = 0; WsReceiveBuffer.Clear(); Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length); } // Prepare WebSocket frame opcode and mask flag if (WsReceiveBuffer.Count < 2) { for (int i = 0; i < 2; ++i, ++index, --size) { if (size == 0) { return; } WsReceiveBuffer.Add(buffer[offset + index]); } } byte opcode = (byte)(WsReceiveBuffer[0] & 0x0F); bool fin = ((WsReceiveBuffer[0] >> 7) & 0x01) != 0; bool mask = ((WsReceiveBuffer[1] >> 7) & 0x01) != 0; int payload = WsReceiveBuffer[1] & (~0x80); // Prepare WebSocket frame size if (payload <= 125) { WsHeaderSize = 2 + (mask ? 4 : 0); WsPayloadSize = payload; WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize; } else if (payload == 126) { if (WsReceiveBuffer.Count < 4) { for (int i = 0; i < 2; ++i, ++index, --size) { if (size == 0) { return; } WsReceiveBuffer.Add(buffer[offset + index]); } } payload = ((WsReceiveBuffer[2] << 8) | (WsReceiveBuffer[3] << 0)); WsHeaderSize = 4 + (mask ? 4 : 0); WsPayloadSize = payload; WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize; } else if (payload == 127) { if (WsReceiveBuffer.Count < 10) { for (int i = 0; i < 8; ++i, ++index, --size) { if (size == 0) { return; } WsReceiveBuffer.Add(buffer[offset + index]); } } payload = ((WsReceiveBuffer[2] << 56) | (WsReceiveBuffer[3] << 48) | (WsReceiveBuffer[4] << 40) | (WsReceiveBuffer[5] << 32) | (WsReceiveBuffer[6] << 24) | (WsReceiveBuffer[7] << 16) | (WsReceiveBuffer[8] << 8) | (WsReceiveBuffer[9] << 0)); WsHeaderSize = 10 + (mask ? 4 : 0); WsPayloadSize = payload; WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize; } // Prepare WebSocket frame mask if (mask) { if (WsReceiveBuffer.Count < WsHeaderSize) { for (int i = 0; i < 4; ++i, ++index, --size) { if (size == 0) { return; } WsReceiveBuffer.Add(buffer[offset + index]); WsReceiveMask[i] = buffer[offset + index]; } } } int total = WsHeaderSize + WsPayloadSize; int length = Math.Min(total - WsReceiveBuffer.Count, (int)size); // Prepare WebSocket frame payload WsReceiveBuffer.AddRange(buffer.Skip(((int)offset + index)).Take(((int)length))); index += length; size -= length; // Process WebSocket frame if (WsReceiveBuffer.Count == total) { int bufferOffset = WsHeaderSize; // Unmask WebSocket frame content if (mask) { for (int i = 0; i < WsPayloadSize; ++i) { WsReceiveBuffer[bufferOffset + i] ^= WsReceiveMask[i % 4]; } } WsReceived = true; if ((opcode & WS_PING) == WS_PING) { // Call the WebSocket ping handler _wsHandler.OnWsPing(WsReceiveBuffer.ToArray(), bufferOffset, WsPayloadSize); } else if ((opcode & WS_PONG) == WS_PONG) { // Call the WebSocket pong handler _wsHandler.OnWsPong(WsReceiveBuffer.ToArray(), bufferOffset, WsPayloadSize); } else if ((opcode & WS_CLOSE) == WS_CLOSE) { // Call the WebSocket close handler _wsHandler.OnWsClose(WsReceiveBuffer.ToArray(), bufferOffset, WsPayloadSize); } else if (((opcode & WS_TEXT) == WS_TEXT) || ((opcode & WS_BINARY) == WS_BINARY)) { // Call the WebSocket received handler _wsHandler.OnWsReceived(WsReceiveBuffer.ToArray(), bufferOffset, WsPayloadSize); } } } } }
/// <summary> /// Prepare WebSocket send frame /// </summary> /// <param name="buffer">Buffer to send</param> /// <param name="offset">Buffer offset</param> /// <param name="size">Buffer size</param> public void PrepareReceiveFrame(byte[] buffer, long offset, long size) { lock (WsReceiveLock) { var index = 0; // Clear received data after WebSocket frame was processed if (WsReceived) { WsReceived = false; WsHeaderSize = 0; WsPayloadSize = 0; WsReceiveBuffer.Clear(); Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length); } while (size > 0) { // Clear received data after WebSocket frame was processed if (WsReceived) { WsReceived = false; WsHeaderSize = 0; WsPayloadSize = 0; WsReceiveBuffer.Clear(); Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length); } // Prepare WebSocket frame opcode and mask flag if (WsReceiveBuffer.Count < 2) { for (int i = 0; i < 2; ++i, ++index, --size) { if (size == 0) { return; } WsReceiveBuffer.Add(buffer[offset + index]); } } byte opcode = (byte)(WsReceiveBuffer[0] & 0x0F); bool fin = ((WsReceiveBuffer[0] >> 7) & 0x01) != 0; bool mask = ((WsReceiveBuffer[1] >> 7) & 0x01) != 0; int payload = WsReceiveBuffer[1] & (~0x80); // Prepare WebSocket frame size if (payload <= 125) { WsHeaderSize = 2 + (mask ? 4 : 0); WsPayloadSize = payload; WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize; } else if (payload == 126) { if (WsReceiveBuffer.Count < 4) { for (int i = 0; i < 2; ++i, ++index, --size) { if (size == 0) { return; } WsReceiveBuffer.Add(buffer[offset + index]); } } payload = ((WsReceiveBuffer[2] << 8) | (WsReceiveBuffer[3] << 0)); WsHeaderSize = 4 + (mask ? 4 : 0); WsPayloadSize = payload; WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize; } else if (payload == 127) { if (WsReceiveBuffer.Count < 10) { for (int i = 0; i < 8; ++i, ++index, --size) { if (size == 0) { return; } WsReceiveBuffer.Add(buffer[offset + index]); } } payload = ((WsReceiveBuffer[2] << 56) | (WsReceiveBuffer[3] << 48) | (WsReceiveBuffer[4] << 40) | (WsReceiveBuffer[5] << 32) | (WsReceiveBuffer[6] << 24) | (WsReceiveBuffer[7] << 16) | (WsReceiveBuffer[8] << 8) | (WsReceiveBuffer[9] << 0)); WsHeaderSize = 10 + (mask ? 4 : 0); WsPayloadSize = payload; WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize; } // Prepare WebSocket frame mask if (mask) { if (WsReceiveBuffer.Count < WsHeaderSize) { for (int i = 0; i < 4; ++i, ++index, --size) { if (size == 0) { return; } WsReceiveBuffer.Add(buffer[offset + index]); WsReceiveMask[i] = buffer[offset + index]; } } } int total = WsHeaderSize + WsPayloadSize; int length = Math.Min(total - WsReceiveBuffer.Count, (int)size); // Prepare WebSocket frame payload WsReceiveBuffer.AddRange(buffer[((int)offset + index)..((int)offset + index + length)]);