diff options
Diffstat (limited to 'modules/websocket')
-rw-r--r-- | modules/websocket/doc_classes/WebSocketClient.xml | 42 | ||||
-rw-r--r-- | modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml | 24 | ||||
-rw-r--r-- | modules/websocket/doc_classes/WebSocketPeer.xml | 42 | ||||
-rw-r--r-- | modules/websocket/doc_classes/WebSocketServer.xml | 75 | ||||
-rw-r--r-- | modules/websocket/emws_client.cpp | 5 | ||||
-rw-r--r-- | modules/websocket/emws_client.h | 1 | ||||
-rw-r--r-- | modules/websocket/emws_peer.cpp | 13 | ||||
-rw-r--r-- | modules/websocket/emws_peer.h | 5 | ||||
-rw-r--r-- | modules/websocket/library_godot_websocket.js | 14 | ||||
-rw-r--r-- | modules/websocket/websocket_multiplayer_peer.cpp | 26 | ||||
-rw-r--r-- | modules/websocket/websocket_multiplayer_peer.h | 1 | ||||
-rw-r--r-- | modules/websocket/websocket_peer.cpp | 1 | ||||
-rw-r--r-- | modules/websocket/websocket_peer.h | 1 | ||||
-rw-r--r-- | modules/websocket/wsl_peer.cpp | 12 | ||||
-rw-r--r-- | modules/websocket/wsl_peer.h | 4 | ||||
-rw-r--r-- | modules/websocket/wsl_server.cpp | 14 |
16 files changed, 126 insertions, 154 deletions
diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml index 40c0ad17ad..1549a907b4 100644 --- a/modules/websocket/doc_classes/WebSocketClient.xml +++ b/modules/websocket/doc_classes/WebSocketClient.xml @@ -13,16 +13,11 @@ </tutorials> <methods> <method name="connect_to_url"> - <return type="int" enum="Error"> - </return> - <argument index="0" name="url" type="String"> - </argument> - <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray()"> - </argument> - <argument index="2" name="gd_mp_api" type="bool" default="false"> - </argument> - <argument index="3" name="custom_headers" type="PackedStringArray" default="PackedStringArray()"> - </argument> + <return type="int" enum="Error" /> + <argument index="0" name="url" type="String" /> + <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray()" /> + <argument index="2" name="gd_mp_api" type="bool" default="false" /> + <argument index="3" name="custom_headers" type="PackedStringArray" default="PackedStringArray()" /> <description> Connects to the given URL requesting one of the given [code]protocols[/code] as sub-protocol. If the list empty (default), no sub-protocol will be requested. If [code]true[/code] is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI], connections to non-Godot servers will not work, and [signal data_received] will not be emitted. @@ -33,26 +28,21 @@ </description> </method> <method name="disconnect_from_host"> - <return type="void"> - </return> - <argument index="0" name="code" type="int" default="1000"> - </argument> - <argument index="1" name="reason" type="String" default=""""> - </argument> + <return type="void" /> + <argument index="0" name="code" type="int" default="1000" /> + <argument index="1" name="reason" type="String" default="""" /> <description> Disconnects this client from the connected host. See [method WebSocketPeer.close] for more information. </description> </method> <method name="get_connected_host" qualifiers="const"> - <return type="String"> - </return> + <return type="String" /> <description> Return the IP address of the currently connected host. </description> </method> <method name="get_connected_port" qualifiers="const"> - <return type="int"> - </return> + <return type="int" /> <description> Return the IP port of the currently connected host. </description> @@ -70,8 +60,7 @@ </members> <signals> <signal name="connection_closed"> - <argument index="0" name="was_clean_close" type="bool"> - </argument> + <argument index="0" name="was_clean_close" type="bool" /> <description> Emitted when the connection to the server is closed. [code]was_clean_close[/code] will be [code]true[/code] if the connection was shutdown cleanly. </description> @@ -82,8 +71,7 @@ </description> </signal> <signal name="connection_established"> - <argument index="0" name="protocol" type="String"> - </argument> + <argument index="0" name="protocol" type="String" /> <description> Emitted when a connection with the server is established, [code]protocol[/code] will contain the sub-protocol agreed with the server. </description> @@ -95,10 +83,8 @@ </description> </signal> <signal name="server_close_request"> - <argument index="0" name="code" type="int"> - </argument> - <argument index="1" name="reason" type="String"> - </argument> + <argument index="0" name="code" type="int" /> + <argument index="1" name="reason" type="String" /> <description> Emitted when the server requests a clean close. You should keep polling until you get a [signal connection_closed] signal to achieve the clean close. See [method WebSocketPeer.close] for more details. </description> diff --git a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml index ee1b60f739..cd41e9a1fb 100644 --- a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml +++ b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml @@ -10,25 +10,18 @@ </tutorials> <methods> <method name="get_peer" qualifiers="const"> - <return type="WebSocketPeer"> - </return> - <argument index="0" name="peer_id" type="int"> - </argument> + <return type="WebSocketPeer" /> + <argument index="0" name="peer_id" type="int" /> <description> Returns the [WebSocketPeer] associated to the given [code]peer_id[/code]. </description> </method> <method name="set_buffers"> - <return type="int" enum="Error"> - </return> - <argument index="0" name="input_buffer_size_kb" type="int"> - </argument> - <argument index="1" name="input_max_packets" type="int"> - </argument> - <argument index="2" name="output_buffer_size_kb" type="int"> - </argument> - <argument index="3" name="output_max_packets" type="int"> - </argument> + <return type="int" enum="Error" /> + <argument index="0" name="input_buffer_size_kb" type="int" /> + <argument index="1" name="input_max_packets" type="int" /> + <argument index="2" name="output_buffer_size_kb" type="int" /> + <argument index="3" name="output_max_packets" type="int" /> <description> Configures the buffer sizes for this WebSocket peer. Default values can be specified in the Project Settings under [code]network/limits[/code]. For server, values are meant per connected peer. The first two parameters define the size and queued packets limits of the input buffer, the last two of the output buffer. @@ -43,8 +36,7 @@ </members> <signals> <signal name="peer_packet"> - <argument index="0" name="peer_source" type="int"> - </argument> + <argument index="0" name="peer_source" type="int" /> <description> Emitted when a packet is received from a peer. [b]Note:[/b] This signal is only emitted when the client or server is configured to use Godot multiplayer API. diff --git a/modules/websocket/doc_classes/WebSocketPeer.xml b/modules/websocket/doc_classes/WebSocketPeer.xml index 5125956416..ab7ef6c4d0 100644 --- a/modules/websocket/doc_classes/WebSocketPeer.xml +++ b/modules/websocket/doc_classes/WebSocketPeer.xml @@ -11,12 +11,9 @@ </tutorials> <methods> <method name="close"> - <return type="void"> - </return> - <argument index="0" name="code" type="int" default="1000"> - </argument> - <argument index="1" name="reason" type="String" default=""""> - </argument> + <return type="void" /> + <argument index="0" name="code" type="int" default="1000" /> + <argument index="1" name="reason" type="String" default="""" /> <description> Closes this WebSocket connection. [code]code[/code] is the status code for the closure (see RFC 6455 section 7.4 for a list of valid status codes). [code]reason[/code] is the human readable reason for closing the connection (can be any UTF-8 string that's smaller than 123 bytes). [b]Note:[/b] To achieve a clean close, you will need to keep polling until either [signal WebSocketClient.connection_closed] or [signal WebSocketServer.client_disconnected] is received. @@ -24,57 +21,54 @@ </description> </method> <method name="get_connected_host" qualifiers="const"> - <return type="String"> - </return> + <return type="String" /> <description> Returns the IP address of the connected peer. [b]Note:[/b] Not available in the HTML5 export. </description> </method> <method name="get_connected_port" qualifiers="const"> - <return type="int"> - </return> + <return type="int" /> <description> Returns the remote port of the connected peer. [b]Note:[/b] Not available in the HTML5 export. </description> </method> + <method name="get_current_outbound_buffered_amount" qualifiers="const"> + <return type="int" /> + <description> + Returns the current amount of data in the outbound websocket buffer. [b]Note:[/b] HTML5 exports use WebSocket.bufferedAmount, while other platforms use an internal buffer. + </description> + </method> <method name="get_write_mode" qualifiers="const"> - <return type="int" enum="WebSocketPeer.WriteMode"> - </return> + <return type="int" enum="WebSocketPeer.WriteMode" /> <description> Gets the current selected write mode. See [enum WriteMode]. </description> </method> <method name="is_connected_to_host" qualifiers="const"> - <return type="bool"> - </return> + <return type="bool" /> <description> Returns [code]true[/code] if this peer is currently connected. </description> </method> <method name="set_no_delay"> - <return type="void"> - </return> - <argument index="0" name="enabled" type="bool"> - </argument> + <return type="void" /> + <argument index="0" name="enabled" type="bool" /> <description> Disable Nagle's algorithm on the underling TCP socket (default). See [method StreamPeerTCP.set_no_delay] for more information. [b]Note:[/b] Not available in the HTML5 export. </description> </method> <method name="set_write_mode"> - <return type="void"> - </return> - <argument index="0" name="mode" type="int" enum="WebSocketPeer.WriteMode"> - </argument> + <return type="void" /> + <argument index="0" name="mode" type="int" enum="WebSocketPeer.WriteMode" /> <description> Sets the socket to use the given [enum WriteMode]. </description> </method> <method name="was_string_packet" qualifiers="const"> - <return type="bool"> - </return> + <return type="bool" /> <description> Returns [code]true[/code] if the last received packet was sent as a text payload. See [enum WriteMode]. </description> diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index 5491f7de15..90182de4c2 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -12,61 +12,46 @@ </tutorials> <methods> <method name="disconnect_peer"> - <return type="void"> - </return> - <argument index="0" name="id" type="int"> - </argument> - <argument index="1" name="code" type="int" default="1000"> - </argument> - <argument index="2" name="reason" type="String" default=""""> - </argument> + <return type="void" /> + <argument index="0" name="id" type="int" /> + <argument index="1" name="code" type="int" default="1000" /> + <argument index="2" name="reason" type="String" default="""" /> <description> Disconnects the peer identified by [code]id[/code] from the server. See [method WebSocketPeer.close] for more information. </description> </method> <method name="get_peer_address" qualifiers="const"> - <return type="String"> - </return> - <argument index="0" name="id" type="int"> - </argument> + <return type="String" /> + <argument index="0" name="id" type="int" /> <description> Returns the IP address of the given peer. </description> </method> <method name="get_peer_port" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="id" type="int"> - </argument> + <return type="int" /> + <argument index="0" name="id" type="int" /> <description> Returns the remote port of the given peer. </description> </method> <method name="has_peer" qualifiers="const"> - <return type="bool"> - </return> - <argument index="0" name="id" type="int"> - </argument> + <return type="bool" /> + <argument index="0" name="id" type="int" /> <description> Returns [code]true[/code] if a peer with the given ID is connected. </description> </method> <method name="is_listening" qualifiers="const"> - <return type="bool"> - </return> + <return type="bool" /> <description> Returns [code]true[/code] if the server is actively listening on a port. </description> </method> <method name="listen"> - <return type="int" enum="Error"> - </return> - <argument index="0" name="port" type="int"> - </argument> - <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray()"> - </argument> - <argument index="2" name="gd_mp_api" type="bool" default="false"> - </argument> + <return type="int" enum="Error" /> + <argument index="0" name="port" type="int" /> + <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray()" /> + <argument index="2" name="gd_mp_api" type="bool" default="false" /> <description> Starts listening on the given port. You can specify the desired subprotocols via the "protocols" array. If the list empty (default), no sub-protocol will be requested. @@ -75,8 +60,7 @@ </description> </method> <method name="stop"> - <return type="void"> - </return> + <return type="void" /> <description> Stops the server and clear its state. </description> @@ -101,40 +85,31 @@ </members> <signals> <signal name="client_close_request"> - <argument index="0" name="id" type="int"> - </argument> - <argument index="1" name="code" type="int"> - </argument> - <argument index="2" name="reason" type="String"> - </argument> + <argument index="0" name="id" type="int" /> + <argument index="1" name="code" type="int" /> + <argument index="2" name="reason" type="String" /> <description> Emitted when a client requests a clean close. You should keep polling until you get a [signal client_disconnected] signal with the same [code]id[/code] to achieve the clean close. See [method WebSocketPeer.close] for more details. </description> </signal> <signal name="client_connected"> - <argument index="0" name="id" type="int"> - </argument> - <argument index="1" name="protocol" type="String"> - </argument> - <argument index="2" name="resource_name" type="String"> - </argument> + <argument index="0" name="id" type="int" /> + <argument index="1" name="protocol" type="String" /> + <argument index="2" name="resource_name" type="String" /> <description> Emitted when a new client connects. "protocol" will be the sub-protocol agreed with the client, and "resource_name" will be the resource name of the URI the peer used. "resource_name" is a path (at the very least a single forward slash) and potentially a query string. </description> </signal> <signal name="client_disconnected"> - <argument index="0" name="id" type="int"> - </argument> - <argument index="1" name="was_clean_close" type="bool"> - </argument> + <argument index="0" name="id" type="int" /> + <argument index="1" name="was_clean_close" type="bool" /> <description> Emitted when a client disconnects. [code]was_clean_close[/code] will be [code]true[/code] if the connection was shutdown cleanly. </description> </signal> <signal name="data_received"> - <argument index="0" name="id" type="int"> - </argument> + <argument index="0" name="id" type="int" /> <description> Emitted when a new message is received. [b]Note:[/b] This signal is [i]not[/i] emitted when used as high-level multiplayer peer. diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 744053b6e2..5cd94e978f 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -79,7 +79,7 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, String str = "ws://"; if (p_custom_headers.size()) { - WARN_PRINT_ONCE("Custom headers are not supported in in HTML5 platform."); + WARN_PRINT_ONCE("Custom headers are not supported in HTML5 platform."); } if (p_ssl) { str = "wss://"; @@ -95,7 +95,7 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, return FAILED; } - static_cast<Ref<EMWSPeer>>(_peer)->set_sock(_js_id, _in_buf_size, _in_pkt_size); + static_cast<Ref<EMWSPeer>>(_peer)->set_sock(_js_id, _in_buf_size, _in_pkt_size, _out_buf_size); return OK; } @@ -136,6 +136,7 @@ int EMWSClient::get_max_packet_size() const { Error EMWSClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) { _in_buf_size = nearest_shift(p_in_buffer - 1) + 10; _in_pkt_size = nearest_shift(p_in_packets - 1); + _out_buf_size = nearest_shift(p_out_buffer - 1) + 10; return OK; } diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index ca2d7ed986..3b0b8395b9 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -45,6 +45,7 @@ private: bool _is_connecting = false; int _in_buf_size = DEF_BUF_SHIFT; int _in_pkt_size = DEF_PKT_SHIFT; + int _out_buf_size = DEF_BUF_SHIFT; static void _esws_on_connect(void *obj, char *proto); static void _esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string); diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 05f9e12ae1..69822f6ff3 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -33,10 +33,11 @@ #include "emws_peer.h" #include "core/io/ip.h" -void EMWSPeer::set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size) { +void EMWSPeer::set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size) { peer_sock = p_sock; _in_buffer.resize(p_in_pkt_size, p_in_buf_size); _packet_buffer.resize((1 << p_in_buf_size)); + _out_buf_size = p_out_buf_size; } void EMWSPeer::set_write_mode(WriteMode p_mode) { @@ -53,7 +54,10 @@ Error EMWSPeer::read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_strin } Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + ERR_FAIL_COND_V(_out_buf_size && (godot_js_websocket_buffered_amount(peer_sock) >= (1ULL << _out_buf_size)), ERR_OUT_OF_MEMORY); + int is_bin = write_mode == WebSocketPeer::WRITE_MODE_BINARY ? 1 : 0; + godot_js_websocket_send(peer_sock, p_buffer, p_buffer_size, is_bin); return OK; } @@ -76,6 +80,13 @@ int EMWSPeer::get_available_packet_count() const { return _in_buffer.packets_left(); } +int EMWSPeer::get_current_outbound_buffered_amount() const { + if (peer_sock != -1) { + return godot_js_websocket_buffered_amount(peer_sock); + } + return 0; +} + bool EMWSPeer::was_string_packet() const { return _is_string; } diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index 73e701720b..6e93ea31a2 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -48,6 +48,7 @@ typedef void (*WSOnError)(void *p_ref); extern int godot_js_websocket_create(void *p_ref, const char *p_url, const char *p_proto, WSOnOpen p_on_open, WSOnMessage p_on_message, WSOnError p_on_error, WSOnClose p_on_close); extern int godot_js_websocket_send(int p_id, const uint8_t *p_buf, int p_buf_len, int p_raw); +extern int godot_js_websocket_buffered_amount(int p_id); extern void godot_js_websocket_close(int p_id, int p_code, const char *p_reason); extern void godot_js_websocket_destroy(int p_id); } @@ -62,14 +63,16 @@ private: Vector<uint8_t> _packet_buffer; PacketBuffer<uint8_t> _in_buffer; uint8_t _is_string = 0; + int _out_buf_size = 0; public: Error read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_string); - void set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size); + void set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size); virtual int get_available_packet_count() const; virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); virtual int get_max_packet_size() const { return _packet_buffer.size(); }; + virtual int get_current_outbound_buffered_amount() const; virtual void close(int p_code = 1000, String p_reason = ""); virtual bool is_connected_to_host() const; diff --git a/modules/websocket/library_godot_websocket.js b/modules/websocket/library_godot_websocket.js index b182d1ecde..dd2fd1e94f 100644 --- a/modules/websocket/library_godot_websocket.js +++ b/modules/websocket/library_godot_websocket.js @@ -101,6 +101,15 @@ const GodotWebSocket = { return 0; }, + // Get current bufferedAmount + bufferedAmount: function (p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return 0; // Godot object is gone. + } + return ref.bufferedAmount; + }, + create: function (socket, p_on_open, p_on_message, p_on_error, p_on_close) { const id = IDHandler.add(socket); socket.onopen = GodotWebSocket._onopen.bind(null, id, p_on_open); @@ -171,6 +180,11 @@ const GodotWebSocket = { return GodotWebSocket.send(p_id, out); }, + godot_js_websocket_buffered_amount__sig: 'ii', + godot_js_websocket_buffered_amount: function (p_id) { + return GodotWebSocket.bufferedAmount(p_id); + }, + godot_js_websocket_close__sig: 'viii', godot_js_websocket_close: function (p_id, p_code, p_reason) { const code = p_code; diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index ddd8e190df..52d9a602a1 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -39,35 +39,15 @@ WebSocketMultiplayerPeer::~WebSocketMultiplayerPeer() { _clear(); } -int WebSocketMultiplayerPeer::_gen_unique_id() const { - uint32_t hash = 0; - - while (hash == 0 || hash == 1) { - hash = hash_djb2_one_32( - (uint32_t)OS::get_singleton()->get_ticks_usec()); - hash = hash_djb2_one_32( - (uint32_t)OS::get_singleton()->get_unix_time(), hash); - hash = hash_djb2_one_32( - (uint32_t)OS::get_singleton()->get_data_path().hash64(), hash); - hash = hash_djb2_one_32( - (uint32_t)((uint64_t)this), hash); //rely on aslr heap - hash = hash_djb2_one_32( - (uint32_t)((uint64_t)&hash), hash); //rely on aslr stack - hash = hash & 0x7FFFFFFF; // make it compatible with unsigned, since negative id is used for exclusion - } - - return hash; -} - void WebSocketMultiplayerPeer::_clear() { _peer_map.clear(); if (_current_packet.data != nullptr) { memfree(_current_packet.data); } - for (List<Packet>::Element *E = _incoming_packets.front(); E; E = E->next()) { - memfree(E->get().data); - E->get().data = nullptr; + for (Packet &E : _incoming_packets) { + memfree(E.data); + E.data = nullptr; } _incoming_packets.clear(); diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index e3ccd1a795..4e80f876d6 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -75,7 +75,6 @@ protected: void _send_add(int32_t p_peer_id); void _send_sys(Ref<WebSocketPeer> p_peer, uint8_t p_type, int32_t p_peer_id); void _send_del(int32_t p_peer_id); - int _gen_unique_id() const; public: /* MultiplayerPeer */ diff --git a/modules/websocket/websocket_peer.cpp b/modules/websocket/websocket_peer.cpp index e77fdcfed2..ee13040821 100644 --- a/modules/websocket/websocket_peer.cpp +++ b/modules/websocket/websocket_peer.cpp @@ -47,6 +47,7 @@ void WebSocketPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_connected_host"), &WebSocketPeer::get_connected_host); ClassDB::bind_method(D_METHOD("get_connected_port"), &WebSocketPeer::get_connected_port); ClassDB::bind_method(D_METHOD("set_no_delay", "enabled"), &WebSocketPeer::set_no_delay); + ClassDB::bind_method(D_METHOD("get_current_outbound_buffered_amount"), &WebSocketPeer::get_current_outbound_buffered_amount); BIND_ENUM_CONSTANT(WRITE_MODE_TEXT); BIND_ENUM_CONSTANT(WRITE_MODE_BINARY); diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h index e9bb20f21f..517b8600d6 100644 --- a/modules/websocket/websocket_peer.h +++ b/modules/websocket/websocket_peer.h @@ -59,6 +59,7 @@ public: virtual uint16_t get_connected_port() const = 0; virtual bool was_string_packet() const = 0; virtual void set_no_delay(bool p_enabled) = 0; + virtual int get_current_outbound_buffered_amount() const = 0; WebSocketPeer(); ~WebSocketPeer(); diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index 1dbadfed74..7f027e1c0d 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -205,7 +205,9 @@ void WSLPeer::make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigne ERR_FAIL_COND(p_data == nullptr); _in_buffer.resize(p_in_pkt_size, p_in_buf_size); - _packet_buffer.resize((1 << MAX(p_in_buf_size, p_out_buf_size))); + _packet_buffer.resize(1 << p_in_buf_size); + _out_buf_size = p_out_buf_size; + _out_pkt_size = p_out_pkt_size; _data = p_data; _data->peer = this; @@ -239,6 +241,8 @@ void WSLPeer::poll() { Error WSLPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { ERR_FAIL_COND_V(!is_connected_to_host(), FAILED); + ERR_FAIL_COND_V(_out_pkt_size && (wslay_event_get_queued_msg_count(_data->ctx) >= (1ULL << _out_pkt_size)), ERR_OUT_OF_MEMORY); + ERR_FAIL_COND_V(_out_buf_size && (wslay_event_get_queued_msg_length(_data->ctx) >= (1ULL << _out_buf_size)), ERR_OUT_OF_MEMORY); struct wslay_event_msg msg; // Should I use fragmented? msg.opcode = write_mode == WRITE_MODE_TEXT ? WSLAY_TEXT_FRAME : WSLAY_BINARY_FRAME; @@ -280,6 +284,12 @@ int WSLPeer::get_available_packet_count() const { return _in_buffer.packets_left(); } +int WSLPeer::get_current_outbound_buffered_amount() const { + ERR_FAIL_COND_V(!_data, 0); + + return wslay_event_get_queued_msg_length(_data->ctx); +} + bool WSLPeer::was_string_packet() const { return _is_string; } diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index f1ea98d384..260d4b183d 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -77,6 +77,9 @@ private: WriteMode write_mode = WRITE_MODE_BINARY; + int _out_buf_size = 0; + int _out_pkt_size = 0; + public: int close_code = -1; String close_reason; @@ -86,6 +89,7 @@ public: virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); virtual int get_max_packet_size() const { return _packet_buffer.size(); }; + virtual int get_current_outbound_buffered_amount() const; virtual void close_now(); virtual void close(int p_code = 1000, String p_reason = ""); diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 5f794415af..7402bbb46e 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -190,15 +190,15 @@ void WSLServer::poll() { remove_ids.push_back(E->key()); } } - for (List<int>::Element *E = remove_ids.front(); E; E = E->next()) { - _peer_map.erase(E->get()); + for (int &E : remove_ids) { + _peer_map.erase(E); } remove_ids.clear(); List<Ref<PendingPeer>> remove_peers; - for (List<Ref<PendingPeer>>::Element *E = _pending.front(); E; E = E->next()) { + for (const Ref<PendingPeer> &E : _pending) { String resource_name; - Ref<PendingPeer> ppeer = E->get(); + Ref<PendingPeer> ppeer = E; Error err = ppeer->do_handshake(_protocols, handshake_timeout, resource_name); if (err == ERR_BUSY) { continue; @@ -207,7 +207,7 @@ void WSLServer::poll() { continue; } // Creating new peer - int32_t id = _gen_unique_id(); + int32_t id = generate_unique_id(); WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData); data->obj = this; @@ -224,8 +224,8 @@ void WSLServer::poll() { remove_peers.push_back(ppeer); _on_connect(id, ppeer->protocol, resource_name); } - for (List<Ref<PendingPeer>>::Element *E = remove_peers.front(); E; E = E->next()) { - _pending.erase(E->get()); + for (const Ref<PendingPeer> &E : remove_peers) { + _pending.erase(E); } remove_peers.clear(); |