WebRTC Data Channel is always in connecting state

26 Views Asked by At

I am trying to send JSON/Text data through a peer connection using WEBRTC. But my datachannel is always stuck in the connecting state and I think that is an issue cause my text messages are not sent to the connected peer.

JS CODE (Client Side):

 let ws;
        let rtcPeerConnection;
        let dataChannel;

        const chatBox = document.getElementById('chatBox');
        const messageInput = document.getElementById('messageInput');
        const sendButton = document.getElementById('sendButton');

        sendButton.onclick = sendMessage;

        function sendMessage() {
            const message = messageInput.value;
            if (message.trim() !== '') {
                chatBox.value += `You: ${message}\n`;
                sendData(message);
                messageInput.value = '';
            }
        }

        function receiveMessage(message) {
            chatBox.value += `Peer: ${message}\n`;
        }

        function sendData(data) {
            console.log(dataChannel.readyState) //this always logs connecting
            if (dataChannel && dataChannel.readyState === 'open') {
                dataChannel.send(data);
            }
        }

        function init() {
            ws = new WebSocket('ws://localhost:3000');
            ws.onmessage = event => receiveMessage(event.data);

            rtcPeerConnection = new RTCPeerConnection();
            rtcPeerConnection.ondatachannel = event => {
                dataChannel = event.channel;
                dataChannel.onmessage = event => receiveMessage(event.data);
            };

            const dataChannelOptions = { ordered: true };
            dataChannel = rtcPeerConnection.createDataChannel('textChat', dataChannelOptions);

            rtcPeerConnection.createOffer()
                .then(offer => rtcPeerConnection.setLocalDescription(offer))
                .then(() => {
                    ws.send(JSON.stringify({
                        type: 'offer',
                        data: rtcPeerConnection.localDescription
                    }));
                })
                .catch(error => console.error('Error creating offer:', error));

            ws.onmessage = async event => {
                const message = JSON.parse(event.data.toString());
                if (message.type === 'answer') {
                    await rtcPeerConnection.setRemoteDescription(message.data);
                } else if (message.type === 'offer') {
                    await rtcPeerConnection.setRemoteDescription(message.data);
                    const answer = await rtcPeerConnection.createAnswer();
                    await rtcPeerConnection.setLocalDescription(answer);
                    ws.send(JSON.stringify({
                        type: 'answer',
                        data: rtcPeerConnection.localDescription
                    }));
                }
            };
        }

        init();

For the Signaling Server I am using Node Js Websockets below is the basic code for the server.

const http = require('http');
const fs = require('fs');
const WebSocket = require('ws');

const server = http.createServer((req, res) => {
    fs.readFile('index.html', 'utf8', (err, data) => {
        if (err) {
            res.writeHead(500);
            return res.end('Error loading index.html');
        }
        res.writeHead(200);
        res.end(data);
    });
});

const wss = new WebSocket.Server({ server });

wss.on('connection', ws => {
    ws.on('message', message => {
        wss.clients.forEach(client => {
            if (client !== ws && client.readyState === WebSocket.OPEN) {
                client.send(message.toString());
            }
        });
    });
});

server.listen(3000, () => {
    console.log('Server running on http://localhost:3000');
});

I am not sure where is the issue in my code. please assist me.

1

There are 1 best solutions below

1
Philipp Hancke On

You are not exchanging ICE candidates, i.e. IP addresses where the peers can connect. See the webrtc sample and look for the onicecandidate handler and the addIceCandidate calls.