[hybi] lws-meta: lightweight ws mux subprotocol

Andy Green <andy@warmcat.com> Thu, 17 August 2017 10:03 UTC

Return-Path: <andy@warmcat.com>
X-Original-To: hybi@ietfa.amsl.com
Delivered-To: hybi@ietfa.amsl.com
Received: from localhost (localhost []) by ietfa.amsl.com (Postfix) with ESMTP id 797DB132448 for <hybi@ietfa.amsl.com>; Thu, 17 Aug 2017 03:03:47 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.9
X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([]) by localhost (ietfa.amsl.com []) (amavisd-new, port 10024) with ESMTP id exrWMsPIwM4d for <hybi@ietfa.amsl.com>; Thu, 17 Aug 2017 03:03:45 -0700 (PDT)
Received: from mail.warmcat.com (mail.warmcat.com []) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id E9C5E1321A8 for <hybi@ietf.org>; Thu, 17 Aug 2017 03:03:43 -0700 (PDT)
To: hybi@ietf.org
From: Andy Green <andy@warmcat.com>
Message-ID: <a24faacd-96d5-17e1-13ce-453a9334fe0b@warmcat.com>
Date: Thu, 17 Aug 2017 18:03:35 +0800
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Language: en-US
Content-Transfer-Encoding: 7bit
Archived-At: <https://mailarchive.ietf.org/arch/msg/hybi/BXqLLk1rGIc9-iMaCYl8zGzAIR0>
Subject: [hybi] lws-meta: lightweight ws mux subprotocol
X-BeenThere: hybi@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: Server-Initiated HTTP <hybi.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/hybi>, <mailto:hybi-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/hybi/>
List-Post: <mailto:hybi@ietf.org>
List-Help: <mailto:hybi-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 17 Aug 2017 10:03:47 -0000

Hi -

FYI libwebsockets ships with a ws subprotocol (not an extension) and 
helper JS since the last release called "lws-meta", which performs ws 
connection muxing.

If you want to make several logical ws connections back to your server 
using different ws subprotocols, ws doesn't give you a way to do it 
without a tcp connection per ws subprotocol.  Either you stick with one 
tcp connection by throwing unrelated subprotocol stuff into a new single 
ws subprotocol and sort out the mess, or you have n tcp connections back 
to the server for n subprotocols.  (n tcp connections also implies n tls 
tunnels for wss case).

"lws-meta" can open one real ws link with one actual tcp connection / 
tls tunnel, and mux n other logical ws connections inside that.

The lws-meta link contains normal ws frames with opaque content and 
follows ws rules about framing, so intermediaries won't care.  After 
some small messages managing child bringup and close (much smaller than 
doing the http/1 ws upgrade each time), there's only 2 bytes overhead 
per child bulk data frame compared to a direct ws link.

JS objects are provided to manage the real link and mux same-basic-api 
child connections in there using the same apis as a direct ws link (ie, 
onopen() / onclose() / onmessage()).  At least in the lws 
implementation, your normal user ws subprotocols that the child 
connections use are unaware if their traffic is coming on a normal tcp 
connection or via lws-meta; for them everything is the same and the same 
protocol handler server-side can accept connections direct and via lws-meta.

The lws-meta subprotocol is very simple, but of course there's some work 
to do server side to have its child IO appear to be coming from a 
discrete connection.

Details here:


Protocol implementation part for lws: