Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions include/sendspin/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "sendspin/types.h"

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
Expand Down Expand Up @@ -409,9 +410,11 @@ class SendspinClient {

/// @brief Processes a JSON message from a connection
/// @param conn The connection that received the message
/// @param message The raw JSON text
/// @param data Pointer to the raw JSON text (not null-terminated; valid for the duration of the
/// call only)
/// @param len Length of the JSON text in bytes
/// @param timestamp Receive timestamp in microseconds
void process_json_message(SendspinConnection* conn, const std::string& message,
void process_json_message(SendspinConnection* conn, const char* data, size_t len,
int64_t timestamp);

/// @brief Processes a binary message from a connection
Expand Down
4 changes: 2 additions & 2 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,10 +483,10 @@ std::string SendspinClient::build_hello_message() {
// Message processing
// ============================================================================

void SendspinClient::process_json_message(SendspinConnection* conn, const std::string& message,
void SendspinClient::process_json_message(SendspinConnection* conn, const char* data, size_t len,
int64_t timestamp) {
JsonDocument doc = make_json_document();
DeserializationError error = deserializeJson(doc, message.c_str(), message.size());
DeserializationError error = deserializeJson(doc, data, len);
if (error || doc.isNull()) {
SS_LOGW(TAG, "Failed to parse JSON message");
return;
Expand Down
13 changes: 7 additions & 6 deletions src/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,14 @@ SS_HOT void SendspinConnection::dispatch_completed_message(bool is_text, int64_t
}

if (is_text) {
// Create string from payload for JSON processing
const std::string message(this->websocket_payload_.data(),
this->websocket_payload_.data() + this->websocket_write_offset_);

// Invoke JSON message callback
// Hand the JSON callback a pointer straight into the reassembly buffer instead of copying
// it into a std::string. The callback parses synchronously; reset_websocket_payload()
// below makes the buffer reusable as soon as it returns, so the callback must not retain
// the pointer. Not null-terminated; the length is authoritative.
if (this->on_json_message_cb) {
this->on_json_message_cb(this, message, receive_time);
this->on_json_message_cb(this,
reinterpret_cast<const char*>(this->websocket_payload_.data()),
this->websocket_write_offset_, receive_time);
}
} else {
// Binary message - connection retains buffer ownership, callback reads in-place
Expand Down
16 changes: 10 additions & 6 deletions src/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ using SendCompleteCallback = std::function<void(bool)>;
* // Concrete subclass provided by the platform layer
* auto conn = std::make_unique<SendspinClientConnection>(url, config);
* conn->on_connected_cb = [](SendspinConnection* c) { c->send_text_message(hello_json, {}); };
* conn->on_json_message_cb = [](SendspinConnection* c, const std::string& msg, int64_t t) { ... };
* conn->on_json_message_cb = [](SendspinConnection* c, const char* d, size_t n, int64_t t) {...};
* conn->on_disconnected_cb = [](SendspinConnection* c) { handle_disconnect(); };
* conn->start();
* // Call conn->loop() from a periodic task
Expand Down Expand Up @@ -165,9 +165,12 @@ class SendspinConnection : public std::enable_shared_from_this<SendspinConnectio

/// @brief Callback invoked when a JSON message is received
/// @param conn Pointer to this connection.
/// @param message The JSON message string.
/// @param data Pointer to the message bytes, owned by the connection. Valid only until the
/// callback returns -- it is reused for the next message immediately afterwards, so the
/// callback must not retain it. Not null-terminated; use @p len.
/// @param len Length of the message in bytes.
/// @param timestamp The client timestamp when the message was received.
std::function<void(SendspinConnection*, const std::string&, int64_t)> on_json_message_cb;
std::function<void(SendspinConnection*, const char*, size_t, int64_t)> on_json_message_cb;

/// @brief Callback invoked when a binary message is received
/// @param conn Pointer to this connection.
Expand Down Expand Up @@ -321,9 +324,10 @@ class SendspinConnection : public std::enable_shared_from_this<SendspinConnectio

/// @brief Dispatches a fully assembled message to the appropriate callback
///
/// For text messages: creates a std::string from the buffer, invokes on_json_message_cb,
/// deallocates buffer. For binary messages: invokes on_binary_message_cb callback. If the
/// buffer is null, does nothing.
/// For text messages: invokes on_json_message_cb with a pointer into the reassembly buffer
/// (no intermediate std::string). For binary messages: invokes on_binary_message_cb. Either
/// way the buffer is retained and only its write offset is reset afterwards. If the buffer is
/// null, does nothing.
///
/// @param is_text True if this is a text message, false for binary.
/// @param receive_time Timestamp when the data was received (microseconds).
Expand Down
4 changes: 2 additions & 2 deletions src/connection_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,9 @@ void ConnectionManager::setup_connection_callbacks(SendspinConnection* conn) {
std::lock_guard<std::mutex> lock(this->conn_mutex_);
this->pending_connected_events_.push_back(c->shared_from_this());
};
conn->on_json_message_cb = [this](SendspinConnection* c, const std::string& message,
conn->on_json_message_cb = [this](SendspinConnection* c, const char* data, size_t len,
int64_t timestamp) {
this->client_->process_json_message(c, message, timestamp);
this->client_->process_json_message(c, data, len, timestamp);
};
conn->on_binary_message_cb = [this](SendspinConnection* /*c*/, uint8_t* payload, size_t len) {
this->client_->process_binary_message(payload, len);
Expand Down
4 changes: 2 additions & 2 deletions src/host/client_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ namespace sendspin {
*
* @code
* auto conn = std::make_unique<SendspinClientConnection>("ws://192.168.1.10:8928");
* conn->on_json_message_cb = [](SendspinConnection*, const std::string& msg, int64_t) {
* handle(msg);
* conn->on_json_message_cb = [](SendspinConnection*, const char* data, size_t len, int64_t) {
* handle(data, len);
* }; conn->start();
* // periodically:
* conn->loop();
Expand Down
Loading