Send a WebSocket frame. Server-to-client frames are not masked. Header and payload are combined into a single buffer to avoid partial frame writes.
| 83 | /// Send a WebSocket frame. Server-to-client frames are not masked. |
| 84 | /// Header and payload are combined into a single buffer to avoid partial frame writes. |
| 85 | void sendWebSocketFrame(Poco::Net::StreamSocket & socket, uint8_t opcode, const char * data, size_t len) |
| 86 | { |
| 87 | uint8_t header[10]; |
| 88 | size_t header_len = 2; |
| 89 | |
| 90 | header[0] = 0x80 | opcode; /// FIN + opcode |
| 91 | |
| 92 | if (len < 126) |
| 93 | { |
| 94 | header[1] = static_cast<uint8_t>(len); |
| 95 | } |
| 96 | else if (len < 65536) |
| 97 | { |
| 98 | header[1] = 126; |
| 99 | header[2] = static_cast<uint8_t>((len >> 8) & 0xFF); |
| 100 | header[3] = static_cast<uint8_t>(len & 0xFF); |
| 101 | header_len = 4; |
| 102 | } |
| 103 | else |
| 104 | { |
| 105 | header[1] = 127; |
| 106 | for (int i = 0; i < 8; ++i) |
| 107 | header[2 + i] = static_cast<uint8_t>((len >> (56 - 8 * i)) & 0xFF); |
| 108 | header_len = 10; |
| 109 | } |
| 110 | |
| 111 | /// Combine header and payload into a single send to avoid partial frame writes |
| 112 | String buf; |
| 113 | buf.reserve(header_len + len); |
| 114 | buf.append(reinterpret_cast<const char *>(header), header_len); |
| 115 | if (len > 0) |
| 116 | buf.append(data, len); |
| 117 | sendAllBytes(socket, buf.data(), buf.size()); |
| 118 | } |
| 119 | |
| 120 | void sendWebSocketBinary(Poco::Net::StreamSocket & socket, const char * data, size_t len) |
| 121 | { |
no test coverage detected