libwebsockets
Lightweight C library for HTML5 websockets
Sending data

Data Structures

struct  lws_write_passthru
 

Enumerations

enum  lws_write_protocol {
  LWS_WRITE_TEXT = 0, LWS_WRITE_BINARY = 1, LWS_WRITE_CONTINUATION = 2, LWS_WRITE_HTTP = 3,
  LWS_WRITE_PING = 5, LWS_WRITE_PONG = 6, LWS_WRITE_HTTP_FINAL = 7, LWS_WRITE_HTTP_HEADERS = 8,
  LWS_WRITE_HTTP_HEADERS_CONTINUATION = 9, LWS_WRITE_NO_FIN = 0x40, LWS_WRITE_H2_STREAM_END = 0x80, LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80
}
 

Functions

LWS_VISIBLE LWS_EXTERN int lws_write (struct lws *wsi, unsigned char *buf, size_t len, enum lws_write_protocol protocol)
 

Detailed Description

APIs related to writing data on a connection

Enumeration Type Documentation

◆ lws_write_protocol

#include <lib/libwebsockets.h>

Enumerator
LWS_WRITE_TEXT 

Send a ws TEXT message,the pointer must have LWS_PRE valid memory behind it. The receiver expects only valid utf-8 in the payload

LWS_WRITE_BINARY 

Send a ws BINARY message, the pointer must have LWS_PRE valid memory behind it. Any sequence of bytes is valid

LWS_WRITE_CONTINUATION 

Continue a previous ws message, the pointer must have LWS_PRE valid memory behind it

LWS_WRITE_HTTP 

Send HTTP content

LWS_WRITE_HTTP_HEADERS 

Send http headers (http2 encodes this payload and LWS_WRITE_HTTP payload differently, http 1.x links also handle this correctly. so to be compatible with both in the future,header response part should be sent using this regardless of http version expected)

LWS_WRITE_HTTP_HEADERS_CONTINUATION 

Continuation of http/2 headers

LWS_WRITE_NO_FIN 

This part of the message is not the end of the message

LWS_WRITE_H2_STREAM_END 

Flag indicates this packet should go out with STREAM_END if h2 STREAM_END is allowed on DATA or HEADERS.

LWS_WRITE_CLIENT_IGNORE_XOR_MASK 

client packet payload goes out on wire unmunged only useful for security tests since normal servers cannot decode the content if used

4035  {
4036  LWS_WRITE_TEXT = 0,
4040  LWS_WRITE_BINARY = 1,
4046  LWS_WRITE_HTTP = 3,
4049  /* LWS_WRITE_CLOSE is handled by lws_close_reason() */
4050  LWS_WRITE_PING = 5,
4051  LWS_WRITE_PONG = 6,
4052 
4053  /* Same as write_http but we know this write ends the transaction */
4054  LWS_WRITE_HTTP_FINAL = 7,
4055 
4056  /* HTTP2 */
4057 
4068  /****** add new things just above ---^ ******/
4069 
4070  /* flags */
4071 
4072  LWS_WRITE_NO_FIN = 0x40,
4075  LWS_WRITE_H2_STREAM_END = 0x80,
4084 };
Definition: libwebsockets.h:4046
Definition: libwebsockets.h:4072
Definition: libwebsockets.h:4036
Definition: libwebsockets.h:4040
Definition: libwebsockets.h:4080
Definition: libwebsockets.h:4064
Definition: libwebsockets.h:4043
Definition: libwebsockets.h:4075
Definition: libwebsockets.h:4058

Function Documentation

◆ lws_write()

LWS_VISIBLE LWS_EXTERN int lws_write ( struct lws *  wsi,
unsigned char *  buf,
size_t  len,
enum lws_write_protocol  protocol 
)

#include <lib/libwebsockets.h>

lws_write() - Apply protocol then write data to client

Parameters
wsiWebsocket instance (available from user callback)
bufThe data to send. For data being sent on a websocket connection (ie, not default http), this buffer MUST have LWS_PRE bytes valid BEFORE the pointer. This is so the protocol header data can be added in-situ.
lenCount of the data bytes in the payload starting from buf
protocolUse LWS_WRITE_HTTP to reply to an http connection, and one of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate data on a websockets connection. Remember to allow the extra bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT are used.

This function provides the way to issue data back to the client for both http and websocket protocols.

IMPORTANT NOTICE!

When sending with websocket protocol

LWS_WRITE_TEXT, LWS_WRITE_BINARY, LWS_WRITE_CONTINUATION, LWS_WRITE_PING, LWS_WRITE_PONG

the send buffer has to have LWS_PRE bytes valid BEFORE the buffer pointer you pass to lws_write().

This allows us to add protocol info before and after the data, and send as one packet on the network without payload copying, for maximum efficiency.

So for example you need this kind of code to use lws_write with a 128-byte payload

char buf[LWS_PRE + 128];

// fill your part of the buffer... for example here it's all zeros memset(&buf[LWS_PRE], 0, 128);

lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT);

When sending HTTP, with

LWS_WRITE_HTTP, LWS_WRITE_HTTP_HEADERS LWS_WRITE_HTTP_FINAL

there is no protocol data prepended, and don't need to take care about the LWS_PRE bytes valid before the buffer pointer.

LWS_PRE is at least the frame nonce + 2 header + 8 length LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off. The example apps no longer use it.

Pad LWS_PRE to the CPU word size, so that word references to the address immediately after the padding won't cause an unaligned access error. Sometimes for performance reasons the recommended padding is even larger than sizeof(void *).

 In the case of sending using websocket protocol, be sure to allocate
 valid storage before and after buf as explained above.  This scheme
 allows maximum efficiency of sending data and protocol in a single
 packet while not burdening the user code with any protocol knowledge.

 Return may be -1 for a fatal error needing connection close, or the
 number of bytes sent.

Truncated Writes

The OS may not accept everything you asked to write on the connection.

Posix defines POLLOUT indication from poll() to show that the connection will accept more write data, but it doesn't specifiy how much. It may just accept one byte of whatever you wanted to send.

LWS will buffer the remainder automatically, and send it out autonomously.

During that time, WRITABLE callbacks will be suppressed.

This is to handle corner cases where unexpectedly the OS refuses what we usually expect it to accept. You should try to send in chunks that are almost always accepted in order to avoid the inefficiency of the buffering.