webrtcftw / goals

Let's use issues to map out goals for this group
22 stars 0 forks source link

Pure JS data channel implementation #1

Open feross opened 9 years ago

feross commented 9 years ago

WebRTC let's us do browser<–>browser p2p communication.

But what about browser<–>server and server<–>server?

WebRTC everywhere

There are significant advantages to using the same transport (i.e. WebRTC) for all peer connections in a decentralized system, including:

The data channel can be used in node.js via the wrtc module by @modeswitch. It's impressive work, but not without it's drawbacks.

It takes 25+ minutes to install on my system, and pre-built binaries are not available :(. It has to download and compile Google's libwebrtc from scratch. libwebrtc is huge! It contains libjingle, chromium's depot_tools, lots of video/audio codec stuff, and more! And there are install issues for users without a suitable compiler installed.

A pure JS implementation (relying only on node.js built-ins like dgram and net) would greatly simplify installation for end users.

Open questions

Related discussion: https://github.com/jbenet/random-ideas/issues/13

feross commented 9 years ago

Tagging people who I've discussed this with: @mafintosh, @substack, @fippo, @jbenet, @maxogden, @modeswitch, @DamonOehlman, @jhiesey.

mafintosh commented 9 years ago

I think we should setup a hangouts session for people interested in implementing this and discuss different approaches asap.

DamonOehlman commented 9 years ago

Sounds like a plan to me, TZ here is +11 so I'll try and participate if I can.

modeswitch commented 9 years ago

Thanks for settings this up.

The approach I took with wrtc has been very mixed, largely for the reasons mentioned above by @feross. I'd like to avoid writing a full WebRTC implementation in JS at this point, in favour of adapting existing native libraries. The two big problems I have with libjingle are 1) that it isn't very modular, and 2) the build process sucks a lot (gyp has not been a pleasure to use).

Mozilla's WebRTC implementation is tightly coupled to Firefox, so it would likely be as bad as libjingle to work with. OpenWebRTC may be smaller and easier to build, but it doesn't have support for data channels (though maybe we can contribute code there?).

It would be nice to have a solution that can support media streams as well. I get feature requests for that all the time. If it's done in a modular way then it doesn't need to impact consumers who don't want it.

Another (crazy?) option is to work with emscripten to generate JS for some of the native library components. I have no idea how nasty that might be, but it's worth mentioning anyway.

Sorry I've been silent on these discussions. I have more time for this now and I intend to be involved. Count me in for a hangout session; I'm in GMT-5.

jbenet commented 9 years ago

Hello everyone! excited this is shaping up -- thanks for including. As @feross mentioned, this discussion has some other people: https://github.com/jbenet/random-ideas/issues/13 and links thoughts.

+1 for hangout.

It takes 25+ minutes to install on my system, and pre-built binaries are not available :(. It has to download and compile Google's libwebrtc from scratch. libwebrtc is huge! It contains libjingle, chromium's depot_tools, lots of video/audio codec stuff, and more! And there are install issues for users without a suitable compiler installed.

Agreed, let's get the UX (for both users and devs) to be great!

Would it be useful to make a standalone c library for data channel (extracted from libwebrtc) that multiple languages could bind to? If this reduced compile time from 25 minutes to <1 minute, maybe that's enough and we don't need a pure JS implementation.

My vote is for this. In terms of time investment, i think it it's both easier, and more far reaching.. Ripping out the sources (not compiling from chromium source but actually extracting the relevant code, removing the chaff) may be a lot simpler than an implementation from scratch (particularly if we can talk / ask questions to the people who implemented it -- the chromium lists are pretty active). Plus, making a {libdc, libdatachannel, libpeerdc, ...} would be extremely helpful to all the other languages in the world. We can do Node prebuilt binaries really well (e.g. @mafintosh's leveldown-prebuilt). (Of course, given plenty of time, i'm all up for helping with a pure js impl, but i think our mileage may go much further if we consider a broader community).

getify commented 9 years ago

useful to make a standalone c library for data channel

+1

piranna commented 9 years ago

GMT+1 (Spain), but prefer to use email/github issues.

A pure JS is almost impossible, or impractical. There's a lot of libraries involved and to have some performance we would need to use compiled modules at some degree. As a teaching project it's ok, but not production ready. I think a better alternative is to have a dinamyc library that can be used by several languajes.

getify commented 9 years ago

selfishly, can it (the C/whatever lib) please be something that also works on iOS?

3rd-Eden commented 9 years ago

I'm also interested in seeing something that allows browser < - > server communication using only data channels. I would love to see something like this be released a module where we can build applications upon. I think that going with an c library where Node can just bind in to makes more sense here as it would allow other languages leverage the work.

chesles commented 9 years ago

+1 to what @jbenet said - a small C library that builds fast and that any language could bind to would be awesome.

I'm interested in experimenting with this in a side project I have and helping/learning as much as I can.

DamonOehlman commented 9 years ago

I'd say for anyone interested in looking at what's involved in creating a more modular implementation utilizing C/C++ libraries, having a look at the prereqs for janus is a great place to start.

I've started thinking about this previously, and if I had managed to find the time I probably would have tackled the problem in two parts:

  1. Creating a binding to libnice. I just did a quick scan and there does seem to be one of these already (https://github.com/Innovailable/node-libnice), however, it is currently licensed using AGPL. cc @thammi
  2. Creating a binding to an SCTP implementation. The one referenced from Janus is sctp-refimpl. The "reference implementation" badge probably means we should exercise caution here, but I'm sure @lminiero can comment about how stable it is.
jb55 commented 9 years ago

I'd say for anyone interested in looking at what's involved in creating a more modular implementation utilizing C/C++ libraries, having a look at the prereqs for janus is a great place to start.

There's also clib by which has a growing ecosystem of micro-libs and has a similar feel to npm.

jb55 commented 9 years ago

I still think a pure JS version is worth trying, as well as a small c version

fippo commented 9 years ago

if you care only about browser<->server then you can probably get away with using ice-tcp (only available in chrome today) in pure js and bindings to usrsctp for now. The latter is easy enough to install, especially compared to the webrtc.org lib.

lminiero commented 9 years ago

sctp-refimpl is an excellent library written by Michael Tuexen, one of the authors of the Data Channels specification in the IETF and SCTP expert. Besides, it's being used in both Chrome and Firefox, so we simply cannot go wrong doing the same :-)

As explained in https://github.com/meetecho/janus-gateway/blob/master/sctp.c (the code where I handle most of the Data Channels stuff) I based the implementation on a sample application that the library provided: http://code.google.com/p/sctp-refimpl/source/browse/trunk/KERN/usrsctp/programs/rtcweb.c

This example shows how you can transfer SCTP messages on top of a different "transport", that is, not using SCTP directly but on top of, let's say UDP or something else. In my case, I obviously wanted to have something that I could have relayed up to the code handling DTLS connectivity, so that I could have it sent that way. Same thing for incoming messages, i.e., data retrieved through DTLS and to be passed to the SCTP stack somehow.

My integration in Janus currently only supports strings, but supporting octets should, at least in principle, just be a matter of using the binary PPID (53) instead of strings (51), as specified in https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-11#section-8

libnice+openssl+sctp-refimpl should be enough to cover the requirements.

hjon commented 9 years ago

Looks like a C library now exists: http://opentools.homeip.net/webrtc

modeswitch commented 9 years ago

I'm going to try ripping out all the mediastream non-datachannel stuff from libjingle, just to see where that gets us.

modeswitch commented 9 years ago

Quick update: I've made some good progress on stripping down libjingle. Data channels are working and all the media streams code is unreferenced. I'm now removing source files and updating build scripts to see how quick/easy this can get. There are very few system deps required now to build.

DamonOehlman commented 9 years ago

@modeswitch That's awesome news mate - very cool :)

modeswitch commented 9 years ago

I've released an update for wrtc that uses a stripped-down version of libwebrtc. If you're on linux, try npm install wrtc to check it out.

A few notes:

Any other feedback, please let me know!

getify commented 9 years ago

just wanted to say this makes my heart smile! :)

LongLiveCHIEF commented 9 years ago

I tried to install with Mac OS 10.9, but ran into issues because I'm using command line tools, (can't install xcode due to company policy). Not sure I want to log this as an issue, but might want to note that Xcode is required for Mac users? (for build obviously)

3rd-Eden commented 9 years ago

You can also install the command line tools without xcode. See https://github.com/kennethreitz/osx-gcc-installer for more details.

szimek commented 9 years ago

I've just tried it on OS X 10.10 and got the following error:

$ npm install wrtc
-
> wrtc@0.0.30 install /Users/szimek/Projects/apps/webrtc-test/node_modules/wrtc
> node-gyp rebuild

  ACTION Run build script /dev/null
TARGET_ARCH=x64 Release
Preparing directories ... done
Cloning libwebrtc repository ...  done
Generating build scripts ... .emake: *** [/dev/null] Error 255
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:267:23)
gyp ERR! stack     at ChildProcess.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:820:12)
gyp ERR! System Darwin 14.0.0
gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/szimek/Projects/apps/webrtc-test/node_modules/wrtc
gyp ERR! node -v v0.10.35
gyp ERR! node-gyp -v v1.0.2
gyp ERR! not ok
npm ERR! Darwin 14.0.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "wrtc"
npm ERR! node v0.10.35
npm ERR! npm  v2.1.14
npm ERR! code ELIFECYCLE

npm ERR! wrtc@0.0.30 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the wrtc@0.0.30 install script 'node-gyp rebuild'.
npm ERR! This is most likely a problem with the wrtc package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get their info via:
npm ERR!     npm owner ls wrtc
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/szimek/Projects/apps/webrtc-test/npm-debug.log

It doesn't really tell much what went wrong...

modeswitch commented 9 years ago

@szimek I'll have it dump messages directly to stdout.

modeswitch commented 9 years ago

@szimek Pushed a new version. Build output should stream to your console. I've also re-added depot_tools, since most people won't have ninja.

szimek commented 9 years ago
$ npm install wrtc
|
> wrtc@0.0.31 install /Users/szimek/Projects/apps/webrtc-test/node_modules/wrtc
> node-gyp rebuild

  ACTION Run build script /dev/null
TARGET_ARCH=x64 Release
: Preparing directories ...
: Cloning depot_tools ...
Cloning into 'depot_tools'...
POST git-upload-pack (189 bytes)
POST git-upload-pack (198 bytes)
remote: Sending approximately 13.98 MiB ...
remote: Counting objects: 807, done
remote: Finding sources: 100% (807/807)
remote: Total 807 (delta 75), reused 435 (delta 75)
Receiving objects: 100% (807/807), 2.74 MiB | 1.49 MiB/s, done.
Resolving deltas: 100% (75/75), done.
Checking connectivity... done.
: Cloning libwebrtc ...
Cloning into 'libwebrtc'...
POST git-upload-pack (205 bytes)
POST git-upload-pack (214 bytes)
remote: Counting objects: 7357, done.
remote: Compressing objects: 100% (6299/6299), done.
remote: Total 7357 (delta 913), reused 6279 (delta 754)
Receiving objects: 100% (7357/7357), 36.95 MiB | 6.43 MiB/s, done.
Resolving deltas: 100% (913/913), done.
Checking connectivity... done.
Checking out files: 100% (6879/6879), done.
: Generating build scripts ...
Updating projects from gyp files...
gyp: third_party/boringssl/boringssl.gyp not found (cwd: /Users/szimek/Projects/apps/webrtc-test/node_modules/wrtc/third_party/libwebrtc)
ERROR: 1 null

make: *** [/dev/null] Error 255
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:267:23)
gyp ERR! stack     at ChildProcess.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:820:12)
gyp ERR! System Darwin 14.0.0
gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/szimek/Projects/apps/webrtc-test/node_modules/wrtc
gyp ERR! node -v v0.10.35
gyp ERR! node-gyp -v v1.0.2
gyp ERR! not ok
npm ERR! Darwin 14.0.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "wrtc"
npm ERR! node v0.10.35
npm ERR! npm  v2.1.14
npm ERR! code ELIFECYCLE

npm ERR! wrtc@0.0.31 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the wrtc@0.0.31 install script 'node-gyp rebuild'.
npm ERR! This is most likely a problem with the wrtc package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get their info via:
npm ERR!     npm owner ls wrtc
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/szimek/Projects/apps/webrtc-test/npm-debug.log

Looks like some issue with boringssl.

modeswitch commented 9 years ago

@szimek I removed boringssl because it's not used in the linux build, but I'll add it back.

modeswitch commented 9 years ago

@szimek Fixed.

Also, I think we're detracting from the thread. Let's continue the discussion over here: https://github.com/js-platform/libwebrtc/issues/1

modeswitch commented 9 years ago

Latest version of node-webrtc works on both linux and osx.

One possibility for developing a pure JS implementation would be to start pulling parts of the native library into JS, iteratively. It sounds like a lot of work, though.

mitar commented 8 years ago

Ah, I am late to the story but I am really sad to see that community has decided to drop all the media stuff in favor of shorter compilation times. I just got an idea how great it would be that both the server and client would communicate over WebRTC and can have the same standard API to do that, both for data and for media. I wanted to create a WebRTC/mesh based community radio where servers would be doing recoding and clients would send their stream to them. But without the MediaStream implementation it means that one has to reimplement the whole audio processing in node.js and on top of data channels. Is it really so problematic that the compilation takes a lot of time? Maybe I just remember Qt times where 4 hours of compiling was completely normal. :-)

mitar commented 8 years ago

So probably what I wanted to say with my rant was that there is a case for interoperability. If majority of nodes in your P2P network speak MediaStream (browsers) it is really sad that servers (much more powerful devices) would not as well.

mitar commented 8 years ago

One more comment and then I will stop. The compilation issues also became simpler in the last year with Docker containerization. Now you get it to compile once inside a Docker image and then you have it. You can even cache it in a Docker layer.

jbenet commented 8 years ago

@mitar why isn't this just a layering problem? i'm failing to see the problem. AFAIU, you should be able to do mediastreams just fine, and have a native library compiled in your code for it?

mitar commented 8 years ago

There are some speculations I am not sure about, but:

To me it just looks like duplication of the code in JS for things which have to be low-latency and are tricky to setup correctly.

Also, having exactly the same audio codecs on the client and server would help a lot. So I would anyway have to compile the audio codecs to use in node.js. So why not have them compiled together with WebRTC?

nickdesaulniers commented 8 years ago

WIP: https://github.com/nickdesaulniers/node-rtc-peer-connection

feross commented 8 years ago

community has decided to drop all the media stuff in favor of shorter compilation times

If you want a complete WebRTC stack on the server, there are already multiple you can pick from. See http://webrtc.org/, http://www.openwebrtc.org/, and https://www.npmjs.com/package/wrtc (for use in node.js).

All we're saying is that there's lots of value to be gained by having a library that's lightweight and only does data channel. :)

mitar commented 8 years ago

There is nothing for node.js:

https://www.npmjs.com/package/wrtc (for use in node.js)

MediaStream APIs are not supported in order to reduce the number of external dependencies and to make compilation faster and easier.

max-mapper commented 8 years ago

Electron works for server side webrtc + node just fine using xvfb-run + electron-spawn

xdumaine commented 8 years ago

@maxogden that's really interesting! Do you know of any write ups or examples of doing that?

max-mapper commented 8 years ago

@xdumaine I figured it out when writing https://github.com/moose-team/peerbot#running-on-headless-ubuntu

mitar commented 8 years ago

He he, I was also thinking about that. That why is node.js just V8 on the server side, why not simply the whole Chrome. :-)

fippo commented 8 years ago

@mitar try running chrome on a server... there is a reason a certain browser with 300 million users doesn't support the latest and greatest web features ;-)

xdumaine commented 8 years ago

I was thinking about using it for a Pi drone project.

paullouisageneau commented 4 years ago

+1 to what @jbenet said - a small C library that builds fast and that any language could bind to would be awesome.

A bit late to the party, I've written a standalone C++ library with a C API implementing WebRTC data channels: https://github.com/paullouisageneau/libdatachannel It should compile on POSIX systems (including MacOS) and Windows. If someone feels like writing bindings, you are very welcome to do so.

feross commented 3 years ago

@paullouisageneau Are there Node.js bindings? We're open to exploring using an alternative to wrtc in webtorrent-hyrbid. More info here: https://github.com/webtorrent/webtorrent-hybrid/issues/58#issuecomment-730145283

paullouisageneau commented 3 years ago

@feross Yes, @murat-dogan has been writing node.js bindings here: https://github.com/murat-dogan/node-datachannel