meetecho / janode

A Node.js adapter for the Janus WebRTC server
ISC License
98 stars 36 forks source link

Add UNIX dgram sockets transport #1

Closed atoppi closed 2 years ago

atoppi commented 2 years ago

This PR adds the UNIX sockets transport to Janode. The UNIX socket transport is a more efficient way of establishing connections with Janus when Janode is co-located on the host OS, since in this case the adapter and the server will communicate through Inter-Process Communication (IPC) using a UNIX socket without traversing the network stack.

When dealing with UNIX sockets Janus only supports SOCK_SEQPACKET (default) and SOCK_DGRAM because those modes preserve message boundaries thus keeping both the implementation and the communication simple. On the other hand, node only offers SOCK_STREAM for IPC (net.Socket Class) on Linux, so it is impossibile to rely on native node modules.

Since we didn't manage to find any external library implementing SOCK_SEQPACKET IPC, we've ended up using unix-dgram-socket. This library has a simple C++ SOCK_DGRAM implementation with js code binding to it.

Caveats when using SOCK_DGRAM IPC

SOCK_DGRAM IPC means that the socket is connection-less, thus: 1) the socket on Janode will bind to a local file, needed for handling responses and located at /tmp/.janode-someid 2) there is no close notification, so the liveness of the channel must be checked with a higher level mechanism (such as session keep-alives). Any error when sending a message will trigger a connection tear-down.

How to use it

In order to use this transport edit the janus.transport.pfunix.jcfg Janus configuration: 1) enable the transport 2) set a path for the server socket (e.g. /tmp/janusapi) 3) set SOCK_DGRAM in the socket type

Then edit the Janode app configuration, setting a Janus url that starts with the file:// scheme and matches the server socket path:

{
    address: {
      url: 'file:///tmp/janusapi',
      apisecret: 'secret'
    },
}

Difference with WebSockets over UNIX sockets

Another chance to indirectly rely on UNIX sockets is to use the WebSocket transport providing a scheme ws+unix:// in the janus url.

{
    address: {
      url: 'ws+unix:///tmp/ws.sock',
      apisecret: 'secret'
    },
}

Ref https://github.com/meetecho/janus-gateway/pull/2620. In that case everything will work as normal WebSockets on both client and server but the communication will not happen on top of TCP/IP but over UNIX sockets (probably SOCK_STREAM), preserving the WebSockets framing. Raw UNIX sockets transport will instead push JSON datagrams from/to the sockets without any other framing.

Skip dependency installation

If by any reason you do not want to install the unix-dgram dependency on your system, just build janode without optional dependencies

npm install --no-optional

Supported platforms

This PR has been tested on Linux only. Windows is not supported by the third-party library (installation will not fail, the compiled module will only contain an empty stub).

Browsers

Of course this transport does not work on browsers. We have updated the sample bundle.sh script to ignore the transport-unix.js file and replace it with an empty blob.