Update networking layer w/ CURL and emscripten impl
This commit is contained in:
+132
@@ -0,0 +1,132 @@
|
||||
---
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Title: curl_ws_recv
|
||||
Section: 3
|
||||
Source: libcurl
|
||||
See-also:
|
||||
- curl_easy_getinfo (3)
|
||||
- curl_easy_perform (3)
|
||||
- curl_easy_setopt (3)
|
||||
- curl_ws_send (3)
|
||||
- libcurl-ws (3)
|
||||
Protocol:
|
||||
- WS
|
||||
Added-in: 7.86.0
|
||||
---
|
||||
|
||||
# NAME
|
||||
|
||||
curl_ws_recv - receive WebSocket data
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
~~~c
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
|
||||
size_t *recv, const struct curl_ws_frame **meta);
|
||||
~~~
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
Retrieves as much as possible of a received WebSocket frame into the *buffer*,
|
||||
but not more than *buflen* bytes. *recv* is set to the number of bytes
|
||||
actually stored.
|
||||
|
||||
If the function call is successful, the *meta* pointer gets set to point to a
|
||||
*const struct curl_ws_frame* that contains information about the received
|
||||
data. That struct must not be freed and its contents must not be relied upon
|
||||
anymore once another WebSocket function is called. See curl_ws_meta(3) for
|
||||
more details on that struct.
|
||||
|
||||
The application must check `meta->bytesleft` to determine whether the complete
|
||||
frame has been received. If more payload is pending, the application must call
|
||||
this function again with an updated *buffer* and *buflen* to resume receiving.
|
||||
This may for example happen when the data does not fit into the provided
|
||||
buffer or when not all frame data has been delivered over the network yet.
|
||||
|
||||
If the application wants to read the metadata without consuming any payload,
|
||||
it may call this function with a *buflen* of zero. Setting *buffer* to a NULL
|
||||
pointer is permitted in this case. Note that frames without payload are
|
||||
consumed by this action.
|
||||
|
||||
If the received message consists of multiple fragments, the *CURLWS_CONT* bit
|
||||
is set in all frames except the final one. The appropriate *CURLWS_TEXT* or
|
||||
*CURLWS_BINARY* flag is set in every frame, regardless whether it is the first
|
||||
fragment, an intermediate fragment or the final fragment. The application is
|
||||
responsible for reassembling fragmented messages. Special care must be taken
|
||||
to correctly handle control frames (i.e. CLOSE, PING and PONG) arriving in
|
||||
between consecutive fragments of a fragmented TEXT or BINARY message. See
|
||||
curl_ws_meta(3) for more details on *CURLWS_CONT*.
|
||||
|
||||
The WebSocket protocol consists of *messages* that can be delivered over the
|
||||
wire as one or more *frames* - but since a frame can be too large to buffer in
|
||||
memory, libcurl may need to deliver partial frames to the application.
|
||||
Fragments, or chunks, of frames.
|
||||
|
||||
# %PROTOCOLS%
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
~~~c
|
||||
int main(void)
|
||||
{
|
||||
char buffer[256];
|
||||
size_t offset = 0;
|
||||
CURLcode res = CURLE_OK;
|
||||
CURL *curl = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "wss://example.com/");
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L);
|
||||
/* start HTTPS connection and upgrade to WSS, then return control */
|
||||
curl_easy_perform(curl);
|
||||
|
||||
/* Note: This example neglects fragmented messages. (CURLWS_CONT bit)
|
||||
A real application must handle them appropriately. */
|
||||
|
||||
while(!res) {
|
||||
size_t recv;
|
||||
const struct curl_ws_frame *meta;
|
||||
res = curl_ws_recv(curl, buffer + offset, sizeof(buffer) - offset, &recv,
|
||||
&meta);
|
||||
offset += recv;
|
||||
|
||||
if(res == CURLE_OK) {
|
||||
if(meta->bytesleft == 0)
|
||||
break; /* finished receiving */
|
||||
if(meta->bytesleft > sizeof(buffer) - offset)
|
||||
res = CURLE_TOO_LARGE;
|
||||
}
|
||||
|
||||
if(res == CURLE_AGAIN)
|
||||
/* in real application: wait for socket here, e.g. using select() */
|
||||
res = CURLE_OK;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
return (int)res;
|
||||
}
|
||||
~~~
|
||||
|
||||
# %AVAILABILITY%
|
||||
|
||||
# RETURN VALUE
|
||||
|
||||
This function returns a CURLcode indicating success or error.
|
||||
|
||||
CURLE_OK (0) means everything was OK, non-zero means an error occurred, see
|
||||
libcurl-errors(3). If CURLOPT_ERRORBUFFER(3) was set with curl_easy_setopt(3)
|
||||
there can be an error message stored in the error buffer when non-zero is
|
||||
returned.
|
||||
|
||||
Returns **CURLE_GOT_NOTHING** if the associated connection is closed.
|
||||
|
||||
Instead of blocking, the function returns **CURLE_AGAIN**. The correct
|
||||
behavior is then to wait for the socket to signal readability before calling
|
||||
this function again.
|
||||
|
||||
Any other non-zero return value indicates an error. See the libcurl-errors(3)
|
||||
man page for the full list with descriptions.
|
||||
|
||||
Returns **CURLE_GOT_NOTHING** if the associated connection is closed.
|
||||
Reference in New Issue
Block a user