blob: 333011caedf5db6f614d75821f1a75c8613d8de4 [file] [log] [blame]
Andy Green6c1f64e2013-01-20 11:28:06 +08001Daemonization
2-------------
3
4There's a helper api lws_daemonize built by default that does everything you
5need to daemonize well, including creating a lock file. If you're making
6what's basically a daemon, just call this early in your init to fork to a
7headless background process and exit the starting process.
8
9Notice stdout, stderr, stdin are all redirected to /dev/null to enforce your
10daemon is headless, so you'll need to sort out alternative logging, by, eg,
11syslog.
12
13
14Maximum number of connections
15-----------------------------
16
17The maximum number of connections the library can deal with is decided when
18it starts by querying the OS to find out how many file descriptors it is
19allowed to open (1024 on Fedora for example). It then allocates arrays that
20allow up to that many connections, minus whatever other file descriptors are
21in use by the user code.
22
23If you want to restrict that allocation, or increase it, you can use ulimit or
24similar to change the avaiable number of file descriptors, and when restarted
25libwebsockets will adapt accordingly.
26
27
Andy Green6f520a52013-01-29 17:57:39 +080028Libwebsockets is singlethreaded
29-------------------------------
Andy Green52f28ce2013-01-25 17:34:15 +080030
Andy Green6f520a52013-01-29 17:57:39 +080031Directly performing websocket actions from other threads is not allowed.
32Aside from the internal data being inconsistent in forked() processes,
33the scope of a wsi (struct websocket) can end at any time during service
34with the socket closing and the wsi freed.
Andy Green52f28ce2013-01-25 17:34:15 +080035
Andy Green6f520a52013-01-29 17:57:39 +080036Websocket write activities should only take place in the
37"LWS_CALLBACK_SERVER_WRITEABLE" callback as described below.
Andy Green52f28ce2013-01-25 17:34:15 +080038
Andy Green6f520a52013-01-29 17:57:39 +080039Only live connections appear in the user callbacks, so this removes any
40possibility of trying to used closed and freed wsis.
41
42If you need to service other socket or file descriptors as well as the
43websocket ones, you can combine them together with the websocket ones
44in one poll loop, see "External Polling Loop support" below, and
45still do it all in one thread / process context.
46
47
48Only send data when socket writeable
49------------------------------------
50
51You should only send data on a websocket connection from the user callback
52"LWS_CALLBACK_SERVER_WRITEABLE" (or "LWS_CALLBACK_CLIENT_WRITEABLE" for
53clients).
54
55If you want to send something, do not just send it but request a callback
56when the socket is writeable using
57
58 - libwebsocket_callback_on_writable(context, wsi) for a specific wsi, or
59 - libwebsocket_callback_on_writable_all_protocol(protocol) for all connections
60using that protocol to get a callback when next writeable.
61
62Usually you will get called back immediately next time around the service
63loop, but if your peer is slow or temporarily inactive the callback will be
64delayed accordingly. Generating what to write and sending it should be done
65in the ...WRITEABLE callback.
66
67See the test server code for an example of how to do this.
Andy Green52f28ce2013-01-25 17:34:15 +080068
69
Andy Green15d56dd2014-04-10 11:23:18 +080070Do not rely on only your own WRITEABLE requests appearing
71---------------------------------------------------------
72
73Libwebsockets may generate additional LWS_CALLBACK_CLIENT_WRITEABLE events
74if it met network conditions where it had to buffer your send data internally.
75
76So your code for LWS_CALLBACK_CLIENT_WRITEABLE needs to own the decision
77about what to send, it can't assume that just because the writeable callback
78came it really is time to send something.
79
80It's quite possible you get an 'extra' writeable callback at any time and
81just need to return 0 and wait for the expected callback later.
82
83
Andy Green099f7892013-02-15 10:25:58 +080084Closing connections from the user side
85--------------------------------------
86
87When you want to close a connection, you do it by returning -1 from a
88callback for that connection.
89
90You can provoke a callback by calling libwebsocket_callback_on_writable on
91the wsi, then notice in the callback you want to close it and just return -1.
92But usually, the decision to close is made in a callback already and returning
93-1 is simple.
94
95If the socket knows the connection is dead, because the peer closed or there
96was an affirmitive network error like a FIN coming, then libwebsockets will
97take care of closing the connection automatically.
98
99If you have a silently dead connection, it's possible to enter a state where
100the send pipe on the connection is choked but no ack will ever come, so the
101dead connection will never become writeable. To cover that, you can use TCP
102keepalives (see later in this document)
103
104
Andy Green6c1f64e2013-01-20 11:28:06 +0800105Fragmented messages
106-------------------
107
108To support fragmented messages you need to check for the final
109frame of a message with libwebsocket_is_final_fragment. This
110check can be combined with libwebsockets_remaining_packet_payload
111to gather the whole contents of a message, eg:
112
113 case LWS_CALLBACK_RECEIVE:
114 {
115 Client * const client = (Client *)user;
116 const size_t remaining = libwebsockets_remaining_packet_payload(wsi);
117
118 if (!remaining && libwebsocket_is_final_fragment(wsi)) {
119 if (client->HasFragments()) {
120 client->AppendMessageFragment(in, len, 0);
121 in = (void *)client->GetMessage();
122 len = client->GetMessageLength();
123 }
124
125 client->ProcessMessage((char *)in, len, wsi);
126 client->ResetMessage();
127 } else
128 client->AppendMessageFragment(in, len, remaining);
129 }
130 break;
131
132The test app llibwebsockets-test-fraggle sources also show how to
133deal with fragmented messages.
134
Andy Green52f28ce2013-01-25 17:34:15 +0800135
Andy Green6c1f64e2013-01-20 11:28:06 +0800136Debug Logging
137-------------
138
139Also using lws_set_log_level api you may provide a custom callback to actually
140emit the log string. By default, this points to an internal emit function
141that sends to stderr. Setting it to NULL leaves it as it is instead.
142
143A helper function lwsl_emit_syslog() is exported from the library to simplify
144logging to syslog. You still need to use setlogmask, openlog and closelog
145in your user code.
146
147The logging apis are made available for user code.
148
149lwsl_err(...)
150lwsl_warn(...)
151lwsl_notice(...)
152lwsl_info(...)
153lwsl_debug(...)
154
155The difference between notice and info is that notice will be logged by default
156whereas info is ignored by default.
157
158
159External Polling Loop support
160-----------------------------
161
162libwebsockets maintains an internal poll() array for all of its
163sockets, but you can instead integrate the sockets into an
164external polling array. That's needed if libwebsockets will
165cooperate with an existing poll array maintained by another
166server.
167
168Four callbacks LWS_CALLBACK_ADD_POLL_FD, LWS_CALLBACK_DEL_POLL_FD,
169LWS_CALLBACK_SET_MODE_POLL_FD and LWS_CALLBACK_CLEAR_MODE_POLL_FD
170appear in the callback for protocol 0 and allow interface code to
171manage socket descriptors in other poll loops.
172
Andy Green58f214e2013-03-09 13:03:53 +0800173You can pass all pollfds that need service to libwebsocket_service_fd(), even
174if the socket or file does not belong to libwebsockets it is safe.
175
176If libwebsocket handled it, it zeros the pollfd revents field before returning.
177So you can let libwebsockets try and if pollfd->revents is nonzero on return,
178you know it needs handling by your code.
179
Andy Green6c1f64e2013-01-20 11:28:06 +0800180
Andy Green36eb70d2013-02-01 08:42:15 +0800181Using with in c++ apps
182----------------------
183
184The library is ready for use by C++ apps. You can get started quickly by
185copying the test server
186
187$ cp test-server/test-server.c test.cpp
188
189and building it in C++ like this
190
191$ g++ -DINSTALL_DATADIR=\"/usr/share\" -ocpptest test.cpp -lwebsockets
192
193INSTALL_DATADIR is only needed because the test server uses it as shipped, if
194you remove the references to it in your app you don't need to define it on
195the g++ line either.
Andy Greena2b3a362013-02-06 20:13:03 +0900196
197
198Availability of header information
199----------------------------------
200
201From v1.2 of the library onwards, the HTTP header content is free()d as soon
202as the websocket connection is established. For websocket servers, you can
203copy interesting headers by handling LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION
204callback, for clients there's a new callback just for this purpose
205LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH.
206
Andy Greena690cd02013-02-09 12:25:31 +0800207
208TCP Keepalive
209-------------
210
211It is possible for a connection which is not being used to send to die
212silently somewhere between the peer and the side not sending. In this case
213by default TCP will just not report anything and you will never get any more
214incoming data or sign the link is dead until you try to send.
215
216To deal with getting a notification of that situation, you can choose to
217enable TCP keepalives on all libwebsockets sockets, when you create the
218context.
219
220To enable keepalive, set the ka_time member of the context creation parameter
221struct to a nonzero value (in seconds) at context creation time. You should
222also fill ka_probes and ka_interval in that case.
223
224With keepalive enabled, the TCP layer will send control packets that should
225stimulate a response from the peer without affecting link traffic. If the
226response is not coming, the socket will announce an error at poll() forcing
227a close.
228
Andy Greena47865f2013-02-10 09:39:47 +0800229Note that BSDs don't support keepalive time / probes / inteveral per-socket
230like Linux does. On those systems you can enable keepalive by a nonzero
231value in ka_time, but the systemwide kernel settings for the time / probes/
232interval are used, regardless of what nonzero value is in ka_time.
Andy Green2672fb22013-02-22 09:54:35 +0800233
234Optimizing SSL connections
235--------------------------
236
237There's a member ssl_cipher_list in the lws_context_creation_info struct
238which allows the user code to restrict the possible cipher selection at
239context-creation time.
240
241You might want to look into that to stop the ssl peers selecting a ciher which
242is too computationally expensive. To use it, point it to a string like
243
244"RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
245
246if left NULL, then the "DEFAULT" set of ciphers are all possible to select.
247
Andy Green5dc62ea2013-09-20 20:26:12 +0800248
249Async nature of client connections
250----------------------------------
251
252When you call libwebsocket_client_connect(..) and get a wsi back, it does not
253mean your connection is active. It just mean it started trying to connect.
254
255Your client connection is actually active only when you receive
256LWS_CALLBACK_CLIENT_ESTABLISHED for it.
257
258There's a 5 second timeout for the connection, and it may give up or die for
259other reasons, if any of that happens you'll get a
260LWS_CALLBACK_CLIENT_CONNECTION_ERROR callback on protocol 0 instead for the
261wsi.
262
263After attempting the connection and getting back a non-NULL wsi you should
264loop calling libwebsocket_service() until one of the above callbacks occurs.
265
266As usual, see test-client.c for example code.
267