Search Unity

UnityPeerJS - simple WebRTC support for Unity WebGL

Discussion in 'Web' started by gfoot, Mar 13, 2015.

  1. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    The other day I became interested in how WebRTC works, for peer-to-peer networking in the browser, and with jonas's WebSockets package as a guide I felt my way through the process of making a package for at least one popular WebRTC API - PeerJS. It was not very difficult, and kind of fun, and this is the result so far:

    UnityPeerJS.unitypackage

    The package includes the jslib, the interop C# layer, and a test MonoBehaviour that's not quite self-sufficient - it needs something to connect to. With a few changes you could make it connect to an instance of itself; however I tested it by connecting to a vanilla PeerJS client running from a regular HTML page in the browser.

    In a nutshell the C# API lets you identify yourself (pick a name), establish connections to other peers (so long as you already know their names), and send and receive byte[] data. Error handling is minimal, and resource cleanup almost entirely absent. So at the moment this is an experimental toy, not a stable library.

    Feel free to use it for whatever you like, bearing in mind PeerJS's licensing of course. I found jonas's WebSockets unitypackage a great help, and maybe this can be similarly helpful for other people.

    A couple of important things to note:
    • You can read about PeerJS here. A lot of the unitypackage API directly mirrors the upstream Javascript API.
    • I didn't implement a C# wrapper, partly because of a distinct scarcity of C#-based WebRTC libraries. I did find one that might work. But for now, the only way to try this out is by doing WebGL builds - it won't work in the editor.
    • WebRTC is a peer-to-peer system but the peers require a central server for matchmaking (referred to as a signalling server). PeerJS defaults to using their own servers for this, and my unitypackage doesn't expose the configuration options for changing that.
    • NAT punchthrough is supported, to a degree. PeerJS defaults to using a STUN server hosted by google, with no TURN servers set up. Again, I don't yet expose the configuration options you need for changing that. If you need to experiment you could just hack the jslib though, as a quick workaround.
    • WebRTC connections have optional settings like requiring packets to be delivered reliably, or in-order; PeerJS exposes some of this, but my unitypackage does not. Again, hack it in the jslib if you need it.
    I am going to play with this some more, and maybe do another version without the PeerJS stuff, just using the browser's WebRTC layer directly.

    WebRTC itself is a bit of a shambles at the moment, especially if your interest is game networking, because it's not really what WebRTC is for and nobody seems to care much about what games need. As far as I can make out, current WebRTC protocols are extremely inefficient (huge headers...) and nobody seems to realise how much of a problem that is for game traffic. There are also big problems with cross-browser support, but it works pretty well in Chrome and Firefox so kind of matches Unity's WebGL portability right now.
     
    rebit likes this.
  2. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    Wow, just tried it, this is awesome!
     
  3. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    I fixed a lot of bugs in the code, and made a chat client demo. You can download the updated unitypackage including the code and scene for the chat demo.

    EDIT: There's an odd bug in the chat client demo - it fails for Peer IDs of length 1, 5, 9, etc. I'm not sure why yet.
     
    Last edited: Mar 16, 2015
  4. Onsterion

    Onsterion

    Joined:
    Feb 21, 2014
    Posts:
    215
    Socket.io not do the same?
     
  5. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    No, Socket.IO doesn't use WebRTC, it uses old fashioned long-polling, with a post-connection upgrade to WebSockets if they are available.
     
  6. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240
    Nice, thanks for the example!

    Assuming it is using SCTP for the data channel it adds 28 bytes to the header, is that correct? I like the idea of WebRTC, it seems like it has come a long way.

    Also if the page I read can be believe STUN by itself for Googles GTalk app has about 92% success with only 8% of clients requiring TURN. That's still a large number when you talk about Google scale but for a game I think I could deal without TURN...
     
  7. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    I only read about this a little bit, but my understanding is that SCTP is tunnelled inside DTLS, which is tunnelled inside UDP. Compared to plain UDP, this is something like an extra 50 header bytes. It might be a temporary measure due to poor router-level support for SCTP or something like that, but still, the UDP header is only 8 bytes so even without it this is still a pretty fat header. I also wouldn't hold your breath for router upgrades - IPv6 has been waiting for decades...

    I would expect STUN to perform no better than any other modern NAT traversal technique. 92% is higher than I would have guessed, but they are the ones with the figures. :)

    TURN is probably not a good idea for a game. While reading up on WebRTC, I came across this company that rents TURN bandwidth. Check out the prices... http://xirsys.com/pricing/

    So I think that like Unity's relay server it's neat that it is supported, but it's not commercially viable for serious games. You're better off requiring that people who want to host their own sessions have decent NAT set-ups.
     
  8. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240
    Yep, TURN is essentially just a relay server so I would expect pricing is going to be similar to running a websocket server via some hosting service, ie. expensive. That's the big draw of WebRTC to me, can I really justify paying for bandwidth for a game I might not even charge for? Probably not.

    What's worse is I looked at that provider and they make you authenticate your app with a TURN API key which in HTML5 would be easily snatched out of the source, so any user could copy your app and also use your TURN bandwidth...I can deal with the fact someone can rip my code in HTML5, that's sort of a compliment, but racking up huge bills I'm on the hook for, different story.
     
  9. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    Yes. I think I saw something about short-term passwords somewhere, where your web server arranges short-term keys on the TURN server for clients to use. Then it doesn't matter so much if they are stolen. Maybe they can build that into their signalling server or something.

    The components are all generic, but browsers do enforce some things like accurate Origin headers which may allow game-funded servers to filter out any cuckoo traffic. It would at least prevent some other game from just hijacking your servers.
     
  10. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    So what is the difference between WebRTC and WebSockets? I'm familiar with the latter and I have my own server that supports we sockets already but not familiar with WebRTC.
     
  11. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240
    Main thing is WebSockets you connect to a server, WebRTC allows peer to peer connections for things like video/audio streaming or data channels.
     
  12. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    So what advantage does it have over, say a lan based setup or matchmaking server combo with direct tcp/ip or better yet UDP connections between peers? Does it provide any Nat traversal benefits? Is it a guaranteed delivery system like tcp/ip or more performance based but potentially lossy like UDP? I'm assuming it is tcp/ip based as I think you mentioned a requirement around packet delivery order.
     
  13. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240
    Let me see if I can answer as non confusing as possible, it gets kind of hairy. If I fail check out this page it is pretty in depth: http://chimera.labs.oreilly.com/books/1230000000545/ch18.html


    Why WebRTC instead of just normal direct tcp or udp between peers?
    WebRTC can be initiated from a web browser specifically thus useful for HTML5. The only sockets that you can initiate from HTML5 apps are plain http, websockets(upgraded http), and WebRTC. Vanilla TCP and UDP is not an option from the browser unless you're using plugins. You also cannot start a WebSocket listener in a browser, only outbound.

    Does it provide any Nat traversal benefits?
    It utilizes STUN and TURN for NAT traversal so you need to provide or use someone elses STUN server and also provide some sort of signalling server to do the matchmaking, but after the two peers are connected all data flows peer to peer. The bandwidth/servers required to get STUN information is provided for free by a number of providers, STUN basically just tells you your public ip address and port so you can inform the other peer who to connect to. TURN is a relay server like you would typically do with something like Photon for instance, shuttling data through a middleman server, but is optional for clients that can't connect with plain STUN/ICE.

    Is it a guaranteed delivery system like tcp/ip or more performance based but potentially lossy like UDP?
    It is udp on the transport layer(makes NAT punchthrough much easier than tcp), encrypted with udp equivalent of TLS called "DTLS" and then a protocol called SCTP is tunneled over the DTLS connection(confused yet?). SCTP supports optional reliable/ordered delivery like tcp, but not required. There are a few WebRTC APIs of interest, audio/video/data, the one most games would be interested in is the DataChannel API, whereas VoiP would be more interested in the streaming media/audio stuff. The DataChannel stuff is pretty much the same as the normal websocket API(message based) and supports text or binary.

    I have yet to do anything beyond proof of concept with it so gfoot or someone else may be able to provide more color. At the end of the day I find it really cool but unlikely to use it for any of my games since I find the security aspect of peer to peer just too difficult to protect against cheating, but it is something I will keep following.
     
    Last edited: Mar 16, 2015
  14. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    Yep, for me it's primarily a matter of using things that work in WebGL builds, where options are limited. On other platforms, unless your game has a very low traffic level, you're better off with plain UDP, and maybe a lightweight layer like UdpKit.

    TURN vs Photon Cloud is a complex comparison - although they both relay traffic through publicly-visible servers, I think they behave quite differently. Photon Cloud gives more functionality, and if that extra functionality suits your game then it should use less bandwidth that TURN in severe situations where peer-to-peer doesn't work; the main disadvantage is that the bandwidth gets used even for peers who could in theory talk directly to each other.
     
    tiggus likes this.
  15. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    By the way, thanks for the link to that book - it is a great description of the protocols involved. Seeing the content of the SCTP header makes me angry though!
     
  16. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240
    Sure no problem, actually it is a really great book in general, check out the section on tcp especially, can help tune a lot of things.
     
  17. yuliyF

    yuliyF

    Joined:
    Nov 15, 2012
    Posts:
    197
    o.. It's only a simply chat, I hope at the video chat =). So, if I want a video chat at the WebGL project on Unity - what am I do -?
     
  18. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    This was just to demonstrate using WebRTC to form a data connection. For video or audio chat you should probably use the browser's direct support, which is quite mature these days. I'm not sure whether there's a clean way to get the result into Unity (like using it as a texture in your scene).
     
  19. yuliyF

    yuliyF

    Joined:
    Nov 15, 2012
    Posts:
    197
    hm.. but I want that user from my game(on facebook or another web page) clicked on the button "video" and run a video chat from another player
     
  20. ACCNCC

    ACCNCC

    Joined:
    May 12, 2015
    Posts:
    8


    I would like to make an online realtime game with WebRTC but I do not understand is there support for WebRTC when exporting to exe,android,os
    Maybe you have ideas how to implement it (if possible =) )?

    the fact that the player from the game in WebGL version could play the other versions of the game exe,android,os
     
  21. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    I found a C# WebRTC library that you could perhaps use, but I didn't download it - possibly it was not free, I'm not sure.
     
  22. ACCNCC

    ACCNCC

    Joined:
    May 12, 2015
    Posts:
    8
    wow! it is possible the link? and what do you have suggestions why it doesn't work?
     
  23. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
  24. Contract-killer

    Contract-killer

    Joined:
    Sep 21, 2012
    Posts:
    42
    Can anyone tell me how to test it as I am making webplayer and anything else notable to connect. Looking for help
     
  25. Contract-killer

    Contract-killer

    Joined:
    Sep 21, 2012
    Posts:
    42
    getting....
    SecurityException: Listening on TCP sockets is not allowed in the webplayer
    System.Net.Sockets.Socket.Listen (Int32 backlog)
    System.Net.Sockets.TcpListener.Start (Int32 backlog)
    System.Net.Sockets.TcpListener.Start ()
    UnityEditor.WebGL.HttpServerEditorWrapper.GetRandomUnusedPort ()
    UnityEditor.WebGL.HttpServerEditorWrapper.CreateIfNeeded (System.String path, System.Int32& port)
    UnityEditor.WebGL.WebGlBuildPostprocessor.LaunchPlayer (BuildLaunchPlayerArgs args)
    UnityEditor.PostprocessBuildPlayer.Launch (BuildTarget target, System.String path, System.String productName, BuildOptions options) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs:282)
    UnityEditor.HostView:OnGUI()
     
  26. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    You're not going to be able to do this directly with Webplayer. If you're using an HTML5 compatible web browser you could use Socket.IO from your javascript and call out to the javascript from Webplayer and back.
     
  27. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    This is the WebGL forum, and not for the Unity Web Player (where this will not work).
     
    Dustin-Horne likes this.
  28. Contract-killer

    Contract-killer

    Joined:
    Sep 21, 2012
    Posts:
    42
    thanks that was my doubt so it will not work with mobile device.
     
  29. Contract-killer

    Contract-killer

    Joined:
    Sep 21, 2012
    Posts:
    42
    It will work with mobile or not ???
     
  30. Blarp

    Blarp

    Joined:
    May 13, 2014
    Posts:
    270
    Websockets for client-server game networking
    webRTC for video/audio streaming ("Twitch.tv"/Spectator-mode & Voice communication)

    A+ combo

    If someone made a video/audio stream through WebRTC for Unity WebGL, I could see Unity acquiring it for Everyplay. Unity hasn't expanded on Everyplay at all and it's been stuck on mobile.

    WebRTC related:
    http://techcrunch.com/2015/12/15/netflixs-ongoing-quest-to-save-bandwidth/

    Everyplay Request:
    https://feedback.unity3d.com/suggestions/everyplay-for-webgl
     
    Last edited: Dec 15, 2015
  31. Contract-killer

    Contract-killer

    Joined:
    Sep 21, 2012
    Posts:
    42
    On uploading the webgl build on server I am getting this @gfoot
     

    Attached Files:

  32. BabilinApps

    BabilinApps

    Joined:
    Dec 28, 2014
    Posts:
    40
    The download links are down. Can someone repost?
     
    Blarp likes this.
  33. Blarp

    Blarp

    Joined:
    May 13, 2014
    Posts:
    270
    weizenhuhn likes this.
  34. SioHio

    SioHio

    Joined:
    Oct 3, 2015
    Posts:
    6
    Can this also be used in non webgl based clients? So if a webgl based client and lets say an Android client want to play together
     
  35. Wisearn

    Wisearn

    Joined:
    Jul 10, 2012
    Posts:
    8
    Edit: Oops, I found a new host that has support for sctp/webrtc ^^

    Problem with the example still though.. nothing happens when I hit connect~ even with a vanilla peerjs running and the same api key on both clients


    also where do I start looking to make the unityproject be able to connect to itself?
     
    Last edited: May 13, 2016
  36. weizenhuhn

    weizenhuhn

    Joined:
    Dec 5, 2016
    Posts:
    7
    This would be exactly what i need, but my network skills are not good enough. I just tried to run this app at the same time on my desktop pc (name = "a") and the android smartphone (name = "b") with the same API Key, but i can't connect "a" to "b".

    Is there some "How to" or a ReadMe or something? Actually I want to send a byte[ ] array from PC to Phone, but I even don't know how to connect to the other device!
     
    Last edited: Jan 19, 2017
  37. hydrix

    hydrix

    Joined:
    Apr 30, 2016
    Posts:
    10
    I was going to write a longpost about this, but I decided it would be better to write it here
    Stop! Think before you use WebRTC + Unity so I can reference this later without creating "duplicate content" on the forums. Basically there are major factors to consider before jumping in to using PeerJS
     
    weizenhuhn likes this.
  38. forestrf

    forestrf

    Joined:
    Aug 28, 2010
    Posts:
    231
    Now the post does not work. What were its contents?
     
    visionnaireMedia likes this.
  39. hydrix

    hydrix

    Joined:
    Apr 30, 2016
    Posts:
    10
    https://web.archive.org/web/20170730015446/http://keywordnerd.com/webrtc-unity

    A year later and I still pretty much agree with this, mostly because developing in node.js horrible. Nowadays I do something like this - a simple net core 2.0 app for matchmaking- then I use the WebRTC plugin on the asset store https://assetstore.unity.com/packages/tools/network/webrtc-network-47846 to connect the games together. I'm working on getting this working as I write this
     
    Last edited: May 7, 2018
    forestrf likes this.
  40. forestrf

    forestrf

    Joined:
    Aug 28, 2010
    Posts:
    231
    After quite a long time I just now was able to implement WebRTC's datachannels in C# (and everything needed, STUN and a subset of SCTP, plus DTLS using Bouncycastle), so now I can communicate with both Firefox and Chrome, but I only implemented one datachannel and unreliable unordered mode.
    I intend to continue working in this, but I want to know: Is someone here interested in this, even more given that this is early in development.
    I am still not focusing on performance as just making this work has taken me quite enough of time, but I have it in mind as I intend to use this myself.
     
  41. Avol

    Avol

    Joined:
    May 27, 2016
    Posts:
    95
    I did manage to create a webgl + node.js game server which uses webrtc for UDP packets. In a sense similar functionality as websockets but use UDP packets through webrtc. This infact allows for UDP packet communication with a game server rather than having 2 clients to have peer to peer connection. Fast passed multiplayer games in browser can be a thing, no matter how hard others try to explain (everything that I googled) that it is not possible. This should be available in some better format, such as a plugin for unity, though nobody has tackled this problem yet, or at least hasn't shared it. Anybody interested:
    node as peer client: https://www.npmjs.com/package/wrtc
    simplified webrtc for browser: https://github.com/feross/simple-peer
     
  42. hydrix

    hydrix

    Joined:
    Apr 30, 2016
    Posts:
    10
    forestrf likes this.
  43. MGronbak

    MGronbak

    Joined:
    Oct 27, 2019
    Posts:
    1
    Hi hydrix,

    I have read your blog post - nice post thanks :0)

    I am currently evalueating Unity3D technology stack with ourpose of creating a WebGL (HTML5) game client that need to be able to communicate with a stand alone DotNet Core 3 application server, listening on WebSocket connection.

    The WebClient, a Firefox Browser activating the resulting WebAssembly generated and provided by an Apache WebServer, seems unable to utilize the WebSocket API from within the WebAssembly and fail to connect to the WebSocket Application Server - if solution is running in an WebAssembly provided by a webserver.

    If the client is run from Unity3D editor or as a stand alone PC Client application the WebSocket seems to work fine and will utilize the Websocket to communicate with the Application server.

    It looks like you did the same thing using the same technologies with success.

    What would I likely be the reason my usage of WebSockets would fail just because it is put into a WebAssembly and executed within this context?

    I am using Unity3D version 2019.2.7f2.

    regards
    MGronbak
     
  44. Thronost

    Thronost

    Joined:
    Nov 25, 2016
    Posts:
    2
    Hi. I'm trying to develop 2 application that have a video/audio chat features between them. But I have a really hard time implementing this.
    On the frontend we have an Angular(7.x.x.) application.
    The backend we have an Asp.net Core 3.1 application.
    And the second application is a Unity application for Android, Windows and now WebGL. WebGL will be our main platform so it it doesn't work for the other platforms is is not (yet) a big problem.

    Communication between Angular and Unity(WebGL) is managed in SignalR. And we hope to get a peer-to-peer connection between unity and angular.
    in angular-to-angular it already works but we can’t find a good tutorial on how to implement this in Unity. Between angular and angular for the webRTC we use the library peer.js. Any help?
    We have already downloaded the above package for unity and we have bought the following link.
    https://assetstore.unity.com/packages/tools/network/webrtc-video-chat-68030


    Any help would really be appreciated!
     
    Last edited: Apr 7, 2020