P2P (peers do not connect outside of the local network) using peerjs broker server

My game at http://144.91.116.148/ElementsOnlineWeb/index.html connects to a broker server that allows discovery using peerjs. It connects peers that are within the same network perfectly and I can play the game. Outside the network it does not want to connect the peers.
I generate a list from http://144.91.116.148:9000/:key/peers and use it to see which peers are connected and connect to them using a lobby type of situation. Once connected they can make a room join and start to play the game. It all works perfectly fine for peers that are within the same network but as soon as I want to play with someone that is not (through the internet)the connection fails to be made. The broker server is started as follow: peerjs -p 9000 --allow_discovery

Do I miss some essentials that need to be installed besides peerjs? I can not seem to discover it doing research myself. I know p2p is experimental in gdevelop but any help is very welcome to solve this critter.

This is my first post on this forum (sorry if I miss some guidelines)

The setup is a four player board game that I came up with a few years ago and always wanted to have an online version of. I have been working with Gdevelop for only 3 weeks now but I am impressed by the rapid development one can make with this awesome game engine. The game is working and I would not have expected it to be so quick to make. WOW.

That is weird because it always worked for me, and I did multiple tests with devices outside of my local network. What you can try is host your own TURN server, like COTURN, and manually initialize the broker server via a javascript event like this:

gdjs.evtTools.p2p.peerConfig = {
    debug: 1,
    host: "broker hostname",
    port: "broker port",
    path: "broker path",
    secure: false,
    key: "",
    config: { 'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' }] }, // Replace with your own server URLs
};
gdjs.evtTools.p2p._loadPeerJS();

Thank you for the quick reply. This is a nice rabbit hole. I installed the COTURN server and entered the java script code instead of the event connect to broker server. I’ve tried all kinds of combinations but it keeps coming back with the error: Could not get ID from server. I even took out the code that does config of the iceservers.

gdjs.evtTools.p2p.peerConfig = {
    debug: 1,
    host: "144.91.116.148",
    port: "9000",
    path: "",
    secure: false,
    key: "",
    
};
gdjs.evtTools.p2p._loadPeerJS();

With the same result. I am not knowledgeable when it comes to Java yet. Should this not simply work the same though as the normal use of the event?:Screenshot%20from%202020-12-17%2016-41-37

I read about the STUN and TURN servers and it seems that it would indeed be probably a solution to this. I feel so close yet… :blush::slightly_smiling_face:

There are two issues I can spot:

  1. All peerjs servers have a key. the default one is “peerjs”.
  2. Not sure why that worked without in the GDevelop event, but you need to put “/” as the path

Corrected config:

{
    debug: 1,
    host: "144.91.116.148",
    port: "9000",
    path: "/",
    secure: false,
    key: "peerjs",
   
}

Thank you. Indeed the key to have the P2P working was literally the key. I even got it running with the stun server I set up as you initially proposed. Unfortunately to no avail. It did not change anything. My mobile on its mobile network can not connect to for example my computer that is on internet through WiFi. As soon as I put WiFi on, on the mobile they do connect. I tried to use turn as well and of course the expected result happened that they can only see themselves (as far as what I understood that is exactly the difference between stun and turn). I guess it can not punch a hole through the NAT somehow.

listenerports

Is the IPv6(peerjs) vs Ipv4(COTURN) maybe a problem (I can hardly believe such)?

This is the code in Gdevelop

I am only allowed to post one picture as new user in this forum but I thought it would be good to add it for the sake of clarity.

Connection problems between your mobile phone (over data plan) and the computer might be relevant to NAT technology used by the mobile phone provider. In that case you are required to have a TURN server publicly accessible to pass the traffic between the mobile phone and your computer through.

It seems that the WebRTC technology requires additional components (STUN, TURN, Broker) to work reliably over different connection methods.

Thank you indeed the turn server seems to be the last resort for these kinds of problems (I understood it incorrectly before)

Using How to set up and configure your own TURN server using Coturn as guide I configured my COTURN server as follow:

In Gdevelop I changed the javacode to:

gdjs.evtTools.p2p.peerConfig = {
debug: 1,
host: “144.91.116.148”,
port: “9000”,
path: “/”,
secure: false,
key: “peerjs”,
config: { ‘iceServers’: [
{
‘urls’: ‘stun:144.91.116.148:3478’
},
{ ‘urls’: ‘turn:144.91.116.148:3478?transport=udp’,
‘credential’: ‘secret’,
‘username’: ‘secret’ },
{
‘urls’: ‘turn:144.91.116.148:3478?transport=tcp’,
‘credential’: ‘secret’,
‘username’: ‘secret’
}]
}, // Replace with your own server URLs

};
gdjs.evtTools.p2p._loadPeerJS();

tls-listening-port=5349 does not seem to open a listening daemon on that port somehow when I look with: sudo lsof -i -P -n | grep LISTEN. writing the javacode with that port on the turn server does not work thus. It does when I use the port 3478 when I test it. But after compiling and installing it on mobile trying to use it through the mobile network it still does not want to connect via the turn server.

Again I am not a Java buff and know little to nothing but would love to have this working. Did I not syntax it correctly? I followed : https://www.baeldung.com/webrtc

Did you also installed the certificates for the TLS?

To be honest, I have no idea why this is happening. Everytime I tested it worked without any additional setup, and I tested again with phone on the mobile network and my PC on my wifi and it worked flawlessly. I wish I could help you but the best I can propose at this point is to ditch p2p and use the MQTT extension released a few days ago. It uses classical server-client architecture but is almost as easy to use as P2P.

Arthuro, do you have details on the MQTT extension? I couldn’t find anything in the Wiki.

It is relatively new, you can find it as a community extension in the “extension gallery”. There is no wiki article for it, but it’s API pretty much self explanatory I think. It is very similar to P2P.

Found it, thank you.

It is too bad because it is the one big hurdle to complete the work. I have found the MQTT extension and will install the mosquitto MQTT broker (or would you advice another?) and see if that will work better. Even though p2p would have my preference. MQTT looked easy enough at first glance but then again all these things do initially :-).

Thank you again for all your help and quick replies. It is very much appreciated.

1 Like

I have setup the Mosquito server and it is running. I tested it using the commands on the server itself ( mosquitto_sub -h localhost -t test for receiving and mosquitto_pub -h localhost -t test -m “hello world” for sending) this works well. Also I can see the listener on port1883. I made a test connection in gdevelop (below)

I can not see it arrive on the server though. I tried many different combinations nothing seemed to make it connect to the broker server. I have a receiver running subscribed to topic Eerste there too and see nothing arrive. How can I test if I am connected to the broker server? Looking at the javascript I assume that this is the correct way to do it but I’m obviously missing something.

Sorry I forgot to precise that due to the web nature of GDevelop, the only supported transport method is Websockets, not tcp sockets. Try putting this in your mosquito config:

listener 8000
protocol websockets

That will make mosquito host a Websockets socket base broker on port 8000

Yes it works. But not with a regular install I had to build the server following Building Mosquitto 1.4 – this is a blog

because web sockets was not supported in the regular install of Mosquitto. Then I configured a listener on port 9001 and protocol web sockets as above and the server connects now and I can sent receive message using the subscription method. I will try to rewrite the game using this method and see if it will work better. I have to yet test it but I can not imagine any connectivity issues will exists as it is now classic client server based architecture (unfortunately)

Thank you for all your support and thinking along with me. I still hope one day I will get the P2P working smoothly as well but for now I can make at least a second version that will be guaranteed to deliver data to the clients.

1 Like

It would be very helpfull if I could subscribe to a topic with a stringvariable that way I can make unique topics for every game that is in play. I thought below should work but I can not receive or sent messages that way it seems. Should it be able to? If not it limits the functionality and have to work around it within the message data it self (which is also possible ofcourse but less neat). Should the VariableString(ID) not be parsed to the javascript as a string automatically?

The MQTT server works great overall as far as I can see thank you for the tip.

:thinking: What are all of your events? How is ID defined? Can you use an external listener to the topic see if it is receiving the message or posting it that causes issues? Any string should work as a topic name, and as long as it is the same the message should go through.

I have external listeners to all topics including the ones that are created using a variable (for example I enter player name : test. I make a listener on the server for test). The behaviorism is very erratic. I have used all QOS types and they all behave the same way. Sometimes messages come through and sometimes they do not. Especially with the topics that are generated with a variable. But also the hard coded topics have this problem it seems. If I for example publish a message three times I have more chance of receiving it once. If I publish it once it most often does not arrive (also not on Qos2 which is the four way handshake that should kind of guarantee it).

If this would work stable it would be a very good way to make the multiplayer board game work but not if I have to hard code everything (everyone receives then each others game data causing congestion).

I guess I am doing something wrong or it is a bug in the engine but I can not figure it out. Been reading about MQTT and as far as I can see the one thing Gdevelop needs in this add-on is the disconnect from server signal (to see which clients have disconnected from the server (maybe use keepalive in a certain way would be a solution, I do not know)

The code below I run gives good results on topic “Lobby” but is erratic on “Room” and very seldom works for the topics generated with the GlobalStringVariable(PlayerName)

Any help is welcome because on MQTT I am really stuck.