I have simple web app,
Client1 logs in and socket connections is made to signal.php
Client2 logs in and socket connections is made to signal.php again
Client2 sends offer to client1 via signal.php
client1 sends answe to client2
ice candidiates are exchanged
So this works fine when the remote system's windows firewall is Off but when the firewall is On the ice connection fails after ice candidates are gathered.
I am using xirsys Turn/Stun servers. I have tried to find a way to find a way to make sure my app runs even if firewall is On. I have seen other webrtc example which do no get blocked by firewall. What am I missing here ?????
UPDATE
Did some more testing with following results
Does not matter if Firewall is On or Off on the client making connection. If the Firwall is On who is getting the Offer the connections fails
Example: Consider client 1 is making the offer and client 2 is receiving the offer. If client 2 has firwall On, the connection fails. If firewall is Off the connection is etablished. Does not matter if client 1 has its firewall On or Off. If client 1 and 2 or on same computer, the connections is always sucessful.
You need to compare the types of TURN servers used by your app which does not work with the ones that work. chrome://webrtc-internals shows the servers.
do you use TURN/TCP and TURN/TLS?
on which ports do the the TURN servers run?
for the working service, what kind of connection is used (see here for how to determine this)
And there are cases where the connection will fail. Your UX needs to deal with those too.
Related
For a mostly offline browser game I'm researching the possibility to run a WebRTC signalling server from a browser.
I can imagine that security-wise it's a big no-no to open a port and serve connections from a browser (or service worker), but I cannot* find any information on this.
Q. Can Chrome, Firefox (or perhaps any other major browser) open a network port and serve connections using javascript? Or is this fundamentally disallowed by browser design?
*) For sake of completeness, I did find one option (maybe), but it's overly complex, and therefore isn't very appealing. There is a javascript package called filerjs, which allows for a posix-like filesytem in the browser, I think using indexedb, that would allow for a nodejs installation in the browser. I did not further investigate it, so no idea if it actually works, and if a connection could be served this way.
I don't think that you can run a signaling server in the browser. But you say "mostly offline", does that mean that the peers are connected to the internet, but playing from the same LAN? Or are they completely offline? Here are a few ideas:
Signaling server on the web
Even if the signaling server is running on the web, chances are that WebRTC will connect directly through the LAN (to be tested, and it may depend on how the browser selects the ICE candidates).
Manual signaling
Now, the signaling server is only there to exchange SDP messages. So you could theoretically copy-paste the offer and answer (or copy it manually, or scan it with a QR code). It may not be practical, but for instance you could try hardcoding the SDP offer/answer. The two players would need to exchange information somehow, though:
The ICE candidates (those are IPs) that you would need to create the SDP message
The SDP type (one has to be the offer, the other has to be the answer)
I never tried it, but maybe your UI could tell the player "Please share the following IPs to the other player, and enter their IPs below. Also select if you are the offerer or the answerer". But you see that it seems a bit convoluted...
Signaling server in the LAN
If the peers are completely offline and the manual signaling is too convoluted, my next idea would be to run the signaling server in the LAN, and have the peers connect to it. You could even make it such that your game first tries to contact your signaling server on the Internet, and if it fails (because it is offline), it could fallback and try to contact the one in the LAN (maybe it would need to ask the user for the IP of the signaling server, then).
I was under the impression that WebRTC goes to great lengths to achieve P2P connectivity despite NATs. [1][2] That's why I was surprised to learn that WebRTC fails to connect peers in some situations where a P2P connection is easy to achieve. I would like to understand why this happens, and if there is anything I can do to improve the situation.
Why do I claim that P2P is easy to achieve in some of these situations? I claim this because I have set up an experiment with 2 devices on different networks:
Device F is connected to the internet behind Full-cone NAT
Device S is connected to the internet behind Symmetric NAT
I can easily achieve a P2P connection between these devices in the following manner:
Device F binds a connection to a random (unpredictable) port and sends a UDP packet through that port to anywhere on the internet. Because F is behind Full-cone NAT, this packet has "hole-punched" the port open, allowing any external addresses to now send packets through that port. In my case the port that I opened locally appears to be the same as the external port. (If the external port was different from the local port, we could use something like STUN to figure out the external port.)
Device S binds a connection to a random (unpredictable) port and sends a UDP packet through that port to the external IP and port of Device F. This packet can be delivered, because the port was hole-punched open in step 1. After this packet, Device S has hole-punched through its own port, allowing packets from Device F to be sent back through it. Device F will know where to send the packets, because the packet that S sent contains the external IP and port. Because Device S has Symmetric NAT, the hole-punching didn't open the port for all traffic, only for traffic from Device F (the external IP and port of Device F).
I used Python to verify that I am able to open a P2P connection between these devices and send messages in both directions, as described above. I don't understand why WebRTC is unable to achieve a P2P connection like this.
Why do I claim that WebRTC fails to connect in some of these situations where a connection should be easy? I claim this because I tried to achieve a WebRTC P2P connection with 3 different code examples. All of the examples worked when devices were in the same local network, but didn't work when the devices were in different networks (the setup described above). None of the libraries I tried provided any useful debugging information to figure out what went wrong, and chrome://webrtc-internals didn't provide any useful information either. I also tried in Firefox to verify that this issue is not implementation-specific.
To be specific, I tried the following code examples:
simple-peer, a WebRTC library. I tried the first example code in the README.
PeerJS, another WebRTC library. I tried the demo page they have set up.
A code snippet from a Stackoverflow answer. [3]
In all 3 experiments I also tried to switch which device initiates the connection and which device receives it.
Since this issue isn't specific to WebRTC implementation, and it isn't specific to any particular WebRTC JavaScript library, I'm beginning to suspect that the spec for WebRTC is broken in some fundamental way, preventing WebRTC from achieving P2P connections in situations where they would be easy to achieve. Am I missing something here?
[1] https://webrtc.org/getting-started/turn-server states: "For most WebRTC applications to function a server is required for relaying the traffic between peers, since a direct socket is often not possible between the clients". This gives the impression that WebRTC should be able to achieve a P2P connection in a scenario where it is easy to achieve.
[2] https://webrtcforthecurious.com/docs/03-connecting/ states: "WebRTC will gather all the information it can and will go to great lengths to achieve bi-directional communication between two WebRTC Agents." This also gives the impression that WebRTC should be able to achieve a P2P connection in a scenario where it is easy to achieve.
[3] WebRTC datachannel with manual signaling, example please?
I want to have two different computers open a static html page, and be able to communicate to each other via WebRTC over a local area network. There is no internet connection to the outside world in this scenario. One of the pcs would be able to enter the ip address of the other pc manually and connect to it using that hardcoded IP. Is an ICE server necessary? If so, does the server itself need internet access to the outside world?
You do not need ICE servers in this case. In general, you have the following ICE candidates normally:
host (are generated by the client by binding to its locally assigned IP addresses and port)
srflx (server reflex candidates are generated by using STUN)
relay (relay candidates are generated by using TURN)
So without ICE servers you will have only host candidates generated which is enough in your case because both users are in the same local network.
Although WebRTC enables peer-to-peer communication, it still needs a server for signaling: to enable the exchange of media and network metadata to bootstrap a peer connection.
So the main problem here is that you need to exchange the “offer” and “answer” between endpoints somehow, so each party will have enough information about each other. Normally, some signaling protocol + public server is used for this purpose.
In your case, you have 3 choices:
to setup a direct p2p WebSocket connection between 2 browsers. Not sure if it's possible. Looks like a browser can only connect to other endpoint, not to listen.
manually copy\past the 'offer' and 'answer' SDP, which is not good as well I think
have some 3rd computer with some signaling server installed, so others peers will use it to exchange the 'offer' and 'answer' between each other
I am working on a way to force the game Alien vs. Predator 2 to connect to specific IP address. The reason is, that quite often the server is reachable, but the UDP broadcast the game sends to discover it do not reach the server.
On localhost, this kind of discovery always works. So what I thought I could do is a simple console application that will listen on UDP broadcast from the game and reply. The reply needs to look like it came from the real server's IP, not localhost.
I figure that with no ISP/firewalls involved, this should be much simpler.
I read Node.JS UDP dgrams documentation. It says how to specify target address and port for a message, but it seems to rely on OS' behavior for filling up the source IP and port.
Is there another way?
You can try adding a line to your operating system host file:
127.0.0.1 **the_original_game_server_ip**
This will redirect all traffic to localhost instead of the game server.
Now just create a console application that listens to the game server port.
I'm using Openfire as XMPP server and I added the websocket plugin to it in order to improve some chat features (i.e. file transfer).
Communication via xmpp among my web clients works fine but there is an issue on client network disconnections or changes.
In fact in those cases disconnected clients still remain online in the server, even if a timeout in the idle connection policy is set.
No ping is sent to the clients, so openfire never checks if client connections are active or not.
I've seen that an issue is still open: https://igniterealtime.org/issues/browse/OF-963
Is there a workaround to avoid disconnected clients remaining online on Openfire server with websockets?
I use older version, exactly 4.0.2 I think for my Openfire installation as this BUG is not fixed yet.
This is the reason why messages are sent from another client and lost, cause first client appear as online and in reality it is not regardless the time interval you set in Openfire config after which it will disconnect clients.