My Godot version is 4.3.rc3
I’m very inexperienced with WebRTC, so I’ve created a project file for testing purposes in-order to familiarize myself with it. I’m also using WebSocket for the initial hand-shake process, which fortunately is working correctly
The project consists of 1 scene with a ColorRect as the root node, and 2 Buttons as child nodes, with one button named “Host” and the other “Join”
The script named “Host.gd” is attached to the button named Host, whilst the script named “Join.gd” is attached to the button named Join
The contents of Host.gd
are as follows (it deals with server-sided logic):
extends Button
var rtc_peer := WebRTCMultiplayerPeer.new()
var sock_peer := WebSocketMultiplayerPeer.new()
func _ready() -> void:
set_process(false)
func _on_button_up() -> void:
rtc_peer.create_server()
sock_peer.create_server(1234)
set_process(true)
multiplayer.multiplayer_peer = rtc_peer
multiplayer.peer_connected.connect(rtc_peer_connected)
sock_peer.peer_connected.connect(sock_peer_connected)
func _process(_delta: float) -> void:
sock_peer.poll()
if 0 < sock_peer.get_available_packet_count():
var data: Dictionary = JSON.parse_string(
sock_peer.get_packet().get_string_from_utf8())
match int(data.type):
1:
rtc_peer.get_peer(data.id).connection.set_remote_description(
"offer", data.sdp)
2:
rtc_peer.get_peer(data.id).connection.set_remote_description(
"answer", data.sdp)
func ice_candidate_created(media: String, index: int, Name: String, id: int) -> void:
print("ice candidate created")
send_to_peer(id, {
"type" = 3,
"media" = media,
"index" = index,
"name" = Name})
func rtc_peer_connected(id: int) -> void:
print("%d connected to rtc server" % id)
func send_to_peer(id: int, data: Dictionary) -> void:
sock_peer.get_peer(id).put_packet(JSON.stringify(data).to_utf8_buffer())
func session_description_created(type: String, sdp: String, id: int) -> void:
print("type is %s" % type)
rtc_peer.get_peer(id).connection.set_local_description(type, sdp)
send_to_peer(id, {
"type" = 1 if type == "offer" else 2,
"sdp" = sdp})
func sock_peer_connected(id: int) -> void:
print("%d connected to socket server" % id)
send_to_peer(id, {"type" = 0, "id" = id})
var peer := WebRTCPeerConnection.new()
peer.initialize({
"iceServers" = [{"urls" = ["stun:stun.l.google.com:19302"]}]})
rtc_peer.add_peer(peer, id)
peer.create_offer()
peer.ice_candidate_created.connect(ice_candidate_created.bind(id))
peer.session_description_created.connect(session_description_created.bind(id))
And the contents of Join.gd
are as follows (it deals with client-sided logic):
extends Button
var my_id: int = 0
var rtc_peer := WebRTCMultiplayerPeer.new()
var sock_peer := WebSocketMultiplayerPeer.new()
func _ready() -> void:
set_process(false)
func _on_button_up() -> void:
sock_peer.create_client("ws://localhost:1234")
set_process(true)
func _process(_delta: float) -> void:
sock_peer.poll()
if 0 < sock_peer.get_available_packet_count():
var data: Dictionary = JSON.parse_string(sock_peer.get_packet().get_string_from_utf8())
match int(data.type):
0:
my_id = data.id
print("client - id set to %d" % my_id)
connect_to_rtc_server(my_id)
1:
rtc_peer.get_peer(1).connection.set_remote_description(
"offer", data.sdp)
2:
rtc_peer.get_peer(1).connection.set_remote_description(
"answer", data.sdp)
3:
rtc_peer.get_peer(1).connection.add_ice_candidate(
data.media, data.index, data.name)
func connect_to_rtc_server(id: int) -> void:
rtc_peer.create_client(id)
multiplayer.multiplayer_peer = rtc_peer
var peer := WebRTCPeerConnection.new()
peer.initialize({
"iceServers" = [{"urls" = ["stun:stun.l.google.com:19302"]}]})
rtc_peer.add_peer(peer, 1)
peer.create_offer()
peer.ice_candidate_created.connect(ice_candidate_created)
peer.session_description_created.connect(session_description_created)
func ice_candidate_created(media: String, index: int, Name: String) -> void:
print("client - ice candidate created")
send_to_server({
"type" = 3,
"id" = my_id,
"media" = media,
"index" = index,
"name" = Name})
func send_to_server(data: Dictionary) -> void:
sock_peer.get_peer(1).put_packet(JSON.stringify(data).to_utf8_buffer())
func session_description_created(type: String, sdp: String) -> void:
print("client - type is %s" % type)
rtc_peer.get_peer(1).connection.set_local_description(type, sdp)
send_to_server({
"type" = 1 if type == "offer" else 2,
"id" = my_id,
"sdp" = sdp})
The project file also contains the native WebRTC plugin, and no issues showed up during its import
I’m testing the project using 2 Instances created using the debug menu, and when I click the Host button on one instance, then click Join on the other, the following error occur on the instance where I clicked Join:
And these are the errors that occur on the instance where I clicked Host:
This is the output result:
499800686 connected to socket server
type is offer
ice candidate created
ice candidate created
type is answer
client - id set to 499800686
client - type is offer
client - ice candidate created
client - type is answer
client - ice candidate created
I’m noticing that the ice candidate seems to be created twice, but I’m unsure as to whether it’s expected behavior, or what could be causing it to happen
I’ll also share some information about me since it’s my first post here: I’ve been using Godot for a reasonable while now, but so far sticking with single-player projects, although I’ve gotten the hang of using ENet and WebSockets for multiplayer. I’m enjoying using Godot so far, as well