Basic fragmented send feature
This commit is contained in:
+16
-2
@@ -73,9 +73,23 @@ public:
|
|||||||
DROPPED
|
DROPPED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Sending fragmented messages puts a bit of effort on the user; you must not interleave regular sends
|
||||||
|
* with fragmented sends and you must sendFirstFragment, [sendFragment], then finally sendLastFragment. */
|
||||||
|
SendStatus sendFirstFragment(std::string_view message, OpCode opCode = OpCode::BINARY, bool compress = false) {
|
||||||
|
return send(message, opCode, compress, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendStatus sendFragment(std::string_view message, bool compress = false) {
|
||||||
|
return send(message, CONTINUATION, compress, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendStatus sendLastFragment(std::string_view message, bool compress = false) {
|
||||||
|
return send(message, CONTINUATION, compress, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Send or buffer a WebSocket frame, compressed or not. Returns BACKPRESSURE on increased user space backpressure,
|
/* Send or buffer a WebSocket frame, compressed or not. Returns BACKPRESSURE on increased user space backpressure,
|
||||||
* DROPPED on dropped message (due to backpressure) or SUCCCESS if you are free to send even more now. */
|
* DROPPED on dropped message (due to backpressure) or SUCCCESS if you are free to send even more now. */
|
||||||
SendStatus send(std::string_view message, OpCode opCode = OpCode::BINARY, bool compress = false) {
|
SendStatus send(std::string_view message, OpCode opCode = OpCode::BINARY, bool compress = false, bool fin = true) {
|
||||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
||||||
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||||
);
|
);
|
||||||
@@ -117,7 +131,7 @@ public:
|
|||||||
/* Get size, allocate size, write if needed */
|
/* Get size, allocate size, write if needed */
|
||||||
size_t messageFrameSize = protocol::messageFrameSize(message.length());
|
size_t messageFrameSize = protocol::messageFrameSize(message.length());
|
||||||
auto [sendBuffer, sendBufferAttribute] = Super::getSendBuffer(messageFrameSize);
|
auto [sendBuffer, sendBufferAttribute] = Super::getSendBuffer(messageFrameSize);
|
||||||
protocol::formatMessage<isServer>(sendBuffer, message.data(), message.length(), opCode, message.length(), compress);
|
protocol::formatMessage<isServer>(sendBuffer, message.data(), message.length(), opCode, message.length(), compress, fin);
|
||||||
|
|
||||||
/* Depending on size of message we have different paths */
|
/* Depending on size of message we have different paths */
|
||||||
if (sendBufferAttribute == SendBufferAttribute::NEEDS_DRAIN) {
|
if (sendBufferAttribute == SendBufferAttribute::NEEDS_DRAIN) {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const std::string_view ERR_TOO_BIG_MESSAGE_INFLATION("Received too big message,
|
|||||||
const std::string_view ERR_INVALID_CLOSE_PAYLOAD("Received invalid close payload");
|
const std::string_view ERR_INVALID_CLOSE_PAYLOAD("Received invalid close payload");
|
||||||
|
|
||||||
enum OpCode : unsigned char {
|
enum OpCode : unsigned char {
|
||||||
|
CONTINUATION = 0,
|
||||||
TEXT = 1,
|
TEXT = 1,
|
||||||
BINARY = 2,
|
BINARY = 2,
|
||||||
CLOSE = 8,
|
CLOSE = 8,
|
||||||
@@ -205,7 +206,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <bool isServer>
|
template <bool isServer>
|
||||||
static inline size_t formatMessage(char *dst, const char *src, size_t length, OpCode opCode, size_t reportedLength, bool compressed) {
|
static inline size_t formatMessage(char *dst, const char *src, size_t length, OpCode opCode, size_t reportedLength, bool compressed, bool fin) {
|
||||||
size_t messageLength;
|
size_t messageLength;
|
||||||
size_t headerLength;
|
size_t headerLength;
|
||||||
if (reportedLength < 126) {
|
if (reportedLength < 126) {
|
||||||
@@ -223,11 +224,9 @@ static inline size_t formatMessage(char *dst, const char *src, size_t length, Op
|
|||||||
memcpy(&dst[2], &tmp, sizeof(uint64_t));
|
memcpy(&dst[2], &tmp, sizeof(uint64_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags = 0;
|
dst[0] = (char) ((fin ? 128 : 0) | ((compressed && opCode) ? SND_COMPRESSED : 0) | (char) opCode);
|
||||||
dst[0] = (char) ((flags & SND_NO_FIN ? 0 : 128) | (compressed ? SND_COMPRESSED : 0));
|
|
||||||
if (!(flags & SND_CONTINUATION)) {
|
//printf("%d\n", (int)dst[0]);
|
||||||
dst[0] |= (char) opCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
char mask[4];
|
char mask[4];
|
||||||
if (!isServer) {
|
if (!isServer) {
|
||||||
|
|||||||
Reference in New Issue
Block a user