From 3e75936387c29f6c9d24511ad8f60723425d69af Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Fri, 21 Dec 2018 02:13:44 +0100 Subject: [PATCH] Begin restoring WebSocket performance --- src/AsyncSocket.h | 18 ++++++++++++++++++ src/WebSocket.h | 29 +++++++++++++++++------------ src/WebSocketProtocol.h | 9 +++++++++ 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/AsyncSocket.h b/src/AsyncSocket.h index 02bc77f..791ff32 100644 --- a/src/AsyncSocket.h +++ b/src/AsyncSocket.h @@ -71,6 +71,24 @@ protected: getLoopData()->corked = true; } + // this is highly broken right now, should properly make use of secondary buffer if needed + std::pair getSendBuffer(size_t size) { + + // for now, just return this straight up + + LoopData *loopData = getLoopData(); + + char *sendBuffer = loopData->corkBuffer + loopData->corkOffset; + + + // very broken + loopData->corkOffset += size; + + + + return {sendBuffer, false}; + } + /* Write in three levels of prioritization: cork-buffer, syscall, socket-buffer. Always drain if possible. * Returns pair of bytes written (anywhere) and wheter or not this call resulted in the polling for * writable (or we are in a state that implies polling for writable). */ diff --git a/src/WebSocket.h b/src/WebSocket.h index 264dd4e..13686b8 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -40,20 +40,25 @@ private: public: // this function need clean-ups and perf. fixes - void send(std::string_view message, uWS::OpCode opCode) { + bool send(std::string_view message, uWS::OpCode opCode = uWS::OpCode::BINARY, bool compress = false) { + /* Transform the message to compressed domain if requested */ + if (compress) { + //message = ; + std::cout << "send compression ignored!" << std::endl; + } - // if corkAllocate(size) then corkFree(unused) - - // format the response - char *buf = (char *) malloc(message.length() + 100); - int writeLength = WebSocketProtocol>::formatMessage(buf, message.data(), message.length(), opCode, message.length(), false); - - - - Super::write(buf, writeLength); - - free(buf); + /* Get size, alloate size, write if needed */ + size_t messageFrameSize = WebSocketProtocol>::messageFrameSize(message.length()); + auto[sendBuffer, requiresWrite] = Super::getSendBuffer(messageFrameSize); + WebSocketProtocol>::formatMessage(sendBuffer, message.data(), message.length(), opCode, message.length(), false); + if (requiresWrite) { + auto[written, failed] = Super::write(sendBuffer, messageFrameSize); + /* Return true for success */ + return !failed; + } + /* Return success */ + return true; } /* Emit close event, stat passive timeout */ diff --git a/src/WebSocketProtocol.h b/src/WebSocketProtocol.h index a0ef600..993f52c 100644 --- a/src/WebSocketProtocol.h +++ b/src/WebSocketProtocol.h @@ -309,6 +309,15 @@ public: return 0; } + static inline size_t messageFrameSize(size_t messageSize) { + if (messageSize < 126) { + return 2 + messageSize; + } else if (messageSize <= UINT16_MAX) { + return 4 + messageSize; + } + return 10 + messageSize; + } + static inline size_t formatMessage(char *dst, const char *src, size_t length, OpCode opCode, size_t reportedLength, bool compressed) { size_t messageLength; size_t headerLength;