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.
10 conn2: = mux ------ lws-meta ws protocol ----- mux = :conn2
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
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.
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.
25 - The traffic on the lws-meta connection is indistinguishable from
26 standard ws traffic, so intermediaries won't object to it
28 - The multiplexing is done in the protocol, **not by an extension**. So
29 it's compatible with all browsers.
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.
35 # Converting your server
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.
42 That's all you need to do on the server side.
44 # Converting your browser JS
46 1) import lws-common.js
48 2) Instantiate a parent lws-meta connection object
51 var lws_meta = new lws_meta_ws();
54 3) Connect the lws-meta object to your server
57 lws_meta.new_parent(get_appropriate_ws_url("?mirror=" + mirror_name));
60 4) Convert your actual ws connections to go via the lws_meta object
63 var my_ws = lws_meta.new_ws("", "dumb-increment-protocol");
66 The first arg is the URL path, the second arg is the ws protocol you want.
68 That's it. my_ws will get `onopen()`, `onmessage()` etc calls as before.
70 # lws-meta wire protocol
72 lws-meta works by adding some bytes at the start of a message indicating
73 which channel the message applies to.
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
82 [ ch1 TEXT NOFIN ] [ ch2 BINARY FIN ] [ ch1 CONTINUATION FIN ]
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.
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.
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.
99 1) CSTRING indicates a string terminated by 0x00 byte
101 2) Channel IDs are sent with 0x20 added to them, to guarantee valid UTF-8
103 ### 0x41: RX: LWS_META_CMD_OPEN_SUBCHANNEL
105 - CSTRING: protocol name
107 - CSTRING: cookie (7 bytes max)
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.
114 ### 0x42: TX: LWS_META_CMD_OPEN_RESULT
117 - BYTE channel id (0 indicates failed)
118 - CSTRING: selected protocol name
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.
126 ### 0x43: TX: LWS_META_CMD_CLOSE_NOTIFY
129 - BYTE: payload length + 0x20
130 - BYTE: close code MSB
131 - BYTE: close code LSB
132 - PAYLOAD: payload (< 123 bytes)
134 Server notifies the client that a child has closed, for whatever reason.
136 ### 0x44: RX: LWS_META_CMD_CLOSE_RQ
138 - BYTE: payload length + 0x20
139 - BYTE: close code MSB
140 - BYTE: close code LSB
141 - PAYLOAD: payload (< 123 bytes)
143 The client requests to close a child connection
145 ### 0x45: TX: LWS_META_CMD_WRITE
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
152 The command only appears at the start of a message, continuations do
153 not have the command.
157 - Once the subchannel is up, overhead is only +2 bytes per message
159 - Close reasons are supported in both directions
161 - Ping and Pong are only supported at the lws-meta level, using normal ws ping and pong packets.
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.
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.
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.
180 # Current Implemention Limitations
182 - only server side is supported in lws. The client side JS for
183 a browser is supported.
185 - max number of child connections per parent at the moment is 8
187 - child connection URL paramter when opening the connection is
190 - there is no ah attached when the child connections are
191 established inside the lws-meta parent. So header access