Comparing version 0.4.0 to 0.5.0
@@ -92,5 +92,5 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Minijanus = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
JanusSession.prototype.destroy = function() { | ||
return this.send("destroy").then(() => { | ||
this._killKeepalive(); | ||
}); | ||
// Note that this message, unlike others, does *not* receive a response from janus, so there is no promise returned. | ||
this.send("destroy"); | ||
this._killKeepalive(); | ||
}; | ||
@@ -192,3 +192,3 @@ | ||
JanusSession.prototype._keepalive = function() { | ||
JanusSession.prototype._sendKeepalive = function() { | ||
return this.send("keepalive"); | ||
@@ -206,3 +206,3 @@ }; | ||
if (this.options.keepaliveMs) { | ||
this.keepaliveTimeout = setTimeout(() => this._keepalive(), this.options.keepaliveMs); | ||
this.keepaliveTimeout = setTimeout(() => this._sendKeepalive(), this.options.keepaliveMs); | ||
} | ||
@@ -209,0 +209,0 @@ }; |
@@ -91,5 +91,5 @@ /** | ||
JanusSession.prototype.destroy = function() { | ||
return this.send("destroy").then(() => { | ||
this._killKeepalive(); | ||
}); | ||
// Note that this message, unlike others, does *not* receive a response from janus, so there is no promise returned. | ||
this.send("destroy"); | ||
this._killKeepalive(); | ||
}; | ||
@@ -191,3 +191,3 @@ | ||
JanusSession.prototype._keepalive = function() { | ||
JanusSession.prototype._sendKeepalive = function() { | ||
return this.send("keepalive"); | ||
@@ -205,3 +205,3 @@ }; | ||
if (this.options.keepaliveMs) { | ||
this.keepaliveTimeout = setTimeout(() => this._keepalive(), this.options.keepaliveMs); | ||
this.keepaliveTimeout = setTimeout(() => this._sendKeepalive(), this.options.keepaliveMs); | ||
} | ||
@@ -208,0 +208,0 @@ }; |
{ | ||
"name": "minijanus", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "Really simple and minimal wrapper for talking to the Janus signalling API.", | ||
@@ -5,0 +5,0 @@ "main": "minijanus.js", |
@@ -7,3 +7,5 @@ # minijanus.js | ||
A super-simplistic and -minimal wrapper for talking to the [Janus signalling API][api-docs]. Developed for use with | ||
Janus as a web game networking backend via [janus-plugin-sfu][]. | ||
Janus as a web game networking backend via [janus-plugin-sfu][], but fundamentally plugin-agnostic. Designed to | ||
provide useful possible abstractions while still providing the maximum possible control over `RTCPeerConnection` | ||
configuration and precise plugin signalling flow. | ||
@@ -16,8 +18,11 @@ If you want a batteries-included wrapper, you should use the one distributed by the Janus developers -- | ||
understand the signalling API. | ||
3. It gives you control over most of the configuration and usage of the RTCPeerConnection directly, whereas janus.js | ||
3. It gives you control over most of the configuration and usage of the `RTCPeerConnection` directly, whereas janus.js | ||
wraps and manages the connection for you. | ||
If you want a similar but moderately more featureful wrapper, check out [minnie-janus][]. | ||
[api-docs]: https://janus.conf.meetecho.com/docs/rest.html | ||
[janus.js]: https://github.com/meetecho/janus-gateway/blob/master/html/janus.js | ||
[janus-plugin-sfu]: https://github.com/mquander/janus-plugin-sfu | ||
[minnie-janus]: https://github.com/michaelfranzl/minnie-janus | ||
@@ -30,44 +35,36 @@ ## Example | ||
var ws = new WebSocket("ws://localhost:8188", "janus-protocol"); | ||
ws.addEventListener("open", () => { | ||
var session = new Minijanus.JanusSession(ws.send.bind(ws)); | ||
ws.addEventListener("message", ev => session.receive(JSON.parse(ev.data))); | ||
session.create().then(() => establishConnection(session)).then(() => { | ||
console.info("Connection established: ", handle); | ||
}); | ||
}); | ||
var session = new JanusPluginSession(ws.send.bind(ws)); | ||
var handle = new JanusPluginHandle(session); | ||
var conn = new RTCPeerConnection({}); | ||
function negotiateIce(conn, handle) { | ||
return new Promise((resolve, reject) => { | ||
conn.addEventListener("icecandidate", ev => { | ||
handle.sendTrickle(ev.candidate || null).then(() => { | ||
if (!ev.candidate) { // this was the last candidate on our end and now they received it | ||
resolve(); | ||
} | ||
ws.addEventListener("message", ev => session.receive(JSON.parse(ev.data))); | ||
ws.addEventListener("open", _ => { | ||
session.create() | ||
.then(_ => handle.attach("janus.plugin.sfu")) | ||
.then(_ => { | ||
conn.addEventListener("icecandidate", ev => { | ||
handle.sendTrickle(ev.candidate || null).catch(e => console.error("Error trickling ICE: ", e)); | ||
}); | ||
}); | ||
}); | ||
}; | ||
function establishConnection(session) { | ||
var conn = new RTCPeerConnection({}); | ||
var handle = new Minijanus.JanusPluginHandle(session); | ||
return handle.attach("janus.plugin.sfu").then(() => { | ||
var iceReady = negotiateIce(conn, handle); | ||
var unreliableCh = conn.createDataChannel("unreliable", { ordered: false, maxRetransmits: 0 }); | ||
var reliableCh = conn.createDataChannel("reliable", { ordered: true }); | ||
var mediaReady = navigator.mediaDevices.getUserMedia({ audio: true }); | ||
var offerReady = mediaReady | ||
.then(media => { | ||
conn.addStream(media); | ||
return conn.createOffer({ audio: true }); | ||
}, () => conn.createOffer()); | ||
var localReady = offerReady.then(conn.setLocalDescription.bind(conn)); | ||
var remoteReady = offerReady | ||
.then(handle.sendJsep.bind(handle)) | ||
.then(answer => conn.setRemoteDescription(answer.jsep)); | ||
return Promise.all([iceReady, localReady, remoteReady]); | ||
}); | ||
} | ||
conn.addEventListener("negotiationneeded", _ => { | ||
var offer = conn.createOffer(); | ||
var local = offer.then(o => conn.setLocalDescription(o)); | ||
var remote = offer.then(j => handle.sendJsep(j)).then(r => conn.setRemoteDescription(r.jsep)); | ||
Promise.all([local, remote]).catch(e => console.error("Error negotiating offer: ", e)); | ||
}); | ||
var unreliableCh = conn.createDataChannel("unreliable", { ordered: false, maxRetransmits: 0 }); | ||
var reliableCh = conn.createDataChannel("reliable", { ordered: true }); | ||
navigator.mediaDevices.getUserMedia({ audio: true }) | ||
.then(m => m.getTracks().forEach(t => conn.addTrack(t, m))) | ||
.catch(e => console.error("Error acquiring media: ", e)); | ||
return new Promise(resolve => handle.on("webrtcup", resolve)); | ||
}) | ||
.then(_ => { console.info("Connected to Janus: ", conn); }) | ||
.catch(e => { console.error("Error connecting to Janus: ", e); }); | ||
}); | ||
``` | ||
(Note that this example code first negotiates only the data channels, and then renegotiates afterward when the | ||
microphone permission is provided. Only recent versions of Janus support renegotiation. If you didn't want this, you | ||
would instead wait to create the connection until the microphone permission was granted.) | ||
## Building | ||
@@ -74,0 +71,0 @@ |
32
tests.js
var mj = require('./minijanus.js'); | ||
var test = require('tape'); | ||
test('events are detected and matched to handles', function(t) { | ||
var session = new mj.JanusSession(signal => {}, { keepaliveMs: null }); | ||
var handles = [0, 1, 2].map(i => { var h = new mj.JanusPluginHandle(session); h.id = i; return h; }); | ||
var h0 = new Promise(resolve => handles[0].on("foo", resolve)); | ||
var h1 = new Promise(resolve => handles[1].on("foo", resolve)); | ||
var h2 = new Promise(resolve => handles[2].on("bar", resolve)); | ||
session.receive({ janus: "foo", sender: 123 }); | ||
session.receive({ janus: "foo", sender: 0 }); | ||
session.receive({ janus: "bar", sender: 2 }); | ||
session.receive({ janus: "foo", sender: 456 }); | ||
session.receive({ janus: "foo", sender: 1 }); | ||
Promise.all([h0, h1, h2]).then(results => { | ||
t.deepEqual(results[0], { janus: "foo", sender: 0 }); | ||
t.deepEqual(results[1], { janus: "foo", sender: 1 }); | ||
t.deepEqual(results[2], { janus: "bar", sender: 2 }); | ||
t.end(); | ||
}).catch(err => { | ||
t.fail(err); | ||
t.end(); | ||
}); | ||
}); | ||
test('transactions are detected and matched up', function(t) { | ||
@@ -31,2 +55,5 @@ var session = new mj.JanusSession(signal => {}, { keepaliveMs: null }); | ||
t.end(); | ||
}).catch(err => { | ||
t.fail(err); | ||
t.end(); | ||
}); | ||
@@ -56,3 +83,6 @@ }); | ||
t.end(); | ||
}); | ||
}).catch(err => { | ||
t.fail(err); | ||
t.end(); | ||
});; | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
74351
452
80