localhost: how to setup XHR-Signaling (connection.openSignalingChannel not getting called)
Asked Answered
B

1

8

I am using RTCMultiConnection v3.4.4

I want to run WebRTC on localhost. I have chosen XHR-Signaling because I want the project to be completely offline. I do not want it to depend on the internet, since everything is on localhost (to be later deployed on LAN)

I have included XHRConnection.js and set connection.setCustomSocketHandler(XHRConnection). I also did the override connection.openSignalingChannel...

However, when I open/start the room, my video shows but the buttons that was disabled by disableInputButtons() still remains disabled. The chat is not working.

I did a console.log at override connection.openSignalingChannel... to confirm if it ever got called, but it does not.

Please help on how to implement XHR-Signaling on localhost.

Thanks.

Code:

File: Audio+Video+TextChat+FileSharing.html

<!-- Demo version: 2017.08.10 -->
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>Audio+Video+TextChat+FileSharing using RTCMultiConnection</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <link rel="shortcut icon" href="./logo.png">
  <link rel="stylesheet" href="./stylesheet.css">
  <script src="./menu.js"></script>
</head>
<body>
  <h1>
    Audio+Video+TextChat+FileSharing using RTCMultiConnection
    <p class="no-mobile">
      Multi-user (many-to-many) video streaming + text chat + file sharing using mesh networking model.
    </p>
  </h1>

  <section class="make-center">
    <input type="text" id="room-id" value="abcdef" autocorrect=off autocapitalize=off size=20>
    <button id="open-room">Open Room</button><button id="join-room">Join Room</button><button id="open-or-join-room">Auto Open Or Join Room</button>

    <br><br>
    <input type="text" id="input-text-chat" placeholder="Enter Text Chat" disabled>
    <button id="share-file" disabled>Share File</button>
    <br><br>
    <button id="btn-leave-room" disabled>Leave/or close the room</button>

    <div id="room-urls" style="text-align: center;display: none;background: #F1EDED;margin: 15px -10px;border: 1px solid rgb(189, 189, 189);border-left: 0;border-right: 0;"></div>

    <div id="chat-container">
        <div id="file-container"></div>
        <div class="chat-output"></div>
    </div>
    <div id="videos-container"></div>
  </section>

<script src="./RTCMultiConnection.min.js"></script>
<script src="./adapter.js"></script>
<script src="./XHRConnection.js"></script>

<!-- custom layout for HTML5 audio/video elements -->
<link rel="stylesheet" href="./getHTMLMediaElement.css">
<script src="./getHTMLMediaElement.js"></script>
<script src="./FileBufferReader.js"></script>
<script>
// ......................................................
// .......................UI Code........................
// ......................................................
document.getElementById('open-room').onclick = function() {
    disableInputButtons();
    connection.open( document.getElementById('room-id').value , function() {
        showRoomURL(connection.sessionid);
        xhr
        (
            'start-broadcast.php' , 
            function( responseText ){ console.log( 'Broadcast started [' + document.getElementById('room-id').value + ']' ) }, 
            JSON.stringify( { name: document.getElementById('room-id').value } )
        );
    });
};

document.getElementById('join-room').onclick = function() {
    disableInputButtons();
    connection.join(document.getElementById('room-id').value);
};

document.getElementById('open-or-join-room').onclick = function() {
    disableInputButtons();
    connection.openOrJoin(document.getElementById('room-id').value, function(isRoomExists, roomid) {
        if (!isRoomExists) {
            showRoomURL(roomid);
        }
    });
};

document.getElementById('btn-leave-room').onclick = function() {
    this.disabled = true;

    if (connection.isInitiator) {
        // use this method if you did NOT set "autoCloseEntireSession===true"
        // for more info: https://github.com/muaz-khan/RTCMultiConnection#closeentiresession
        connection.closeEntireSession(function() {
            document.querySelector('h1').innerHTML = 'Entire session has been closed.';
        });
    } else {
        connection.leave();
    }
};

// ......................................................
// ................FileSharing/TextChat Code.............
// ......................................................

document.getElementById('share-file').onclick = function() {
    var fileSelector = new FileSelector();
    fileSelector.selectSingleFile(function(file) {
        connection.send(file);
    });
};

document.getElementById('input-text-chat').onkeyup = function(e) {
    if (e.keyCode != 13) return;

    // removing trailing/leading whitespace
    this.value = this.value.replace(/^\s+|\s+$/g, '');
    if (!this.value.length) return;

    connection.send(this.value);
    appendDIV(this.value);
    this.value = '';
};

var chatContainer = document.querySelector('.chat-output');

function appendDIV(event) {
    var div = document.createElement('div');
    div.innerHTML = event.data || event;
    chatContainer.insertBefore(div, chatContainer.firstChild);
    div.tabIndex = 0;
    div.focus();

    document.getElementById('input-text-chat').focus();
}


// ......................................................
// ..................RTCMultiConnection Code.............
// ......................................................

var connection = new RTCMultiConnection();
connection.setCustomSocketHandler(XHRConnection);
connection.direction = 'one-way';
// by default, socket.io server is assumed to be deployed on your own URL
// connection.socketURL = '/';
connection.trickleIce = false;

// comment-out below line if you do not have your own socket.io server
// connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';

//connection.socketMessageEvent = 'audio-video-file-chat-demo';
connection.enableLogs = true;
connection.enableFileSharing = true; // by default, it is "false".

// this object is used to store "onmessage" callbacks from "openSignalingChannel handler
var onMessageCallbacks = {};

// this object is used to make sure identical messages are not used multiple times
var messagesReceived = {};

// overriding "openSignalingChannel handler
connection.openSignalingChannel = function (config) {

    console.log( 'called: openSignalingChannel' );
    var channel = config.channel || this.channel;
    onMessageCallbacks[channel] = config.onmessage;

    // let RTCMultiConnection know that server connection is opened!
    if (config.onopen) {
        console.log( 'Calling the config.open object' );
        setTimeout(config.onopen, 1);
    }
    else console.log( 'No config.open object' );

    // returning an object to RTCMultiConnection
    // so it can send data using "send" method
    return {
        send: function (data) {
            data = {
                channel: channel,
                message: data,
                sender: connection.userid
            };

            // posting data to server
            // data is also JSON-ified.
            xhr('xhr-signalhandler-post.php', null, JSON.stringify(data));
        },
        channel: channel
    };
};

connection.session = {
    audio: true,
    video: true,
    data: true
};

connection.sdpConstraints.mandatory = {
    OfferToReceiveAudio: true,
    OfferToReceiveVideo: true
};

connection.videosContainer = document.getElementById('videos-container');
connection.onstream = function(event) {
    var width = parseInt(connection.videosContainer.clientWidth / 2) - 20;
    var mediaElement = getHTMLMediaElement(event.mediaElement, {
        title: event.userid,
        buttons: ['full-screen'],
        width: width,
        showOnMouseEnter: false
    });

    connection.videosContainer.appendChild(mediaElement);

    setTimeout(function() {
        mediaElement.media.play();
    }, 5000);

    mediaElement.id = event.streamid;
};

connection.onstreamended = function(event) {
    var mediaElement = document.getElementById(event.streamid);
    if (mediaElement) {
        mediaElement.parentNode.removeChild(mediaElement);
    }
};

connection.onmessage = appendDIV;
connection.filesContainer = document.getElementById('file-container');

connection.onopen = function() {
    console.log( "com. openend" );
    document.getElementById('share-file').disabled = false;
    document.getElementById('input-text-chat').disabled = false;
    document.getElementById('btn-leave-room').disabled = false;

    document.querySelector('h1').innerHTML = 'You are connected with: ' + connection.getAllParticipants().join(', ');
};

connection.onclose = function() {
    if (connection.getAllParticipants().length) {
        document.querySelector('h1').innerHTML = 'You are still connected with: ' + connection.getAllParticipants().join(', ');
    } else {
        document.querySelector('h1').innerHTML = 'Seems session has been closed or all participants left.';
    }
};

connection.onEntireSessionClosed = function(event) {
    document.getElementById('share-file').disabled = true;
    document.getElementById('input-text-chat').disabled = true;
    document.getElementById('btn-leave-room').disabled = true;

    document.getElementById('open-or-join-room').disabled = false;
    document.getElementById('open-room').disabled = false;
    document.getElementById('join-room').disabled = false;
    document.getElementById('room-id').disabled = false;

    connection.attachStreams.forEach(function(stream) {
        stream.stop();
    });

    // don't display alert for moderator
    if (connection.userid === event.userid) return;
    document.querySelector('h1').innerHTML = 'Entire session has been closed by the moderator: ' + event.userid;
};

connection.onUserIdAlreadyTaken = function(useridAlreadyTaken, yourNewUserId) {
    // seems room is already opened
    connection.join(useridAlreadyTaken);
};

function disableInputButtons() {
    document.getElementById('open-or-join-room').disabled = true;
    document.getElementById('open-room').disabled = true;
    document.getElementById('join-room').disabled = true;
    document.getElementById('room-id').disabled = true;
}

// ......................................................
// ......................Handling Room-ID................
// ......................................................

function showRoomURL(roomid) {
    var roomHashURL = '#' + roomid;
    var roomQueryStringURL = '?roomid=' + roomid;

    var html = '<h2>Unique URL for your room:</h2><br>';

    html += 'Hash URL: <a href="' + roomHashURL + '" target="_blank">' + roomHashURL + '</a>';
    html += '<br>';
    html += 'QueryString URL: <a href="' + roomQueryStringURL + '" target="_blank">' + roomQueryStringURL + '</a>';

    var roomURLsDiv = document.getElementById('room-urls');
    roomURLsDiv.innerHTML = html;

    roomURLsDiv.style.display = 'block';
}

(function() {
    var params = {},
        r = /([^&=]+)=?([^&]*)/g;

    function d(s) {
        return decodeURIComponent(s.replace(/\+/g, ' '));
    }
    var match, search = window.location.search;
    while (match = r.exec(search.substring(1)))
        params[d(match[1])] = d(match[2]);
    window.params = params;
})();

var roomid = '';
if (localStorage.getItem(connection.socketMessageEvent)) {
    roomid = localStorage.getItem(connection.socketMessageEvent);
} else {
    roomid = connection.token();
}
document.getElementById('room-id').value = roomid;
document.getElementById('room-id').onkeyup = function() {
    localStorage.setItem(connection.socketMessageEvent, this.value);
};

var hashString = location.hash.replace('#', '');
if (hashString.length && hashString.indexOf('comment-') == 0) {
    hashString = '';
}

var roomid = params.roomid;
if (!roomid && hashString.length) {
    roomid = hashString;
}

if (roomid && roomid.length) {
    document.getElementById('room-id').value = roomid;
    localStorage.setItem(connection.socketMessageEvent, roomid);

    // auto-join-room
    (function reCheckRoomPresence() {
        connection.checkPresence(roomid, function(isRoomExists) {
            if (isRoomExists) {
                connection.join(roomid);
                return;
            }

            setTimeout(reCheckRoomPresence, 5000);
        });
    })();

    disableInputButtons();
}
</script>

  <footer>
    <small id="send-message"></small>
  </footer>

  <script src="common.js"></script>
</body>
</html>

XHRConnection.js:

function XHRConnection(connection, connectCallback) {

    connection.socket = {
        send: function(data) {
            data = {
                message: data,
                sender: connection.userid
            };

            // posting data to server
            // data is also JSON-ified.
            xhr('xhr-signalhandler-post.php', null, JSON.stringify(data));
        }
    };


    // this object is used to make sure identical messages are not used multiple times
    var messagesReceived = {};

    function repeatedlyCheck() {
        xhr('xhr-signalhandler-get.php', function(data) {
            // if server says nothing; wait.
            if (data == false) return setTimeout(repeatedlyCheck, 400);

            // if already receied same message; skip.
            if (messagesReceived[data.ID]) return setTimeout(repeatedlyCheck, 400);
            messagesReceived[data.ID] = data.Message;

            // "Message" property is JSON-ified in "openSignalingChannel handler
            data = JSON.parse(data.Message);

            if (data.eventName === connection.socketMessageEvent) {
                onMessagesCallback(data.data);
            }

            if (data.eventName === 'presence') {
                data = data.data;
                if (data.userid === connection.userid) return;
                connection.onUserStatusChanged({
                    userid: data.userid,
                    status: data.isOnline === true ? 'online' : 'offline',
                    extra: connection.peers[data.userid] ? connection.peers[data.userid].extra : {}
                });
            }

            // repeatedly check the database
            setTimeout(repeatedlyCheck, 1);
        });
    }

    repeatedlyCheck();

    setTimeout
    (
        function() {

            if (connection.enableLogs) {
                console.info('XHR connection opened');
            }

            connection.socket.emit('presence', {
                userid: connection.userid,
                isOnline: true
            });

            if( connectCallback ) {
                console.log( 'Calling connectCallback...' );
                connectCallback(connection.socket);
                console.log( 'Done' );
            }
        }, 

        2000 
    );

    connection.socket.emit = function(eventName, data, callback) {
        if (eventName === 'changed-uuid') return;
        if (data.message && data.message.shiftedModerationControl) return;

        connection.socket.send({
            eventName: eventName,
            data: data
        });

        if (callback) {
            callback();
        }
    };

    var mPeer = connection.multiPeersHandler;

    function onMessagesCallback(message) {
        if (message.remoteUserId != connection.userid) return;

        if (connection.peers[message.sender] && connection.peers[message.sender].extra != message.extra) {
            connection.peers[message.sender].extra = message.extra;
            connection.onExtraDataUpdated({
                userid: message.sender,
                extra: message.extra
            });
        }

        if (message.message.streamSyncNeeded && connection.peers[message.sender]) {
            var stream = connection.streamEvents[message.message.streamid];
            if (!stream || !stream.stream) {
                return;
            }

            var action = message.message.action;

            if (action === 'ended' || action === 'stream-removed') {
                connection.onstreamended(stream);
                return;
            }

            var type = message.message.type != 'both' ? message.message.type : null;
            stream.stream[action](type);
            return;
        }

        if (message.message === 'connectWithAllParticipants') {
            if (connection.broadcasters.indexOf(message.sender) === -1) {
                connection.broadcasters.push(message.sender);
            }

            mPeer.onNegotiationNeeded({
                allParticipants: connection.getAllParticipants(message.sender)
            }, message.sender);
            return;
        }

        if (message.message === 'removeFromBroadcastersList') {
            if (connection.broadcasters.indexOf(message.sender) !== -1) {
                delete connection.broadcasters[connection.broadcasters.indexOf(message.sender)];
                connection.broadcasters = removeNullEntries(connection.broadcasters);
            }
            return;
        }

        if (message.message === 'dropPeerConnection') {
            connection.deletePeer(message.sender);
            return;
        }

        if (message.message.allParticipants) {
            if (message.message.allParticipants.indexOf(message.sender) === -1) {
                message.message.allParticipants.push(message.sender);
            }

            message.message.allParticipants.forEach(function(participant) {
                mPeer[!connection.peers[participant] ? 'createNewPeer' : 'renegotiatePeer'](participant, {
                    localPeerSdpConstraints: {
                        OfferToReceiveAudio: connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                        OfferToReceiveVideo: connection.sdpConstraints.mandatory.OfferToReceiveVideo
                    },
                    remotePeerSdpConstraints: {
                        OfferToReceiveAudio: connection.session.oneway ? !!connection.session.audio : connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                        OfferToReceiveVideo: connection.session.oneway ? !!connection.session.video || !!connection.session.screen : connection.sdpConstraints.mandatory.OfferToReceiveVideo
                    },
                    isOneWay: !!connection.session.oneway || connection.direction === 'one-way',
                    isDataOnly: isData(connection.session)
                });
            });
            return;
        }

        if (message.message.newParticipant) {
            if (message.message.newParticipant == connection.userid) return;
            if (!!connection.peers[message.message.newParticipant]) return;

            mPeer.createNewPeer(message.message.newParticipant, message.message.userPreferences || {
                localPeerSdpConstraints: {
                    OfferToReceiveAudio: connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                    OfferToReceiveVideo: connection.sdpConstraints.mandatory.OfferToReceiveVideo
                },
                remotePeerSdpConstraints: {
                    OfferToReceiveAudio: connection.session.oneway ? !!connection.session.audio : connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                    OfferToReceiveVideo: connection.session.oneway ? !!connection.session.video || !!connection.session.screen : connection.sdpConstraints.mandatory.OfferToReceiveVideo
                },
                isOneWay: !!connection.session.oneway || connection.direction === 'one-way',
                isDataOnly: isData(connection.session)
            });
            return;
        }

        if (message.message.readyForOffer || message.message.addMeAsBroadcaster) {
            connection.addNewBroadcaster(message.sender);
        }

        if (message.message.newParticipationRequest && message.sender !== connection.userid) {
            if (connection.peers[message.sender]) {
                connection.deletePeer(message.sender);
            }

            var userPreferences = {
                extra: message.extra || {},
                localPeerSdpConstraints: message.message.remotePeerSdpConstraints || {
                    OfferToReceiveAudio: connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                    OfferToReceiveVideo: connection.sdpConstraints.mandatory.OfferToReceiveVideo
                },
                remotePeerSdpConstraints: message.message.localPeerSdpConstraints || {
                    OfferToReceiveAudio: connection.session.oneway ? !!connection.session.audio : connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                    OfferToReceiveVideo: connection.session.oneway ? !!connection.session.video || !!connection.session.screen : connection.sdpConstraints.mandatory.OfferToReceiveVideo
                },
                isOneWay: typeof message.message.isOneWay !== 'undefined' ? message.message.isOneWay : !!connection.session.oneway || connection.direction === 'one-way',
                isDataOnly: typeof message.message.isDataOnly !== 'undefined' ? message.message.isDataOnly : isData(connection.session),
                dontGetRemoteStream: typeof message.message.isOneWay !== 'undefined' ? message.message.isOneWay : !!connection.session.oneway || connection.direction === 'one-way',
                dontAttachLocalStream: !!message.message.dontGetRemoteStream,
                connectionDescription: message,
                successCallback: function() {
                    // if its oneway----- todo: THIS SEEMS NOT IMPORTANT.
                    if (typeof message.message.isOneWay !== 'undefined' ? message.message.isOneWay : !!connection.session.oneway || connection.direction === 'one-way') {
                        connection.addNewBroadcaster(message.sender, userPreferences);
                    }

                    if (!!connection.session.oneway || connection.direction === 'one-way' || isData(connection.session)) {
                        connection.addNewBroadcaster(message.sender, userPreferences);
                    }
                }
            };

            connection.onNewParticipant(message.sender, userPreferences);
            return;
        }

        if (message.message.shiftedModerationControl) {
            connection.onShiftedModerationControl(message.sender, message.message.broadcasters);
            return;
        }

        if (message.message.changedUUID) {
            if (connection.peers[message.message.oldUUID]) {
                connection.peers[message.message.newUUID] = connection.peers[message.message.oldUUID];
                delete connection.peers[message.message.oldUUID];
            }
        }

        if (message.message.userLeft) {
            mPeer.onUserLeft(message.sender);

            if (!!message.message.autoCloseEntireSession) {
                connection.leave();
            }

            return;
        }

        mPeer.addNegotiatedMessage(message.message, message.sender);
    }

    window.addEventListener('beforeunload', function() {
        connection.socket.emit('presence', {
            userid: connection.userid,
            isOnline: false
        });
    }, false);
}


// a simple function to make XMLHttpRequests
function xhr( url, callback, data ) {

    // if( data ) console.log('[' + url + '] sending: ' + JSON.stringify( data ) );

    if (!window.XMLHttpRequest || !window.JSON){
        console.log( 'No JSON and/or XMLHttpRequest support' );
        return;
    }

    var request = new XMLHttpRequest();
    request.onreadystatechange = function() {
        if (callback && request.readyState == 4 && request.status == 200) {
            // server MUST return JSON text

            if( request.responseText != 'false' )
                console.log('Logging non-false data [from ' + url + ']: ' + request.responseText + "[...data POST'ed: " + JSON.stringify( data ) + "]" );

            callback(JSON.parse(request.responseText));
        }
    };

    request.open( 'POST', url );
    var formData = new FormData();

    // you're passing "message" parameter
    formData.append( 'message', data );
    request.send(formData);
}

start-broadcast.php:

<?php
require( "connection.inc.php" );

if( isset( $_POST['message'] ) )
{
    $data = json_decode( $_POST['message'] , true );
    // Now, if someone initiates WebRTC session; you should make an XHR request to create a record in the room-table; and 
    // set "Owner-id" equals to that user's "user-id".

    //{"message":{"eventName":"presence","data":{"userid":"winey","isOnline":true}},"sender":"winey"}

    $query = " INSERT INTO active_broadcasts ( name ) VALUES ( '{$data['name']}' ) ";

    if( $mysqli->query( $query ) )
    {
        $transport = json_encode( false );
        exit( $transport );
    }
    else
        exit( $mysqli->error );
}
else
    exit( 'No data sent' );
?>

xhr-signalhandler-post.php:

<?php
require( "connection.inc.php" );

$response = array();

//{"message":{"eventName":"presence","data":{"userid":"winey","isOnline":true}},"sender":"winey"}

// var_dump( $_POST );
// exit;

if( isset( $_POST['message'] ) )
{
    $query = " INSERT INTO webrtc-messages ( name ) VALUES ( '{$_POST['name']}' ) ";

    if( $mysqli->query( $query ) )
    {
        $transport = json_encode( false );
        exit( $transport );
    }
    else
        exit( $mysqli->error );

    // Now, if someone else joins the room; you can update above record; and append his "user-id" in the "Participants-id" column.
}


if( @$_POST["message"] = "undefined" )
    $response = false;

$transport = json_encode( $response );
exit( $transport );

?>

xhr-signalhandler-get.php:

<?php
require( "connection.inc.php" );
$response = array();

// var_dump( $_POST );

if( isset( $_POST['message'] ) )
{
    $query = "SELECT id , message , channel , `sender-id` FROM `webrtc-messages` ";

    if( $mysqli->connect_errno )
        exit ( "Failed to connect to MySQL: " . $mysqli->connect_error );

    if( $res = $mysqli->query( $query ) )
    {
        if( $res->num_rows > 0 )
        {
            while( $value = mysqli_fetch_assoc( $res ) )
            {   
                //
            }
        }
    }
    else
    {
        echo "<center class='text-danger'>Server error</center>";
        exit( $mysqli->error );
    }
}

if( @$_POST["message"] = "undefined" )
    $response = false;

$transport = json_encode( $response );
exit( $transport );
?>
Buttonwood answered 14/8, 2017 at 0:47 Comment(6)
Did you test this demo? (using SSE over PHP i.e. server sent events): rtcmulticonnection.herokuapp.com/demos/SSEConnection.htmlDerivation
@MuazKhan two things needs clarification in the link you provided. 1. Can I use this SSEConnection with the RTCMultiConnection project? (I mean to use it as the signaling server for RTCMultiConnection.js, even as it is localhost) 2. In the source-code you posted for https://github.com/muaz-khan/RTCMultiConnection/tree/master/demos/SSEConnection, you said replace sseDirPath with sseDirPath='php-server.com/SSEConnection'. Does this not violate the requirement that this project is on localhost, because I believe the domain will need to resolve to the internet?Buttonwood
SSEConnection demo is using version 3 of the RTCMultiConnection.js (i.e. latest version). You can upload HTML-demo file in the same directory of "SSE.php" file; meaning that you don't need to set CORS link. Everything (JS+SSE+HTML) will be served by same directory+domain. (so localhost should run PHP to make it work)Derivation
@MuazKhan but since the value for sseDirPath is an external domain (i.e. php-server.com/SSEConnection/), it means it requires internet at that point, right? Or I just set sseDirPath = null because it is on localhost?Buttonwood
XHR-signaling (your codes above) also requires PHP. XHR means you publish and retries messages from MySQL/PHP. So you always need a PHP script. SSE also requires PHP whether it is on localhost or on a remote server. You can download SSE.php on localhost and set this: sseDirPath=http://localhost:9001/demos/SSEConection/SSE.phpDerivation
@Muaz Khan I have PHP setup on my localhost. Can you please run the 3 scripts I provided above so that you will understand the situation for the XHR-signaling? (start-broadcast.php, xhr-signalhandler-post.php, and xhr-signalhandler-get.php are all PHP scripts that run on my localhost PHP via Ajax, as shown in the code posted above)Buttonwood
P
2

I've never played with WebRTC nor RTCMultiConnection but I think I understand where your problem comes from.

As you're using XHR, there is no direct connection between your client (web browser) and your server. So, there is no way for the server to push information to the client thus, the openSignalingChannel override will never be triggered.

The trick is to call a function on a regular basis to check the server status (aka. long polling).

If you check the documentation of RTCMultiConnection about the openSignalingChannel override ( http://www.rtcmulticonnection.org/docs/openSignalingChannel/#xhr-signaling ), you'll notice the use of repeatedlyCheck();. I think this is the missing piece of your puzzle.

Hope it helps.

Pescara answered 20/8, 2017 at 12:33 Comment(5)
That is what repeatedlyCheck() is doing in the XHRConnection.js file that I posted with the question. I think it is something that has to do with the underlying RTCMultiConnection.js script itself, because that seems to be the only script that has a reference to openSignalingChannel()Buttonwood
@OlowookereEmmanuel indeed, sorry, I didn't pay enought attention to your implementation. I must admit I played a little with your sample, mocking the response of xhr-signalhandler-get.php as I don't have access to the whole project but I didn't succeed in entering openSignalingChannel(). One thing I notice thought is a difference in using onMessageCallbacks, the author creates a property for each channel: onMessageCallbacks[data.channel] but the function body is assigned inside openSignalingChannel() (onMessageCallbacks[channel] = config.onmessage;).Pescara
I really wish this project works. It just seems impossible!Buttonwood
Hey man I am too am stuck with php/sql implementation did you solved it???Mclaurin
No bro. I have suspended work on the concerned project. However, I will advice that you use the GitHub page - contributors seems to have now increased and thus the rate of resolving issues has improved.Buttonwood

© 2022 - 2024 — McMap. All rights reserved.