Coder Social home page Coder Social logo

Comments (15)

muaz-khan avatar muaz-khan commented on May 23, 2024

Please try following snippets.

Your Nodejs Code

A signaling server simply need to get/subscribe messages and transmit over relevant sockets.

var io = require('socket.io').listen(8888);
io.sockets.on('connection', function (socket) {
    socket.on('message', function (data) {
        socket.broadcast.emit('message', data);
    });
});

RTCMultiConnection Usage

Link two files:

https://cdn.webrtc-experiment.com/RTCMultiConnection.js
https://cdn.webrtc-experiment.com/socket.io.js

Initialize RTCMultiConnection object:

var connection = new RTCMultiConnection('common-channel-id');

Override openSignalingChannel method:

var onMessageCallbacks = {};
var socketio = io.connect('http://localhost:8888/');

socketio.on('message', function(data) {
    if(data.sender == connection.userid) return;

    if (onMessageCallbacks[data.channel]) {
        onMessageCallbacks[data.channel](data.message);
    };
});

connection.openSignalingChannel = function (config) {
    var channel = config.channel || this.channel;
    onMessageCallbacks[channel] = config.onmessage;

    if (config.onopen) setTimeout(config.onopen, 1000);
    return {
        send: function (message) {
            socketio.emit('message', {
                sender: connection.userid,
                channel: channel,
                message: message
            });
        },
        channel: channel
    };
};

Rest of the code:

document.getElementById('openRoom').onclick = function() {
    connection.open();
};
document.getElementById('joinRoom').onclick = function() {
    connection.connect();
};

References

  1. https://github.com/muaz-khan/WebRTC-Experiment/blob/master/Signaling.md
  2. http://www.rtcmulticonnection.org/docs/openSignalingChannel/
  3. https://github.com/muaz-khan/RTCMultiConnection/wiki/Channels-and-Sessions

API References

  1. http://www.rtcmulticonnection.org/docs/constructor/
  2. http://www.rtcmulticonnection.org/docs/open/
  3. http://www.rtcmulticonnection.org/docs/connect/
  4. http://www.rtcmulticonnection.org/docs/channel-id/

Quick Simple Demos:

  1. http://jsfiddle.net/zar6fg60/
  2. http://jsfiddle.net/c46de0L8/

You can use same openSignalingChannel method in all RTCMultiConnection demos.

Why openSignalingChannel?

RTCMultiConnection exposes this method to allow application-developers handle signaling in the ui-level. You can manage how to send/transmit messages and how to pass subscribed messages to RTCMultiConnection handlers.

In the openSignalingChannel method, you simply gets reference to unique-channel. Each channel points unique peer connection object.

WebRTC peer-to-peer model merely allows two-way handshake; which means that we can setup between two peers only. For conferencing, we usually open many 1:1 connections.

So, by using "channel-id" that is passed over openSignalingChannel method, you can handle how to POST/GET messages to RTCMultiConnection client.

// "data.channel" == unique-channel-id for each peer session
// it means that using this random-string, you can manage which message is
// for who....so messages are delivered reliably among different peer sessions

if (onMessageCallbacks[data.channel]) {
    onMessageCallbacks[data.channel](data.message);
};

Actually RTCMultiConnection tries to rely on end-user's signaling medium instead of forcing or using its own signaling implementations. That's why it isn't opening rooms itself.

There is XHR-based signaling demo as well, which explains how XHR POST/GET is integrated with RTCMultiConnection openSignalingChannel method:

A few points are explained in FAQ:

How/When openSignalingChannel is invoked?

On each participant request, both userA and userB opens socket with identical channel-id.

Then userA creates offer and passes over same socket. It means that now you're having offer-sdp in your openSignalingChannel. You need to push that message to server and server need to transmit that message to target connected sockets.

Now, through your openSignalingChannel, RTCMultiConnection will get the offer-sdp. UserB will create answer and same process will happen in reverse order.

Assuming that userA sends a message XXXXX over a socket which is having channel-id 0077.

Now, in your openSignalingChannel code, you'll get send method invoked. E.g.

connection.openSignalingChannel = function (config) {
    return {
        send: function (message) {
            console.error(message); // message === XXXXX
        }
    };
};

Now, assuming that your signaling medium received transmitted message from the server:

socketio.on('message', function(data) {
    // data.message === XXXXX
    // data.channel   === something-unique for each peer session
    console.error(data.channel, data.message);
});

What is peer session?

To connect two WebRTC peers, RTCMutliConnection need to transfer some kind of session messages and candidates among both users.

A peer session is a unique region or area or gateway or medium that allows RTCMultiConnection to reliably share such messages until peers are closed and removed.

Each peer session is given a unique channel-id. It is a random string that is generated on the fly.

A peer session relies on your socket. A socket is a term used for signaling medium.

If there are 5 users connected in a conferencing room, there will be 4 peer sessions opened for each user: https://www.webrtc-experiment.com/docs/RTP-usage.html

When we use term 1:1 connection; RTCMultiConnection names it as a peer-session.

So, for 5 interconnected users there will be 4 one-to-one peer connections opened for each user. All these peers are opened using 4 peer sessions i.e. 4 sockets or 4 signaling channels.

All such complex things are part of RTCMultiConnection because:

  1. We need to reliably share relevant data with relevant users by keeping privacy or attacks in mind.
  2. We need to make sure 10 or more users can connect without interrupting any single message.
  3. We need to hide such complexity from application developer so that he simply need to POST/GET messages instead of worrying about how things are handled and used.

Summary

You can define openSignalingChannel in your HTML page. This method allows you handle how messages are transmitted or received.

from rtcmulticonnection.

Slyb00ts avatar Slyb00ts commented on May 23, 2024

Ive got everything right and its not working, can u share full example code, but not just openSignalingChannel. I dont need any filesharing etc in example, just full code to create a connection beetwen two pc using websockets i was trying everything i can, but still no luck :( websocket server is sending everything in broadcast so it shouldnt be an issue.

from rtcmulticonnection.

crina27 avatar crina27 commented on May 23, 2024

Hi,

I'm trying to create a plugin for a group that allows the group admin to broadcast and the other users are "Anonymous Viewers". I can allow other users to broadcast in the same page using:
connection.addStream({
audio: true,
video: true,
broadcast: true
});
Now I want the admin to be able to close the users broadcast. I tried using this code:
var lastChild = videos.lastChild; //this is the div that contains the video elements
var id=lastChild.id;
connection.leave(id);
but it throws 'You ejected invalid user.' . Can you tell me want am I doing wrong?

Also I noticed that when I'm using one of your demos I don't have to give permission to use my webcam and microphone, but when I save the page in my IIS folder and try to start a broadcast I need to allow the page to use my webcam and microphone. Do I need to change some settings on my IIS or in the code to skip this step?

from rtcmulticonnection.

Yuripetusko avatar Yuripetusko commented on May 23, 2024

@crina27 I think you need to use eject method http://www.rtcmulticonnection.org/docs/eject/

you can get userId in connection.onstream event, just store all stream objects in an array, and then eject one using appropriate userid.

from rtcmulticonnection.

muaz-khan avatar muaz-khan commented on May 23, 2024

@crina27 You may tried demos with SSL-based domain. You can try non-SSL domain and you'll see that getUserMedia notification bar is always displayed:

http://www.webrtc-experiment.com/

Ref:

Here is how to ask a viewer to stop broadcasting:

connection.onconnected = function(event) {
    event.peer.onCustomMessage = function(message) {
        if (message.dropAllMedias) {
            // remove all audio streams
            // remove all video streams
            // remove all screen streams
            connection.removeStream({
                screen: true,
                audio: true,
                video: true
            });
        }
    };
};

btnAskToStopBroadcast.onclick = function() {
    var userid = 'target-userid';
    connection.peers[userid].sendCustomMessage({
        dropAllMedias: true
    });
};

Same code can be written as:

connection.onCustomMessage = function(message) {
    if (message.targetUserid == connection.userid && message.dropAllMedias) {
        // remove all audio streams
        // remove all video streams
        // remove all screen streams
        connection.removeStream({
            screen: true,
            audio: true,
            video: true
        });
    }
};

btnAskToStopBroadcast.onclick = function() {
    var userid = 'target-userid';
    connection.sendCustomMessage({
        dropAllMedias: true,
        targetUserid: userid
    });
};

Ref:

from rtcmulticonnection.

crina27 avatar crina27 commented on May 23, 2024

I tried to use the code above and it removes the user's broadcast from the admin page, but on the user's side it removes the admin's broadcast. I want to stop the user from broadcasting but still allow him to see what the admin is broadcasting.

from rtcmulticonnection.

muaz-khan avatar muaz-khan commented on May 23, 2024

Use local:true:

connection.removeStream({
    screen: true,
    audio: true,
    video: true,
    local: true, // stop all local streams
    stop: true   // invoke stream.stop() as well
});

or:

connection.streams.stop('local');

from rtcmulticonnection.

crina27 avatar crina27 commented on May 23, 2024

I used connection.streams.stop('local') and now It works. Thank you!

from rtcmulticonnection.

crina27 avatar crina27 commented on May 23, 2024

If I allow a second user to start broadcasting and after some time he just reloads the page then he is automatically asked acces to the webcam and microphone without asking for permission from the admin even though before reload I call the close function : connection. close() .

I want the user just to view the admin's broadcast when he reloads. How can I change this behavior?

from rtcmulticonnection.

muaz-khan avatar muaz-khan commented on May 23, 2024

Please use connection.onNewSession event:

Examples:

from rtcmulticonnection.

crina27 avatar crina27 commented on May 23, 2024

I used connection.onNewSession event
connection.onNewSession = function(session) {
session.join({ oneway: true });
}
Also I noticed that this happens if only the microphone is available. If both devices work then when I refresh as a normal user I don't start broadcasting again.

from rtcmulticonnection.

muaz-khan avatar muaz-khan commented on May 23, 2024

Please try this:

from rtcmulticonnection.

crina27 avatar crina27 commented on May 23, 2024

I don't think the problem is with the session. First the admin of the group opens a session and starts broadcasting and when the group users open the video conference window are able to view the admin but not to broadcast. If a user wants to speak he has to ask for permission from the admin. The problem occurs when a user has acces only to his microphone. If he reloads his window then when he joins the session he begins to broadcast again without having to ask for permission.
If both devices work (webcam and microphone) then when he reloads the page he is only able to view the admin and not to broadcast as it should be.

This is the code I used:

window.connection = new RTCMultiConnection();

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

connection.dontOverrideSession = false;

connection.onNewSession = function(session) {
    session.join({
        oneway: true
    });
}

connection.onstream = function(e) { //add users to padder div
    if (e.mediaElement.id != "undefined") {
        videos.appendChild(e.mediaElement);
    }
    if (e.type == 'remote') {
        // because "viewer" joined room as "oneway:true"
        // initiator will NEVER share participants
        // to manually ask for participants;
        // call "askToShareParticipants" method.
        connection.askToShareParticipants();
    }

    // if you're moderator
    // if stream-type is 'remote'
    // if target user is broadcaster!
    if (connection.isInitiator && e.type == 'remote' && !e.session.oneway) {
        // call "shareParticipants" to manually share participants with all connected users!
        connection.shareParticipants({
            dontShareWith: e.userid
        });
    }
}

And this is the code for the Start conference / Join conference:

//Start or join conference
start.onclick = function() {
    // dont-override-session allows you force RTCMultiConnection
    // to not override default session of participants;
    // by default, session is always overridden and set to the session coming from initiator!
    if (this.firstChild.data == 'Join conference') {
        viewers.innerHTML = "<h6 style='color:#0EC8D7;'>Number of participants: </h6>";

        connection.connect(connection.channel);

        question.style.display = 'inline';
        this.style.display = "none";
        end.style.display = 'inline';
    }

    if (this.firstChild.data == 'Start conference') {
        var rows = membersList.rows.length;
        viewers.innerHTML = "<h6 style='color:#0EC8D7;'>Number of participants: " + rows + "</h6>";

        connection.open({
            sessionid: connection.channel,
            captureUserMediaOnDemand: false
        });
        this.style.display = 'none';
        end.style.display = 'inline';
    }
};

When the admin allows him to broadcast I used:

connection.addStream({
    audio: true,
    video: true,
    broadcast: true
});

And connection.leave() when he reloads or closes the window.

from rtcmulticonnection.

khanhtran3005 avatar khanhtran3005 commented on May 23, 2024

@Slyb00ts I got the same problem with you. Please make sure that when participants join a room, sessionid and userid must be the same with moderator's sessionid and userid

connection.join({
   sessionid: data.sessionid,
   userid: data.moderatorid,
   session: connection.session
});

from rtcmulticonnection.

khanhtran3005 avatar khanhtran3005 commented on May 23, 2024

@muaz-khan Can I give initiator role to other in a conference if initiator left?

from rtcmulticonnection.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.