Giter Site home page Giter Site logo

rtc-switchboard's Introduction

rtc-switchboard

This is an rtc.io signalling server (counterpart to rtc-signaller) uses websockets to communicate with signalling clients. It has been designed and built primarily as a reference implementation for a signalling server and is not designed to be deployed at scale.

NPM

unstable Build Status bitHound Score

Try it out

If you would like to use our test signalling server (no uptime guaranteed) then you can use rtc-quickconnect and take it for a spin:

var quickconnect = require('rtc-quickconnect');

quickconnect('//switchboard.rtc.io/', { room: 'switchboard-test' })
  .createDataChannel('test')
  .once('channel:opened:test', function(peerId, dc) {
    dc.onmessage = function(evt) {
      console.log('received data: ', evt.data);
    };

    dc.send('hello');
  });

Other examples are available in the guidebook

Usage: Standalone

If you wish to use rtc-switchboard on its own to test signalling, then you can simply clone this repository, install dependencies and start the server:

git clone https://github.com/rtc-io/rtc-switchboard.git
cd rtc-switchboard
npm install && npm start

If you wish to run the server on a specific port, then set the NODE_PORT environment variable prior to execution:

NODE_PORT=8997 node server.js

Usage: API

To create an application using switchboard signalling, see the following examples:

Pure Node HTTP

var server = require('http').createServer();
var switchboard = require('rtc-switchboard/')(server, { servelib: true });
var port = parseInt(process.env.NODE_PORT || process.env.PORT || process.argv[2], 10) || 3000;
var replify = require('replify');

server.on('request', function(req, res) {
  if (req.url === '/') {
    res.writeHead(302, {
      'Location': 'https://github.com/rtc-io/rtc-switchboard'
    });
    res.end('switchboard available from: https://github.com/rtc-io/rtc-switchboard');
  }
});

// start the server
server.listen(port, function(err) {
  if (err) {
    return console.log('Encountered error starting server: ', err);
  }

  console.log('server running at http://localhost:' + port + '/');
});

// add the repl
replify({
  name: 'switchboard',
  app: switchboard,
  contexts: {
    server: server
  }
});

switchboard.on('room:create', function(room) {
  console.log('room ' + room + ' created, now have ' + switchboard.rooms.length + ' active rooms');
});

switchboard.on('room:destroy', function(room) {
  console.log('room ' + room + ' destroyed, ' + switchboard.rooms.length + ' active rooms remain');

  if (typeof gc == 'function') {
    console.log('gc');
    gc();
  }
});

Using Express

var express = require('express');
var app = express();
var server = require('http').Server(app);
var port = process.env.PORT || 3000;

// create the switchboard
var switchboard = require('rtc-switchboard')(server);

server.listen(port, function(err) {
  if (err) {
    return;
  }

  console.log('server listening on port: ' + port);
});

Usage: Docker

If you are interested in deploying an instance of rtc-switchboard using docker then the following is a great place to start:

https://github.com/synctree/docker-rtc-switchboard

Logging and Analytics using the data event

Every message that flows through the switchboard (whether handled or not) can be logged through tapping into the data event. The example below demonstrates how this can be done with a node logging module like bunyan:

var express = require('express');
var app = express();
var server = require('http').Server(app);
var port = process.env.PORT || 3000;
var bunyan = require('bunyan');
var log = bunyan.createLogger({ name: 'rtc-switchboard' });

// create the switchboard
var switchboard = require('rtc-switchboard')(server);

server.listen(port, function(err) {
  if (err) {
    return;
  }

  console.log('server running at: http://localhost:' + port + '/');
});

switchboard.on('data', function(data, peerId, spark) {
  log.info({ peer: peerId }, 'received: ' + data);
});

As can be seen in the example above, the handlers of the data event can expect to receive three arguments to the handler function, as per the code snippet below:

switchboard.on('data', function(data, peerId, spark) {
});

The data is the raw data of that has been sent from the client, the peerId is the id of the peer sending the data (this will be undefined if it is a message received prior to an /announce command).

License(s)

Apache 2.0

Copyright 2015 National ICT Australia Limited (NICTA)

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

rtc-switchboard's People

Contributors

aaronik avatar auser avatar damonoehlman avatar davidbanham avatar nathanoehlman avatar silviapfeiffer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rtc-switchboard's Issues

Should all messages get sender metadata attached?

I'm currently improving the signaller documentation at the moment (specifically the send function). While it makes sense for a signaller not to send any identification as part of the message (for the sake of keeping message size small) it would probably be helpful for the switchboard to mark messages as they are distributed with the source of the message.

The question here is how to do this in a way that does not break older versions of the signaller that will connect to a signalling server. As the signaller looks for message parts delimited by the pipe | character it should be simple enough to add an additional message part to the end of the message with the source id.

Specifically, I'm thinking using an additional character to enable the signaller to pick this component of the message out prior to other processing.

For instance, a custom /chat message might have been sent before using the signaller like:

signaller.send('/chat', {
  message: 'Hello',
  src: signaller.id
});

Which would translate into the following:

/chat|{"message":"Hello","src":"95cc43aa-9f39-4e53-88b7-3bee18b88c2a"}

With the sender tag attached the message might look like this instead:

/chat|{"message":"Hello","src":"95cc43aa-9f39-4e53-88b7-3bee18b88c2a"}|~95cc43aa-9f39-4e53-88b7-3bee18b88c2a"

In each case, the signaller would be able to process these custom chat messages using the same syntax of:

signaller.on('chat', function(data) {
});

While the new switchboard coded message would have an additional argument provided to the event handler, this would not impact event handling.

HOWTO: Security

How to allow users to join once they have been authenticated, etc.

Reannounce Handling - Room Reallocation

As the rtc-signaller is designed to allow multiple announce messages, the switchboard needs to fall in line here. As such, the switchboard should be able to handle the following scenarios using a signaller.

Reannounce with room specified

signaller.announce();
signaller.send('hello');
signaller.announce({ room: 'testroom'});
signaller.send('hi there');

Expected behaviour would be that switchboard instance of the peer would be allocated to testroom from the __default room that is used when no room is specified in the announce. The hello message would be delivered to __default room participants whereas hi there would only be delivered to members of testroom.

Change room on re-announce

signaller.announce({ room: 'room1' });
signaller.send('hello');
signaller.announce({ room: 'room2' });
signaller.send('hi there');

Expected behaviour is that the switchboard instance of the peer would be first allocated to room1 and then allocated to room2 when the second announce message was received. Thus the hello message would be delivered to peers connected to the room1 room and the hi there message would be received by peers connected to the room2 room.

Serving switchboard over HTTPS

Hi, I'm currently doing a college project which requires video and audio transmission from person to person within a browser. rtc.io seems like a great way to achieve this. I am however running into a problem. I am serving the HTML page with the rtc.io content over HTTPS, since Chrome requires HTTPS to be used when handling the webcam. While this isn't an issue perse, the problem arises when I try to connect a client to a self-hosted switchboard. Chrome will only allow me connect a client to a switchboard if the switchboard is also served over HTTPS, which it isn't as far as I can tell. What would be the correct way to connect a client to the switchboard over HTTPS?

Multiplexing tests

From version 0.5 of the switchboard, the ability to route multiple peer connections over a single primus spark (socket) will be supported. At this stage though we have no tests to ensure this behaviour works as expected.

WebSocket connection to 'wss://switchboard.rtc.io/' failed: Error during WebSocket handshake: Unexpected response code: 404

I was trying the video conferencing example which was given on the demo of rtc.io.
My local stream was working fine,but the remote user was not able to connect to me.
I was getting an error in console.

WebSocket connection to 'wss://switchboard.rtc.io/' failed: Error during WebSocket handshake: Unexpected response code: 404
I am on a https server.I think the rtc.io doesn't support https.

Remove Multiple Peers per Spark Logic

The current announce handler attempts to handler a single primus spark being used by multiple signallers (see https://github.com/rtc-io/rtc-switchboard/blob/master/handlers/announce.js#L20). In retrospect I believe this behaviour is incorrect and unmanageable and should be reverted to only associate a single signaller per spark.

We should allow for spark reuse though, and ensure that an announce coming down the pipe with a different id to that which is associated with the spark is correctly handled (i.e previous signaller instance sends a leave message prior to the new signalling peers announce message being dispatched).

wss:// 404

Hi, im trying to do an experiment in screensharing:

var quickconnect = require('rtc-quickconnect')

var constraints = {
  audio: false,
  video: {
    mandatory: {
      chromeMediaSource: 'screen'
    },
    optional: []
  }
}


quickconnect('//rtc.io/switchboard/', { ns: 'screenshare-test', data: true, constraints: constraints }).on('dc:open', function(channel, peerId) {
  console.log(channel, peerId)
  // var video = document.createElement('video')
  // video.src = window.URL.createObjectURL(stream)
  // video.autoplay = true
  // document.body.appendChild(video)
})

to use the screen sharing API you must be on an https server. I'm using npm install crisp -g to do this locally in development.

When I run the above code (using browserify) I get the following error:

WebSocket connection to 'wss://rtc.io/switchboard/' failed: Error during WebSocket handshake: Unexpected response code: 404

Is wss:// supported? I can't use ws:// due to mixed protocol errors

`room:create` and `room:destroy` events

It would be great to know when a new room has been created (i.e. the first participant of a room has joined) and a room is destroyed (the last participant has left).

Should the switchboard advise a signaller how many peers are in the current scope?

When joining a server one of the first things you do if you are using the signaller is to send an /announce message. This is sent to other connected peers within your current scope (room if you have announced in a room) or server if not.

To determine whether or not you have any peers around you, you currently have to wait until connected peers send you a targeted /announce message telling you about them.

The difficulty is, that at this stage you have no idea on whether to expect these wait for messages, etc. In most cases, this does not cause a problem, but in my experimentation with creating a mesh demo you need to take different action if you are the first party in a room vs another party joining. As it stands, you have no way of telling that you are the first party in the room.

A potential solution to this would be to extend the switchboard to send something like a /roominfo message to the peer that has just announced itself containing room metadata.

Applications requiring this kind of information could then listen for the roominfo event and make determination based on this. For instance, rtc-mesh would wait for the event to determine whether it is ready immediately if the first or whether it should wait for peer data to sync before providing access.

Handle Socket Dropout and Reconnection

Currently when a socket is closed switchboard takes this as an indication that the client has left. This is not correct as a websocket connection (like any other network connection) is susceptible to dropping out. Primus handles this case and automatically reconnects "sparks" - we need to ensure that this is handled correctly by the switchboard.

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.