3 ms·
Ask HN: HTTP P2P?
Is it possible to have a Javascript game running in a web browser that somehow allows networked play without going through a central server? How about with web sockets and TCP hole punching (obviously this would need a server for initial setup)?
Has anyone heard of any work in this area? Am I missing something obvious, simpler and easier? Thanks.
- IgorPartola 15y agoYou need a server. JavaScript does not have access to the necessary sys calls to open sockets or perform IO. This could be possible with browser support, but I doubt browsers would want to support such features since they could be abused really badly. AFAIK Opera bundles a web server to allow for some kind of file sharing, but it seems unlikely you would be able to use it for your purpose.
- andrewcooke 15y agoThanks, but why wouldn't web sockets work with TCP hole punching? [http://www.acooke.org/cute/WhatisTCPh1.html http://www.acooke.org/cute/WhatisTCPh1.html - self link, but used to be a reasonable Quora post] Is it just that no-one has done this yet? I don't see an obvious technical reason.
- IgorPartola 15y agoDoes web sockets actually allow you to bind() and listen()? I do not believe so. Will take a look at your link in a bit.
- andrewcooke 15y agoTCP hole punching avoids the need to bind and listen. You arrange things (thanks to some looseness in the TCP spec, with the help of a central server) so that two "outgoing" connections talk to each other. It's how Skype manages to make incoming connections to computers, for example, even though they are behind NAT (firewalls and modems). [edit: for some reason I can't reply to your reply below, but you are misunderstanding how hole punching works. They do not listen - that (avoiding listening) is pretty much the whole reason why hole punching is needed/used. But the latter point about complexity is probably valid.]
- IgorPartola 15y agoAccording to [1], section 4.2: > From the same local TCP ports that $A$ and $B$ used to register with $S$, $A$ and $B$ each asynchronously make outgoing connection attempts to the other's public and private endpoints as reported by $S$, while simultaneously listening for incoming connections on their respective local TCP ports. This makes it sound like both hosts have to listen for incoming connections: there is no way to hijack a TCP session and redirect it to a different host on the fly (aside from some very special circumstances where you have set up anycast and TCP session sharing, which you wouldn't be able to do in a network you do not fully control). Also, AFAI remember, the WebSockets API is a step above TCP: you ask the browser to make a connection to endpoint S, and it negotiates the connection by asking the server if it supports not just TCP, but WebSockets and from where, etc. Thus the example from [1] would get much more complicated: you now have to make sure the browser not only performs the normal WebSocket setup, but then makes a new connection to a different server, while simultaneously listening for an incoming connection: not something, I believe, a part of the WebSockets spec. [1] http://www.brynosaurus.com/pub/net/p2pnat/ http://www.brynosaurus.com/pub/net/p2pnat/
- huhtenberg 15y ago> TCP hole punching avoids the need to bind and listen You still need a bind. This greatly improves the chances of symmetrical TCP open actually going through as planned. Also, you will need a central server to coordinate the setup, because, again, this further increases the precision of hole punching.
- andrewcooke 15y agook, since there's little in the way of useful responses, here are some results i've found since asking. first, there's a draft standard for arranging p2p connections with tcp hole punching (STUNT or STUN for TCP) - http://tools.ietf.org/html/draft-ietf-mmusic-ice-tcp-16 http://tools.ietf.org/html/draft-ietf-mmusic-ice-tcp-16 second, there's a draft standard for sip over websockets (sip is a protocol used to arrange a connection between two peers) - http://tools.ietf.org/html/draft-ibc-sipcore-sip-websocket-00 http://tools.ietf.org/html/draft-ibc-sipcore-sip-websocket-0... these almost overlap, but there's an annoying gap, which is that i can still find no way to connect websockets to tcp. so you could use sip to negotiate a circuit, and you could use ice to close the circuit using tcp, but not (afaict) with websockets. furthermore, because of how websockets seems to be implemented (it's kind of multiplexed in to http, as far as i can tell) it seems like it would be hard to close this gap.
- andrewcooke 15y agoThis is so late I doubt anyone will see it, but I finally have an answer, thanks to Saul Ibarra Corretge. The missing link is WebRTC - http://www.webrtc.org/ http://www.webrtc.org/ You can set up a connection using SIP (see above) and then WebRTC will provide a Javascript API for making the connection between peers (and the WebRTC docs include various references to ICE which makes me suspect they will work correctly behind NAT etc). So it's possible with experimental Google APIs today ("Latest Google Chrome (dev channel) comes with WebRTC support" - Saul).
- huhtenberg 15y agoFWIW, I managed to get two clients, each behind its own HTTP proxy, connect to each other using symmetrical TCP open. Not browsers, and with the help of a coordinating server, but the clients did end up with a direct connection between themselves. People tend to think it is hard, because no one does it, and no one does it, because everyone thinks it's hard. Catch 22. Just try it, damn it. It's trivial :)
- mike-cardwell 15y agoA signed Java applet which has asked the user for permission can bind to local ports and make arbitrary connections to any IP. JavaScript can interact with the Java applet too. I don't know, but the same might be possible with Flash too?
- andrewcooke 15y agoyes, i think this would work. unfortunately, i can't see anything in "pure" javascript that is equivalent: the xmlhttprequest is restricted to the originating ip (and it looks like they are single request/response, but in practice perhaps that could be worked around); websockets have the same restriction (but are bi-directional and multiple message) plus they are implemented on top/inside of the http stream, so don't (uniquely) own a tcp connection. and server-side java libs exist for hole punching. so you could pretty easily implement a java-only solution, called from javascript.