libwebsockets
Lightweight C library for HTML5 websockets
Built-in service loop entry

Functions

LWS_VISIBLE LWS_EXTERN int lws_service (struct lws_context *context, int timeout_ms)
 
LWS_VISIBLE LWS_EXTERN int lws_service_tsi (struct lws_context *context, int timeout_ms, int tsi)
 
LWS_VISIBLE LWS_EXTERN void lws_cancel_service_pt (struct lws *wsi)
 
LWS_VISIBLE LWS_EXTERN void lws_cancel_service (struct lws_context *context)
 
LWS_VISIBLE LWS_EXTERN int lws_service_fd (struct lws_context *context, struct lws_pollfd *pollfd)
 
LWS_VISIBLE LWS_EXTERN int lws_service_fd_tsi (struct lws_context *context, struct lws_pollfd *pollfd, int tsi)
 
LWS_VISIBLE LWS_EXTERN int lws_service_adjust_timeout (struct lws_context *context, int timeout_ms, int tsi)
 
LWS_VISIBLE LWS_EXTERN int lws_handle_POLLOUT_event (struct lws *wsi, struct lws_pollfd *pollfd)
 

Detailed Description

lws_client_http_body_pending() - control if client connection neeeds to send body

Parameters
wsiclient connection
something_left_to_sendnonzero if need to send more body, 0 (default) if nothing more to send

If you will send payload data with your HTTP client connection, eg, for POST, when you set the related http headers in LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER callback you should also call this API with something_left_to_send nonzero, and call lws_callback_on_writable(wsi);

After sending the headers, lws will call your callback with LWS_CALLBACK_CLIENT_HTTP_WRITEABLE reason when writable. You can send the next part of the http body payload, calling lws_callback_on_writable(wsi); if there is more to come, or lws_client_http_body_pending(wsi, 0); to let lws know the last part is sent and the connection can move on.

Built-in service loop entry

If you're not using libev / libuv, these apis are needed to enter the poll() wait in lws and service any connections with pending events.

Function Documentation

◆ lws_cancel_service()

LWS_VISIBLE LWS_EXTERN void lws_cancel_service ( struct lws_context *  context)

#include <lib/libwebsockets.h>

lws_cancel_service() - Cancel wait for new pending socket activity

Parameters
contextWebsocket context
 This function let a call to lws_service() waiting for a timeout
 immediately return.

 What it basically does is provide a fake event that will be swallowed,
 so the wait in poll() is ended.  That's useful because poll() doesn't
 attend to changes in POLLIN/OUT/ERR until it re-enters the wait.

◆ lws_cancel_service_pt()

LWS_VISIBLE LWS_EXTERN void lws_cancel_service_pt ( struct lws *  wsi)

#include <lib/libwebsockets.h>

lws_cancel_service_pt() - Cancel servicing of pending socket activity on one thread

Parameters
wsiCancel service on the thread this wsi is serviced by
 This function lets a call to lws_service() waiting for a timeout
 immediately return.

 It works by creating a phony event and then swallowing it silently.

 The reason it may be needed is when waiting in poll(), changes to
 the event masks are ignored by the OS until poll() is reentered.  This
 lets you halt the poll() wait and make the reentry happen immediately
 instead of having the wait out the rest of the poll timeout.

◆ lws_service()

LWS_VISIBLE LWS_EXTERN int lws_service ( struct lws_context *  context,
int  timeout_ms 
)

#include <lib/libwebsockets.h>

lws_service() - Service any pending websocket activity

Parameters
contextWebsocket context
timeout_msTimeout for poll; 0 means return immediately if nothing needed service otherwise block and service immediately, returning after the timeout if nothing needed service.

This function deals with any pending websocket traffic, for three kinds of event. It handles these events on both server and client types of connection the same.

1) Accept new connections to our context's server

2) Call the receive callback for incoming frame data received by server or client connections.

You need to call this service function periodically to all the above functions to happen; if your application is single-threaded you can just call it in your main event loop.

Alternatively you can fork a new process that asynchronously handles calling this service in a loop. In that case you are happy if this call blocks your thread until it needs to take care of something and would call it with a large nonzero timeout. Your loop then takes no CPU while there is nothing happening.

If you are calling it in a single-threaded app, you don't want it to wait around blocking other things in your loop from happening, so you would call it with a timeout_ms of 0, so it returns immediately if nothing is pending, or as soon as it services whatever was pending.

◆ lws_service_adjust_timeout()

LWS_VISIBLE LWS_EXTERN int lws_service_adjust_timeout ( struct lws_context *  context,
int  timeout_ms,
int  tsi 
)

#include <lib/libwebsockets.h>

lws_service_adjust_timeout() - Check for any connection needing forced service

Parameters
contextWebsocket context
timeout_msThe original poll timeout value. You can just set this to 1 if you don't really have a poll timeout.
tsithread service index

Under some conditions connections may need service even though there is no pending network action on them, this is "forced service". For default poll() and libuv / libev, the library takes care of calling this and dealing with it for you. But for external poll() integration, you need access to the apis.

If anybody needs "forced service", returned timeout is zero. In that case, you can call lws_service_tsi() with a timeout of -1 to only service guys who need forced service.

◆ lws_service_fd()

LWS_VISIBLE LWS_EXTERN int lws_service_fd ( struct lws_context *  context,
struct lws_pollfd pollfd 
)

#include <lib/libwebsockets.h>

lws_service_fd() - Service polled socket with something waiting

Parameters
contextWebsocket context
pollfdThe pollfd entry describing the socket fd and which events happened, or NULL to tell lws to do only timeout servicing.

This function takes a pollfd that has POLLIN or POLLOUT activity and services it according to the state of the associated struct lws.

The one call deals with all "service" that might happen on a socket including listen accepts, http files as well as websocket protocol.

If a pollfd says it has something, you can just pass it to lws_service_fd() whether it is a socket handled by lws or not. If it sees it is a lws socket, the traffic will be handled and pollfd->revents will be zeroed now.

If the socket is foreign to lws, it leaves revents alone. So you can see if you should service yourself by checking the pollfd revents after letting lws try to service it.

You should also call this with pollfd = NULL to just allow the once-per-second global timeout checks; if less than a second since the last check it returns immediately then.

◆ lws_service_fd_tsi()

LWS_VISIBLE LWS_EXTERN int lws_service_fd_tsi ( struct lws_context *  context,
struct lws_pollfd pollfd,
int  tsi 
)

#include <lib/libwebsockets.h>

lws_service_fd_tsi() - Service polled socket in specific service thread

Parameters
contextWebsocket context
pollfdThe pollfd entry describing the socket fd and which events happened.
tsithread service index

Same as lws_service_fd() but used with multiple service threads

◆ lws_service_tsi()

LWS_VISIBLE LWS_EXTERN int lws_service_tsi ( struct lws_context *  context,
int  timeout_ms,
int  tsi 
)

#include <lib/libwebsockets.h>

lws_service_tsi() - Service any pending websocket activity

Parameters
contextWebsocket context
timeout_msTimeout for poll; 0 means return immediately if nothing needed service otherwise block and service immediately, returning after the timeout if nothing needed service.
tsiThread service index, starting at 0

Same as lws_service(), but for a specific thread service index. Only needed if you are spawning multiple service threads.