Godot Version
v4.2.2.stable.mono.official
Question
I am having trouble implementing the minimal setup for WebRTC as specified in the docs using C#.
The problem is that when I call CreateOffer(), SessionDescriptionCreated does not fire.
Here is my C# Code. I just attached this onto a Node on the scene.
using System.Threading.Tasks;
using Godot;
namespace WebRTCTest;
public partial class TestCSharp : Node
{
private WebRtcPeerConnection conn1 = new();
private WebRtcPeerConnection conn2 = new();
WebRtcDataChannel ch1;
WebRtcDataChannel ch2;
public TestCSharp()
{
ch1 = conn1.CreateDataChannel("chat", new() { { "id", 1 }, { "negotiated", true } });
ch2 = conn2.CreateDataChannel("chat", new() { { "id", 1 }, { "negotiated", true } });
}
public override async void _Ready()
{
conn1.SessionDescriptionCreated += (type, sdp) => conn1.SetLocalDescription(type, sdp);
conn1.SessionDescriptionCreated += (type, sdp) => conn2.SetRemoteDescription(type, sdp);
conn1.IceCandidateCreated += (media, index, name) => conn2.AddIceCandidate(media, (int)index, name);
conn2.SessionDescriptionCreated += (type, sdp) => conn2.SetLocalDescription(type, sdp);
conn2.SessionDescriptionCreated += (type, sdp) => conn1.SetRemoteDescription(type, sdp);
conn2.IceCandidateCreated += (media, index, name) => conn1.AddIceCandidate(media, (int)index, name);
conn1.SessionDescriptionCreated += (type, sdp) => GD.Print("c1 desc created");
conn1.SessionDescriptionCreated += (type, sdp) => GD.Print("c1 ice candidate created");
await Task.Delay(1000);
conn1.CreateOffer();
await Task.Delay(1000);
ch1.PutPacket("hello".ToUtf8Buffer());
GD.Print("finished running");
}
}
and the errors in the console (raised by the ch1.PutPacket("hello".ToUtf8Buffer())
line):
NativeCalls.cs:4865 @ int Godot.NativeCalls.godot_icall_1_550(nint, nint, System.Byte[]): DataChannel is closed
NativeCalls.cs:4865 @ int Godot.NativeCalls.godot_icall_1_550(nint, nint, System.Byte[]): Method/function failed. Returning: FAILED
I tried printing out the connection state conn1 and it’s on “New” before I call CreateOffer() but gets stuck on “Connecting” after.
I’m not sure what happened but I remember my code working once and then just breaking after. I tried to implement the same coed in gdscript and the “session description created” signal fires properly.
here is the gdscript I used to test the webrtc:
extends Node
# Create the two peers
var p1 = WebRTCPeerConnection.new()
var p2 = WebRTCPeerConnection.new()
# And a negotiated channel for each each peer
var ch1 = p1.create_data_channel("chat", {"id": 1, "negotiated": true})
var ch2 = p2.create_data_channel("chat", {"id": 1, "negotiated": true})
func _ready():
# Connect P1 session created to itself to set local description.
p1.session_description_created.connect(p1.set_local_description)
p1.session_description_created.connect(_test)
# Connect P1 session and ICE created to p2 set remote description and candidates.
p1.session_description_created.connect(p2.set_remote_description)
p1.ice_candidate_created.connect(p2.add_ice_candidate)
# Same for P2
p2.session_description_created.connect(p2.set_local_description)
p2.session_description_created.connect(p1.set_remote_description)
p2.ice_candidate_created.connect(p1.add_ice_candidate)
# Let P1 create the offer
p1.create_offer()
# Wait a second and send message from P1.
await get_tree().create_timer(2).timeout
ch1.put_packet("Hi from P1".to_utf8_buffer())
# Wait a second and send message from P2.
await get_tree().create_timer(2).timeout
ch2.put_packet("Hi from P2".to_utf8_buffer())
func _test(_type, _sdp):
print("offer created")
func _process(_delta):
# Poll connections
p1.poll()
p2.poll()
# Check for messages
if ch1.get_ready_state() == ch1.STATE_OPEN and ch1.get_available_packet_count() > 0:
print("P1 received: ", ch1.get_packet().get_string_from_utf8())
if ch2.get_ready_state() == ch2.STATE_OPEN and ch2.get_available_packet_count() > 0:
print("P2 received: ", ch2.get_packet().get_string_from_utf8())
and here is the console output:
offer created
P2 received: Hi from P1
P1 received: Hi from P2