peers / peerjs

Simple peer-to-peer with WebRTC.
https://peerjs.com
MIT License
12.48k stars 1.43k forks source link

Connection being made but not opened to send data #618

Closed geocontrol closed 2 years ago

geocontrol commented 4 years ago

I have two simple HTML pages

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Peer JS</title>
</head>
<body>
  <h1>QR Code</h1>
  <h2 id="peerid">peer ID</h2>
  <h2 id="message">message</h2>  

<script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script>
<script>
    var peer = new Peer();

    peer.on('open', function (id) {
        console.log('My peer ID is: ' + id);
        document.getElementById("peerid").innerHTML = id;
    });

    peer.on('connection', function (conn) { 
        console.log(conn); 
        conn.on('open', function () {
            ready();
        });
    });

    function ready() {
        console.log('Connection Open');
        // Receive messages
        conn.on('data', function (data) {
            console.log('Received', data);
            document.getElementById("message").innerHTML = data;
        });
    };

</script>
</body>
</html>

and index2.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Peer 2</title>
</head>

<body>
    <h2 id="peerid">peer ID</h2>

    <span style="font-weight: bold">ID: </span>
    <input type="text" id="receiver-id" title="Input the ID from receive.html">
    <button id="connect-button">Connect</button>

    <input type="text" id="sendMessageBox" placeholder="Enter a message..." autofocus="true" />
    <button type="button" id="sendButton">Send</button>
    <button type="button" id="clearMsgsButton">Clear Msgs (Local)</button>

    <h2 id="message">message</h2>

    <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script>
    <script type="text/javascript">
        (function () {

            var lastPeerId = null;
            var peer = null; // own peer object
            var conn = null;
            var recvIdInput = document.getElementById("receiver-id");
            var status = document.getElementById("status");
            var message = document.getElementById("message");
            var connectButton = document.getElementById("connect-button");
            var sendMessageBox = document.getElementById("sendMessageBox");
            var sendButton = document.getElementById("sendButton");
            var clearMsgsButton = document.getElementById("clearMsgsButton");
            /**
             * Create the Peer object for our end of the connection.
             *
             * Sets up callbacks that handle any events related to our
             * peer object.
             */
            function initialize() {
                // Create own peer object with connection to shared PeerJS server
                peer = new Peer(null, {
                    debug: 2
                });

                peer.on('open', function (id) {
                    // Workaround for peer.reconnect deleting previous id
                    if (peer.id === null) {
                        console.log('Received null id from peer open');
                        peer.id = lastPeerId;
                    } else {
                        lastPeerId = peer.id;
                    }

                    console.log('ID: ' + peer.id);
                });
                peer.on('disconnected', function () {
                    status.innerHTML = "Connection lost. Please reconnect";
                    console.log('Connection lost. Please reconnect');

                    // Workaround for peer.reconnect deleting previous id
                    peer.id = lastPeerId;
                    peer._lastServerId = lastPeerId;
                    peer.reconnect();
                });
                peer.on('close', function () {
                    conn = null;
                    status.innerHTML = "Connection destroyed. Please refresh";
                    console.log('Connection destroyed');
                });
                peer.on('error', function (err) {
                    console.log(err);
                    alert('' + err);
                });
            };

            /**
             * Create the connection between the two Peers.
             *
             * Sets up callbacks that handle any events related to the
             * connection and data received on it.
             */
            function join() {
                // Close old connection
                if (conn) {
                    conn.close();
                }

                // Create connection to destination peer specified in the input field
                conn = peer.connect(recvIdInput.value, {
                    reliable: true
                });

                conn.on('open', function () {
                    //status.innerHTML = "Connected to: " + conn.peer;
                    console.log("Connected to: " + conn.peer);

                    // Check URL params for comamnds that should be sent immediately
                    var command = getUrlParam("command");
                    if (command)
                        conn.send(command);
                });
                // Handle incoming data (messages only since this is the signal sender)
                conn.on('data', function (data) {
                    addMessage("<span class=\"peerMsg\">Peer:</span> " + data);
                });
                conn.on('close', function () {
                    //status.innerHTML = "Connection closed";
                });
                conn.on('error', function (err) {
                    console.log("ERROR ERROR");
                    console.log(err);
                });
            };

            /**
             * Get first "GET style" parameter from href.
             * This enables delivering an initial command upon page load.
             *
             * Would have been easier to use location.hash.
             */
            function getUrlParam(name) {
                name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
                var regexS = "[\\?&]" + name + "=([^&#]*)";
                var regex = new RegExp(regexS);
                var results = regex.exec(window.location.href);
                if (results == null)
                    return null;
                else
                    return results[1];
            };

            // Listen for enter in message box
            sendMessageBox.onkeypress = function (e) {
                var event = e || window.event;
                var char = event.which || event.keyCode;
                if (char == '13')
                    sendButton.click();
            };
            // Send message
            sendButton.onclick = function () {
                console.log('Send Button Clicked');
                if (conn.open) {
                    var msg = sendMessageBox.value;
                    sendMessageBox.value = "";
                    conn.send(msg);
                    console.log("Sent: " + msg);
                    addMessage("<span class=\"selfMsg\">Self: </span> " + msg);
                } else {
                    console.log('Problem opening the connection stream');
                    console.log(conn);
                }
            };
            // Clear messages box
            clearMsgsButton.onclick = function () {
                clearMessages();
            };
            // Start peer connection on click
            connectButton.addEventListener('click', join);

            // Since all our callbacks are setup, start the process of obtaining an ID
            initialize();
        })();
    </script>
</body>

</html>

Both connect using your peer server, but no connection is actually opened, so no data can be sent.

The use case I have is:

User A and User B both most likely on a phone, using our app. User A will show a QR Code, which User B will scan (both from within the app). This will create a p2p connection between the two apps, allowing both to send a couple of messages (its storing a I met this person and digitally signed their account' type stuff, so its recording a two way connection between the two actors, with the consent / initiating of storing triggered once the p2p connection has been made.

I tried running the https://github.com/jmcker/Peer-to-Peer-Cue-System application and it appears to show the same behaviour (i used some of the code in index2.html, trying to work out if i was triggering things too quickly).

The pages are being run in Chrome (Mac) Version 79.0.3945.117 (Official Build) (64-bit) and also Firefox (Mac) 72.0.1 (64-bit)

Any thoughts?

Subcode commented 4 years ago

I'm having the same issue with the Peer-to-Peer-Cue-System application. I've also tried a lot of the examples and cant get it to work, the receiver seems to connect to the sender and the connection open event gets called, but it doesn't seem to be getting called for the sender. And when i output the connection from inside the connection open event of the receiver it says its not open.

geocontrol commented 4 years ago

I have started to look at implementing what I need to do in libp2p as it feels like there are issues with this library that I am not able to fix / work around. :-/

Subcode commented 4 years ago

I've just retried and everything seems to work. The peer.min.js in Peer-to-Peer-Cue-System is an old version, updating that to the latest one worked for me.

afrokick commented 4 years ago

Seems like a NAT issue