Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to know whether to create a room, or join one #38

Open
mvayngrib opened this issue Jun 2, 2013 · 16 comments
Open

No way to know whether to create a room, or join one #38

mvayngrib opened this issue Jun 2, 2013 · 16 comments

Comments

@mvayngrib
Copy link
Contributor

One of the current problems I'm experiencing with RTCMultiConnection-v1.2.js with the socketio-over-nodejs server is the lack of a proper way to establish a session. I'm currently using the hack that waits 5 seconds to see if it gets a session invite, otherwise it creates a new channel, but it's pretty unreliable, especially with a slow connection.

I feel like there should be a way to ask the server - "does this room exist?" - like you do with Firebase. Otherwise the two people who want to chat have to go in one at a time, which is not always practical. And a 5 second wait is quite long...especially when testing over and over :)

@imomin
Copy link

imomin commented Jun 2, 2013

I am new to node.js and WebRTC and I started playing with it last night, I have similar thoughts, I was wondering if there is a way to remove dependency of Firebase.

I came up with this idea (not tested)
In signaler.js add var rooms = [];
and add

//expects query param id eg. http://localhost:8888/isRoomExists?id=blahblah
app.get('/isRoomExists', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(rooms.indexOf(req.query.id) > -1);
});
//expects query param id eg. http://localhost:8888/roomAdd?id=blahblah
app.get('/roomAdd', function (req, res) {
res.setHeader('Content-Type', 'application/json');
var roomId = req.query.id;
if(rooms.indexOf(roomId) == -1){
rooms.push(roomId);
res.send(roomId);
}
else {
//may be throw error
res.send(roomId);
}
});
//expects query param id eg. http://localhost:8888/roomRemove?id=blahblah
app.get('/roomRemove', function (req, res) {
res.setHeader('Content-Type', 'application/json');
var roomId = req.query.id;
if(rooms.indexOf(req.query.id) > -1){
rooms.splice(rooms.indexOf(req.query.id),1);
}
res.send(true);
});

muaz-khan added a commit that referenced this issue Jun 3, 2013
Channel presence in "socket.io over node.js" can be detected like this:

function testChannelPresence(channel) {
var socket = io.connect('/');

socket.on('presence', function (isChannelPresent) {
console.log('is channel present', isChannelPresent);
if (!isChannelPresent) playRoleOfSessionInitiator();
});

socket.emit('presence', channel);
}
testChannelPresence('default-channel');

Demo: http://webrtc-signaling.jit.su/RTCMultiConnection

Socket.io over Node.js source code:

https://github.com/muaz-khan/WebRTC-Experiment/tree/master/socketio-over-nodejs
@muaz-khan
Copy link
Owner

function testChannelPresence(channel) {
    var socket = io.connect('/');

    socket.on('presence', function (isChannelPresent) {
            console.log('is channel present', isChannelPresent);
            if (!isChannelPresent) playRoleOfSessionInitiator();
        });

    socket.emit('presence', channel);
}
testChannelPresence('default-channel');

@mvayngrib
Copy link
Contributor Author

cool, thanks :)

I know I asked for this functionality...but thinking about it now, it would save a trip to the server if you could call 'new-channel' and have the server either
a) create a new channel IFF it doesn't already exist, or
b) connect to the channel if it already does

@kooler
Copy link

kooler commented Jun 3, 2013

Is it possible to make such kind of trick for connections based on Firebase?

@muaz-khan
Copy link
Owner

Are you meant something like this?

channelToTest = 'default-channel';
new Firebase('https://chat.firebaseIO.com/' + channelToTest).once('value', function (data) {
    var isChannelPresent = data.val() != null;
    if (!isChannelPresent) playRoleOfSessionInitiator();

    console.log('is channel present', isChannelPresent);
});

@kooler
Copy link

kooler commented Jun 6, 2013

Yep, exactly, works great. Thanks!

@zdfs
Copy link

zdfs commented Jun 24, 2013

The Firebase method doesn't seem to work with 1.3. Should it?

@muaz-khan
Copy link
Owner

@zdfs Are you meant "unable to detect presence of the channel".....or....?

Did you try something like this?

channelToTest = location.hash.substr(1) || 'another-channel';

new Firebase('https://chat.firebaseIO.com/' + channelToTest).once('value', function (data) {
    var isChannelPresent = data.val() != null;

    // if no channel present; open new session
    if (!isChannelPresent) connection.open('a-session-id');

    // else join existing session
    else connection.connect('a-session-id');
});

@zdfs
Copy link

zdfs commented Jun 25, 2013

Yeah. data.val() always returns null in 1.3. It works correctly in 1.2.

@muaz-khan
Copy link
Owner

It works; session-id must be same for all three cases:

  1. For session initiator e.g. connection.open('session-id')
  2. For session participants e.g. connection.connect('session-id')
  3. And for detecting presence of the session e.g. new window.Firebase('https://chat.firebaseIO.com/' + sessionid)
var sessionid = 'session-id';
var connection = new RTCMultiConnection();

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

connection.onstream = function (e) {
    document.body.appendChild(e.mediaElement);
};

new window.Firebase('https://chat.firebaseIO.com/' + sessionid).once('value', function (data) {
    var isRoomPresent = data.val() != null;
    if (!isRoomPresent) connection.open(sessionid);
    else connection.connect(sessionid);

    console.debug('room is present?', isRoomPresent);
});

By default, v1.3 uses chat.firebaseIO.com i.e. chat key. You can override it too:

// overriding for session initiation
connection.firebase = 'signaling';

// presence detection
new window.Firebase('https://signaling.firebaseIO.com/' + sessionid).once(....);

You can see that signaling key is used both for session initiation and presence detection.

@zdfs
Copy link

zdfs commented Jun 25, 2013

I'll take a look tomorrow. Thanks for your input!

@zdfs
Copy link

zdfs commented Jun 25, 2013

Turns out that https://rtcweb.firebaseIO.com doesn't behave like https://chat.firebaseIO.com. Once I switched the url, behavior returned to normal.

Will probably switch to my own socket IO implementation at some point, but will need the Firebase service for a bit longer. Thanks for your help!

@muaz-khan
Copy link
Owner

Do you know, firebase can behave like socket.io over node.js too!

new Firebase('https://YOURINSTANCE.firebaseio.com').on('value', function(snap) { 
     // here is the data transferred from the sender!
    var data = snap.val();

    // will never keep data on firebase servers!
    snap.ref().remove(); 
});

I'm using same technique in RTCMultiConnection-v1.4 and DataChannel-v1.1.

Their set function allow us overwrite existing data; however push seems better because we usually share different kinds of data e.g. ice candidates; session descriptions; presence/notifications etc. (simultaneously)

@ghost
Copy link

ghost commented Jul 5, 2013

@muaz-khan Your proposed solution, which is working well with RTCMultiConnection-1.3, fails when using RTCMultiConnection-1.4. How can we then check whether to create or join a room?

@muaz-khan
Copy link
Owner

RTCMultiConnection-v1.4 working demos coming soon. E.g.

  1. All-in-One test
  2. Video Conferencing & File Sharing & Text Chat
  3. Renegotiation
  4. Auto Session Initiation (i.e. auto join/create rooms)

etc.

Following code works well with v1.4 too; to detect presence of the room; and create/join room accordingly:

new window.Firebase('https://chat.firebaseIO.com/' + sessionid).once('value', function (data) {
    var isRoomPresent = data.val() != null;
    if (!isRoomPresent) connection.open(sessionid);
    else connection.connect(sessionid);

    console.debug('room is present?', isRoomPresent);
});

@softi89
Copy link

softi89 commented Apr 11, 2014

can I replace Firebase('https://chat.firebaseIO.com/' + sessionid) with node.js signaling server

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants