Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm making a mod for shapez.io, multiplayer, but I have some issues with webRTC.

When I'm running the two clients local they can connect via an external signalling server. So they can talk via a datachannel.

Whem I'm using clients from different networks they don't connect. There is no error, but the offers and answers are send via the signalling server.

I do not understand webRTC very well so I hope some one can help me.

The current github code is online on https://thomasbrants.nl/shapez.io-multiplayer/. Goto to multiplayer -> new game or resume game -> enter wss://thomasbrants.nl:8888 -> you get a uuid Open a new client -> multiplayer -> join -> enter wss://thomasbrants.nl:8888 -> enter uuid

Github: https://github.com/DJ1TJOO/shapez.io/tree/multiplayer

This code generates a uuid and the user can share this. It connects to the signalling server and creates a room with the uuid. Then when createPeer is called it tries to connect to a peer.

this.connectionId = uuidv4();
                // @ts-ignore
                var socket = io(this.host, { transport: ["websocket"] });
                var socketId = undefined;

                var connections = [];
                socket.on("connect", () => {
                    socket.on("id", id => {
                        socketId = id;
                    });
                    socket.emit("createRoom", this.connectionId);

                    //Create peer
                    socket.on("createPeer", async data => {
                        const config = {
                            iceServers: [{
                                urls: "stun:stun.1.google.com:19302",
                            }, ],
                        };
                        const pc = new RTCPeerConnection(config);
                        const dc = pc.createDataChannel("game", {
                            negotiated: true,
                            id: 0,
                        });

                        //Create offer
                        await pc.setLocalDescription(await pc.createOffer());
                        pc.onicecandidate = ({ candidate }) => {
                            if (candidate || pc.signalingState === "stable") return;
                            console.log("Offer send");
                            console.log(pc.signalingState);
                            console.log(pc.getStats);
                            socket.emit("offer", {
                                offer: pc.localDescription.sdp,
                                socketIdReceiver: socketId,
                                socketIdSender: data.socketIdSender,
                                room: data.room,
                            });
                        };

                        //Answer
                        socket.on("answer", data => {
                            if (data.socketIdReceiver !== socketId || pc.signalingState === "stable") return;
                            pc.setRemoteDescription({
                                type: "answer",
                                sdp: data.answer,
                            });
                            console.log("Answer received");
                            console.log(pc.signalingState);
                            console.log(pc.getStats());

                            var onOpen = event => {
                                //not empty but not related
                            };

                            var onMessage = ev => {
                                //not empty but not related
                            };

                            dc.onopen = onOpen;
                            dc.onmessage = onMessage;
                            onOpen();

                            pc.ondatachannel = event => {
                                let receiveChannel = event.channel;
                                receiveChannel.onmessage = onMessage;
                                receiveChannel.onopen = onOpen;
                            };
                            connections.push({ pc: pc, dc: dc });
                        });
                    });
                });

Here the uuid is put in and then it connects to the signalling server. And tries to make a connection.

// @ts-ignore
                var socket = io(host, { transport: ["websocket"] });
                var socketId = undefined;
                socket.on("connect", () => {
                    console.log("Connected to the signalling server");
                    socket.on("id", id => {
                        socketId = id;
                        console.log("Got id: " + id);
                        socket.emit("joinRoom", connectionId, socketId);
                    });
                    socket.on("error", () => {
                        this.dialogs.showWarning(
                            T.dialogs.multiplayerGameError.title,
                            T.dialogs.multiplayerGameError.desc + "<br><br>"
                        );
                    });
                    socket.on("offer", async data => {
                        if (data.socketIdSender !== socketId) return;
                        console.log("offer received");
                        const config = {
                            iceServers: [
                                {
                                    urls: "stun:stun.1.google.com:19302",
                                },
                            ],
                        };
                        const pc = new RTCPeerConnection(config);
                        const dc = pc.createDataChannel("game", {
                            negotiated: true,
                            id: 0,
                        });
                        await pc.setRemoteDescription({
                            type: "offer",
                            sdp: data.offer,
                        });
                        await pc.setLocalDescription(await pc.createAnswer());
                        pc.onicecandidate = ({ candidate }) => {
                            if (candidate) return;
                            socket.emit("answer", {
                                socketIdReceiver: data.socketIdReceiver,
                                socketIdSender: data.socketIdSender,
                                answer: pc.localDescription.sdp,
                                room: data.room,
                            });
                            console.log("answer send");
                        };

                        var gameDataState = -1;
                        var gameData = "";

                        var onMessage = ev => {
                            //not empty but not related
                        };

                        dc.onmessage = onMessage;
                        pc.ondatachannel = event => {
                            let receiveChannel = event.channel;
                            receiveChannel.onmessage = onMessage;
                        };
                    });
                });

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
177 views
Welcome To Ask or Share your Answers For Others

1 Answer

等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...