godotengine / webrtc-native

The official GDNative WebRTC implementation for non-html exports.
MIT License
210 stars 34 forks source link

RPC calls failing when integrating webrtc-native into bomber-rtc project #23

Closed sjhennion closed 1 year ago

sjhennion commented 3 years ago

In prototyping multiplayer with Godot, I originally had an example working that was based off of the bomberman example codebase doing NAT punchthrough with a rendezvous server using Godot's ENet implementation. However, after doing some research and realizing how naive my implementation was, and not wanting to dive into implementing ICE on top of ENet (just yet), I figured it was worthwhile seeing if WebRTC would serve my purposes.

Using a combination of the godot-example-project's webrtc-signaling example, @Faless 's bomber-rtc example, webrtc-native, and my existing codebase, I went to work of transitioning everything over to WebRTC. For what it's worth, I'm currently testing with 3.2.3-stable, and have four different machines interacting:

The issues I have seem to stem from having more than two peers connecting. I went through a pretty lengthy process of trying different combinations of systems being the "host" (for what that means in the webrtc sense with server_compatibility = true), with and without the non local headless instance to determine if it was an issue with ICE/NAT punchthrough.

The issues I have always seemed to come up when the ICE candidate process had completed, and connected_ok was called from gamestate.gd. I've greatly simplified gamestate, essentially halting it from moving on to the register_player calls, as this was what was failing, occasionally. Instead, after receiving connected_ok, I have each of the "clients" starting a loop of sending rpc calls that just sends a string with ping+n, where n is an incrementing number. What ends up happening is that the other connected clients, as well as the server should receive:

ping+1
ping+2
ping+3
ping+4
ping+5
ping+6
...  

Instead, what happens is that occasionally one of these rpc calls seems to get dropped, and instead of ping+n, I'll just get a blank newline written to the debug log, like this:

ping+1
ping+2
ping+3

ping+5
ping+6
...  

The drops seem random, and just because the drop seems to happen on one receiver (be it another client, or the server), another receiver won't necessarily miss the same call, which leads me to believe there is something happening on the webrtc-native rpc reception side that's causing the miss.

The reason I've narrowed this down to webrtc-native is because last night I went through and generated HTML5 exports on the 3 local machines in order to utilize the same webrtc high level multiplayer code base, but not use webrtc-native, and I have not been able to recreate the issue once. I probably ran ~20 iterations, and was switching back and forth between HTML5 and native export, with the native always failing a few times in sending 25 ping rpc calls following connected_ok.

I understand this is a pretty large wall of text. I certainly can put together a reproducible test if someone else has at least three separate machine that can do HTML5 and native tests, if need be, but I figured it was worthwhile to post my findings and get a conversation going first.

mashumafi commented 2 years ago

I think I was able to produce something identical to this in https://github.com/godotengine/godot-demo-projects/pull/667

Faless commented 1 year ago

The WebRTC multiplayer peer used to behave in a slightly different manner in previous versions of Godot, but the behaviors have been normalized in recent Godot betas (beta4 and newer), and the WebRTC demos have been updated to reflect those changes. See https://github.com/godotengine/webrtc-native/issues/64#issuecomment-1324062854 for more details. The updated demos for 4.0 now also shows how to use RPCs. Closing as fixed.