Fix to expose openssl dependency
[platform/upstream/libwebsockets.git] / README.lws-meta.md
1 # lws-meta protocol
2
3 lws-meta is a lightweight ws subprotocol that accepts other ws connections
4 to the same server inside it and multiplexes their access to the connection.
5
6 ```
7   Client                                                    Server
8  
9   conn1: \                                                / :conn1
10   conn2:  =   mux ------ lws-meta ws protocol ----- mux  =  :conn2
11   conn3: /                                                \ :conn3
12 ```
13
14 You may have n client ws connections back to the server, but you now
15 only have one tcp connection (and one SSL wrapper if using SSL) instead
16 of n of those.
17
18 If you currently make multiple ws connections back to the server, so you
19 can have different protocols active in one webpage, this if for you.
20
21  - The subprotocol code for the connections inside a lws-meta connection
22    need zero changes from being a normal ws connection.  It is unaware
23    it is inside an lws-meta parent connection.
24
25  - The traffic on the lws-meta connection is indistinguishable from
26    standard ws traffic, so intermediaries won't object to it
27
28  - The multiplexing is done in the protocol, **not by an extension**.  So
29    it's compatible with all browsers.
30
31  - Javascript helper code is provided to very simply use lws-meta
32    protocol instead of direct connections.  The lws test server has
33    been converted to use this by default.
34
35 # Converting your server
36
37 1) include the provided lws-meta plugin (plugins/protocl_lws_meta.c) as an
38 active protocol for your server.  You can do that using runtime plugins, or
39 include the plugin sources into your server at build-time.  The lws test
40 server uses the latter approach.
41
42 That's all you need to do on the server side.
43
44 # Converting your browser JS
45
46 1) import lws-common.js
47
48 2) Instantiate a parent lws-meta connection object
49
50 ```
51 var lws_meta = new lws_meta_ws();
52 ```
53
54 3) Connect the lws-meta object to your server
55
56 ```
57 lws_meta.new_parent(get_appropriate_ws_url("?mirror=" + mirror_name));
58 ```
59
60 4) Convert your actual ws connections to go via the lws_meta object
61
62 ```
63 var my_ws = lws_meta.new_ws("", "dumb-increment-protocol");
64 ```
65
66 The first arg is the URL path, the second arg is the ws protocol you want.
67
68 That's it.  my_ws will get `onopen()`, `onmessage()` etc calls as before.
69
70 # lws-meta wire protocol
71
72 lws-meta works by adding some bytes at the start of a message indicating
73 which channel the message applies to.
74
75 Channel messages are atomic on the wire.  The reason is if we tried to
76 intersperse other channel fragments between one channels message fragments,
77 an intermediary would observe violations of the ws framing rule about
78 having to start a message with TEXT or BINARY, and use only CONTINUATION
79 for the subsequent fragments.  Eg
80
81 ```
82   [ ch1 TEXT NOFIN ] [ ch2 BINARY FIN ] [ ch1 CONTINUATION FIN ]
83 ```
84
85 is illegal to an observer that doesn't understand lws-meta headers in the
86 packet payloads.  So to avoid this situation, only complete messages may
87 be sent from one subchannel in each direction at a time.
88
89 Consequently, only the first fragment of each message is modified to
90 have the extra two bytes identifying the subchannel it is aimed at, since
91 the rest of the message from the same subchannel is defined to follow.
92
93 If it makes latencies, modify the protocol sending large messages to
94 send smaller messages, so the transmission of messages from other channels
95 can be sent inbetween the smaller messages.
96
97 ## lws-meta commands
98
99 1) CSTRING indicates a string terminated by 0x00 byte
100
101 2) Channel IDs are sent with 0x20 added to them, to guarantee valid UTF-8
102
103 ### 0x41: RX: LWS_META_CMD_OPEN_SUBCHANNEL
104
105    - CSTRING: protocol name
106    - CSTRING: url
107    - CSTRING: cookie (7 bytes max)
108
109 Client is requesting to open a new channel with the given protocol name,
110 at the given url.  The cookie (eg, channel name) is only used in
111 LWS_META_CMD_OPEN_RESULT, when the channel id is assigned, so it is
112 applied to the right channel.
113
114 ### 0x42: TX: LWS_META_CMD_OPEN_RESULT
115
116    - CSTRING cookie
117    - BYTE channel id (0 indicates failed)
118    - CSTRING: selected protocol name
119
120 The server is informing the client of the results of a previous
121 open request.  The cookie the client sent to identify the request
122 is returned along with a channel id to be used subsequently.  If
123 the channel ID is 0 (after subtracting the transport offset of
124 0x20) then the open request has failed.
125
126 ### 0x43: TX: LWS_META_CMD_CLOSE_NOTIFY
127
128    - BYTE channel id
129    - BYTE: payload length + 0x20
130    - BYTE: close code MSB
131    - BYTE: close code LSB
132    - PAYLOAD: payload (< 123 bytes)
133
134 Server notifies the client that a child has closed, for whatever reason.
135
136 ### 0x44: RX: LWS_META_CMD_CLOSE_RQ
137    - BYTE: channel id
138    - BYTE: payload length + 0x20
139    - BYTE: close code MSB
140    - BYTE: close code LSB
141    - PAYLOAD: payload (< 123 bytes)
142
143 The client requests to close a child connection
144
145 ### 0x45: TX: LWS_META_CMD_WRITE
146
147    - BYTE: channel id
148
149 Normal write of payload n from lws-meta perspective is actually
150 LWS_META_CMD_WRITE, channel id, then (n - 2) bytes of payload
151
152 The command only appears at the start of a message, continuations do
153 not have the command.
154
155 ## Protocol Notes
156
157  - Once the subchannel is up, overhead is only +2 bytes per message
158
159  - Close reasons are supported in both directions
160
161  - Ping and Pong are only supported at the lws-meta level, using normal ws ping and pong packets.
162
163  - Only the final close of the tcp lws-meta connection itself goes out as
164    a normal ws close frame.  Subchannels close is done in a normal TEXT
165    message using LWS_META_CMD_CLOSE_RQ and then the close packet payload.
166    This is so intermediaries do not mistake subchannel closures for the
167    tcp / ws link going down.
168
169    Messages that start with LWS_META_CMD_OPEN_SUBCHANNEL only contain those
170    commands but may contain any number of them for the whole duration of the
171    message.  The lws-meta js support collects child open requests made before
172    the parent lws-meta connection is open, and dumps them all in a single
173    message when it does open.
174
175    Messages that start with LWS_META_CMD_OPEN_RESULT or LWS_META_CMD_CLOSE_NOTIFY
176    only contain those two commands, but they may contain any number of them
177    for the whole duration of the message.
178
179
180 # Current Implemention Limitations
181
182  - only server side is supported in lws.  The client side JS for
183    a browser is supported.
184
185  - max number of child connections per parent at the moment is 8
186
187  - child connection URL paramter when opening the connection is
188    ignored
189
190  - there is no ah attached when the child connections are
191    established inside the lws-meta parent.  So header access
192    functions will fail.