diff --git a/Gruntfile.js b/Gruntfile.js index b9cee73a3..b7c5764e6 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -185,7 +185,7 @@ module.exports = function (grunt) { grunt.registerTask('publish', [ 'clean:production', 'concat:production', - 'concat:complete', + 'concat:complete', 'versionise', 'replace:dist', 'uglify:production_min', diff --git a/README.md b/README.md index e50f709a5..e345baa28 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,10 @@ You'll need a Temasys Developer Account and an API key to use this. [Register he We've gone to great length to make this library work in as many browsers as possible. SkywayJS is build on top of [AdapterJS](https://github.com/Temasys/AdapterJS) and works with our [Temasys WebRTC Plugin](https://temasys.atlassian.net/wiki/display/TWPP/WebRTC+Plugins) even in Internet Explorer and Safari on Mac and PC. -- [Introducing SkywayJS](https://temasys.atlassian.net/wiki/display/TPD/Introducing+SkywayJS) - The complete documentation and API docs +- [Getting started](http://temasys.github.io/how-to/2014/08/08/Getting_started_with_WebRTC_and_SkywayJS/) +- [SkywayJS API Docs](http://cdn.temasys.com.sg/skyway/skywayjs/0.3.x/doc/classes/Skyway.html) +- [Introducing SkywayJS](http://temasys.atlassian.net/wiki/display/TPD/Introducing+SkywayJS) +- [Developer Console](https://developer.temasys.com.sg) - Get your API key #### Need help or want something changed? @@ -53,11 +56,11 @@ The skyway.js library development files #### tests -Tape/Testling tests, currently work-in-progress - +- Run `test.sh ` to test the trigger events of SkywayJS. + - To run a test, simply type: `test.sh test webrtc` + - To run a bot (that some tests requires), simply type: `test.sh bot webrtc` +- Note that in some instances, if the test requires a bot, always run the bot first before running the test. ## License -[APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) - - +[APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) \ No newline at end of file diff --git a/demo/app/css/style.css b/demo/app/css/style.css index d87ae3477..f9af6ef5e 100644 --- a/demo/app/css/style.css +++ b/demo/app/css/style.css @@ -47,12 +47,13 @@ } #credential_panel .panel-body .form-group .control-group { } -video { +video, object { background:#444; border:solid 2px #fff; padding:0!important; } -video#local_video { +video#local_video, +object#local_video { right:15px; position:absolute; z-index:9999; @@ -91,11 +92,12 @@ footer { } } @media screen and (max-width:991px){ - video { + video, object { display:block; width:100%; } - video#local_video { + video#local_video, + object#local_video { right:0; position:static; display:block diff --git a/demo/app/index.html b/demo/app/index.html index a9cc66584..958c75be0 100644 --- a/demo/app/index.html +++ b/demo/app/index.html @@ -84,6 +84,8 @@ Display Name + + diff --git a/demo/app/js/main.js b/demo/app/js/main.js index f73af46ba..e9f67c02e 100644 --- a/demo/app/js/main.js +++ b/demo/app/js/main.js @@ -44,19 +44,20 @@ Demo.Elements = { chatLog: '#chat_log', chatBody: '#chat_body' }; -Demo.API.displayMsg = function (nick, msg, isPvt, isFile) { +Demo.API.displayChatMessage = function (peerId, message, isFile) { var timestamp = new Date(); var element = (isFile) ? Demo.Elements.fileLog : Demo.Elements.chatLog; var element_body = (isFile) ? Demo.Elements.fileBody : Demo.Elements.chatBody; $(element).append( '
' + '

' + - '' + nick + '' + + '' + peerId + '' + '' + timestamp.getHours() + ':' + timestamp.getMinutes() + ':' + timestamp.getSeconds() + '

' + '

' + - (isPvt?'[pvt msg] ':'') + msg + (isPvt?'':'') + + (message.isPrivate ? '[pvt msg] ' : '') + message.content + + (message.isPrivate ? '' : '') + '

' ); $(element_body).animate({ @@ -83,31 +84,38 @@ Demo.Skyway.on('dataTransferState', function (state, transferId, peerId, transfe var percentage = transferInfo.percentage; switch (state) { + case Demo.Skyway.DATA_TRANSFER_STATE.UPLOAD_REQUEST : + var result = confirm('Accept file "' + name + '" [size: ' + size + '] from ' + peerId + '?'); + Demo.Skyway.respondBlobRequest(peerId, result); + break; case Demo.Skyway.DATA_TRANSFER_STATE.UPLOAD_STARTED : - Demo.API.displayMsg(senderPeerId, - '

' + name + '
' + size + ' Bytes

' + - '' + - '' + - '
' + - ' Uploaded Status
' + - '

Download Uploaded File

', - false, true); - Demo.API.displayMsg(senderPeerId, 'I\'ve sent a File', false); + Demo.API.displayChatMessage(senderPeerId, { + content: '

' + name + '
' + size + ' Bytes

' + + '' + + '' + + '
' + + ' Uploaded Status
' + + '

Download Uploaded File

' + }, true); + Demo.API.displayChatMessage(senderPeerId, 'I\'ve sent a File', false); break; case Demo.Skyway.DATA_TRANSFER_STATE.DOWNLOAD_STARTED : - Demo.API.displayMsg(senderPeerId, - '

' + name + '
' + size + ' Bytes

' + - '
' + - '
' + - 'Downloading...
' + - '

', - false, true); - Demo.API.displayMsg(senderPeerId, 'I\'ve sent you a File', false); + alert(JSON.stringify(transferInfo)); + Demo.API.displayChatMessage(senderPeerId, { + content: '

' + name + '
' + size + ' Bytes

' + + '
' + + '
' + + 'Downloading...
' + + '

' + }, true); + Demo.API.displayChatMessage(senderPeerId, { + content: 'I\'ve sent you a File' + }); break; case Demo.Skyway.DATA_TRANSFER_STATE.UPLOADING : if ($(element).find('.' + peerId).width() < 1) { @@ -124,7 +132,9 @@ Demo.Skyway.on('dataTransferState', function (state, transferId, peerId, transfe $(element).find('span').html(percentage + ' %'); break; case Demo.Skyway.DATA_TRANSFER_STATE.UPLOAD_COMPLETED : - Demo.API.displayMsg(peerId, 'Peer ' + peerId + ' has received your file "' + name + '"'); + Demo.API.displayChatMessage(peerId, { + content: 'Peer ' + peerId + ' has received your file "' + name + '"' + }); $(element).find('.' + peerId).html('✓'); break; case Demo.Skyway.DATA_TRANSFER_STATE.DOWNLOAD_COMPLETED : @@ -142,13 +152,24 @@ Demo.Skyway.on('dataTransferState', function (state, transferId, peerId, transfe } }); //--------------------------------------------------- -Demo.Skyway.on('chatMessageReceived', function (msg, peerId, isPvt) { - Demo.API.displayMsg(peerId, msg, isPvt); +Demo.Skyway.on('incomingMessage', function (message, peerId, isSelf) { + console.info(message); + if (message.isDataChannel) { + message.content = message.content.header + ': ' + message.content.content; + } else { + message.content = message.content.content; + } + Demo.API.displayChatMessage((isSelf) ? 'You' : peerId, message); }); //--------------------------------------------------- Demo.Skyway.on('peerJoined', function (peerId, peerInfo, isSelf){ + console.info(peerInfo); if (isSelf) { $(Demo.Elements.displayUserId).html(peerId); + $('#isAudioMuted').css('color', + (peerInfo.mediaStatus.audioMuted) ? 'red' : 'green'); + $('#isVideoMuted').css('color', + (peerInfo.mediaStatus.videoMuted) ? 'red' : 'green'); $(Demo.Elements.joinRoom).hide(); $(Demo.Elements.leaveRoomBtn).show(); $(Demo.Elements.presencePanel).show(); @@ -159,32 +180,38 @@ Demo.Skyway.on('peerJoined', function (peerId, peerInfo, isSelf){ $(Demo.Elements.fileListPanel).show(); } } else { - Demo.API.displayMsg('System', 'Peer ' + peerId + ' joined the room'); + Demo.API.displayChatMessage('System', { + content: 'Peer ' + peerId + ' joined the room' + }); var newListEntry = '' + - '[' + - ((peerInfo.mediaStatus.audioMuted) ? 'NA' : 'A') + - '] ' + peerInfo.userData.displayName + ''; + '' + peerInfo.userData.displayName + ''; var titleList = [ 'Joined Room', 'Handshake: Welcome', 'Handshake: Offer', 'Handshake: Answer', 'Candidate Generation state', 'ICE Connection state', - 'Peer Connection state', 'Data Channel Connection state' + 'Peer Connection state', 'Data Channel Connection state', + 'MediaStream: Video', 'MediaStream: Audio' ]; var glyphiconList = [ 'glyphicon-log-in', 'glyphicon-hand-right', 'glyphicon-hand-left', 'glyphicon-thumbs-up', 'glyphicon-flash', 'glyphicon-magnet', - 'glyphicon-user', 'glyphicon-link' + 'glyphicon-user', 'glyphicon-link', 'glyphicon-facetime-video video', + 'glyphicon-volume-up audio' ]; - for( var i = 0; i < 8; i++) { + for( var i = 0; i < 10; i++) { newListEntry += '   '; } newListEntry += ''; $('#presence_list').append(newListEntry); $('#user' + peerId + ' .0').css('color','green'); + $('#user' + peerId + ' .video').css('color', + (peerInfo.mediaStatus.videoMuted) ? 'red' : 'green'); + $('#user' + peerId + ' .audio').css('color', + (peerInfo.mediaStatus.audioMuted) ? 'red' : 'green'); } }); //--------------------------------------------------- -Demo.Skyway.on('addPeerStream', function (peerId, stream, isSelf){ +Demo.Skyway.on('incomingStream', function (peerId, stream, isSelf){ if (!isSelf) { Demo.API.peers += 1; if( Demo.API.peers > 2 ){ @@ -243,13 +270,22 @@ Demo.Skyway.on('readyStateChange', function (state, error){ $(Demo.Elements.updateUserInput).val(displayName); return; } else if (state === Demo.Skyway.READY_STATE_CHANGE.ERROR) { - alert(error); + for (var errorCode in Demo.Skyway.READY_STATE_CHANGE_ERROR) { + if (Demo.Skyway.READY_STATE_CHANGE_ERROR[errorCode] === + error.errorCode) { + alert('An error occurred parsing and retrieving server code.\n' + + 'Error was: ' + errorCode); + break; + } + } } $(Demo.Elements.channelStatus).show(); }); //--------------------------------------------------- Demo.Skyway.on('peerLeft', function (peerId){ - Demo.API.displayMsg('System', 'Peer ' + peerId + ' has left the room'); + Demo.API.displayChatMessage('System', { + content: 'Peer ' + peerId + ' has left the room' + }); Demo.API.peers -= 1; $('video').each( function(){ if(this.peerId === peerId){ @@ -357,17 +393,21 @@ Demo.Skyway.on('dataChannelState', function (state, peerId) { //--------------------------------------------------- Demo.Skyway.on('peerUpdated', function (peerId, peerInfo, isSelf) { if (isSelf) { - $(Demo.Elements.updateUserInput).val('[' + - ((peerInfo.mediaStatus.audioMuted) ? 'NA' : 'A') + '] ' + - peerInfo.userData.displayName); + $('#isAudioMuted').css('color', + (peerInfo.mediaStatus.audioMuted) ? 'red' : 'green'); + $('#isVideoMuted').css('color', + (peerInfo.mediaStatus.videoMuted) ? 'red' : 'green'); if (peerInfo.mediaStatus.videoMuted) { $(Demo.Elements.localVideo)[0].src = ''; } else { $(Demo.Elements.localVideo)[0].src = Demo.Streams.local; } } else { - $('#user' + peerId +' .name').html('[' + ((peerInfo.mediaStatus.audioMuted) ? 'NA' : 'A') + - '] ' + peerInfo.userData.displayName); + $('#user' + peerId + ' .video').css('color', + (peerInfo.mediaStatus.videoMuted) ? 'red' : 'green'); + $('#user' + peerId + ' .audio').css('color', + (peerInfo.mediaStatus.audioMuted) ? 'red' : 'green'); + $('#user' + peerId + ' .name').html(peerInfo.userData.displayName); $('video').each( function(){ if ($(this)[0].peerId === peerId) { if (peerInfo.mediaStatus.videoMuted) { @@ -380,12 +420,9 @@ Demo.Skyway.on('peerUpdated', function (peerId, peerInfo, isSelf) { } }); //--------------------------------------------------- -Demo.Skyway.on('roomLock', function (status, isLocked, error) { - if (!status) { - alert(error); - } else { - $(Demo.Elements.displayLockStatus).html((isLocked) ? 'Locked' : 'Not Locked'); - } +Demo.Skyway.on('roomLock', function (isLocked, peerId, peerInfo, isSelf) { + $(Demo.Elements.displayLockStatus).html((isLocked) ? 'Locked' : 'Not Locked'); + console.info(peerInfo); }); //--------------------------------------------------- Demo.Skyway.on('channelOpen', function () { @@ -406,7 +443,9 @@ Demo.Skyway.on('channelMessage', function (){ }); //--------------------------------------------------- Demo.Skyway.on('channelError', function (error) { - Demo.API.displayMsg('System', 'Channel Error:
' + error); + Demo.API.displayChatMessage('System', { + content: 'Channel Error:
' + error + }); }); /******************************************************** DOM Events @@ -418,8 +457,13 @@ $(document).ready(function () { $(Demo.Elements.chatInput).keyup(function(e) { e.preventDefault(); if (e.keyCode === 13) { - //Demo.Skyway.sendDataChannelChatMsg( $(Demo.Elements.chatInput).val() ); - Demo.Skyway.sendChatMessage( $(Demo.Elements.chatInput).val() ); + Demo.Skyway.sendP2PMessage({ + header: '[DC]', + content: $(Demo.Elements.chatInput).val() + }); + Demo.Skyway.sendMessage({ + content: $(Demo.Elements.chatInput).val() + }); $(Demo.Elements.chatInput).val(''); } }); @@ -455,14 +499,10 @@ $(document).ready(function () { }); //--------------------------------------------------- $(Demo.Elements.updateUserBtn).click(function () { - try { - var displayName = $(Demo.Elements.updateUserInput).val(); - var userData = Demo.Skyway.getUserData(); - userData.userData.displayName = displayName; - Demo.Skyway.setUserData(userData.userData); - } catch (err) { - alert('Invalid JSON provided'); - } + var displayName = $(Demo.Elements.updateUserInput).val(); + var userData = Demo.Skyway.getUserData(); + userData.displayName = displayName; + Demo.Skyway.setUserData(userData); }); //--------------------------------------------------- $(Demo.Elements.lockBtn).click(function () { diff --git a/demo/index.html b/demo/index.html index 3d232a5e4..7f36148f3 100644 --- a/demo/index.html +++ b/demo/index.html @@ -41,6 +41,28 @@

SkywayJS Documentation

+
+
+

Simple Conference room

+
+
+

+ This demo connect as Guest to your API test account. + You just need to fill app ID that you want to use for this demo at the top of the + simple-app/app.js file. No css is provided. +

+
+
    +
  • Automatically fetch for cam.
  • +
  • Automatically connects to 'demo' Room.
  • +
  • Handle connection and disconnection of peers.
  • +
  • Unlimited number of stream.
  • +
+

+ View Demo +

+
+

Demo

diff --git a/demo/simple-app/app.js b/demo/simple-app/app.js new file mode 100644 index 000000000..e52ebf7aa --- /dev/null +++ b/demo/simple-app/app.js @@ -0,0 +1,67 @@ +//------------ +// Create our Skyway object +var SkywayDemo = new Skyway(); + +//////////////////////////////////// +///////TO FILL +var APPKEYID = XXXXXXXX - XXXX - XXXX - XXXX - XXXXXXXXXXXX; +var ROOMNAME = "demo"; +var SKYWAYSERVER = "http://api.temasys.com.sg/"; +/////// +/////////////////////////////////// + +(function() +{ + SkywayDemo.init( + { + roomserver: SKYWAYSERVER, + apiKey: APPKEYID, + defaultRoom: ROOMNAME, + region: "sg" + }); +})(); + +//-------- +SkywayDemo.on('readyStateChange', function(state) +{ + console.log("readyStateChange"); + if (state === SkywayDemo.READY_STATE_CHANGE.COMPLETED) + { + SkywayDemo.joinRoom( + { + audio: true, + video: true + }); + } +}); +//-------- +SkywayDemo.on('mediaAccessSuccess', function(stream) +{ + console.log("mediaAccessSuccess"); + attachMediaStream(document.getElementById("myVideo"), stream); +}); +//-------- +SkywayDemo.on('incomingStream', function(peerID, stream, isSelf) +{ + if (!isSelf) + { + console.log("addPeerStream"); + var DOMRemoteVideo = document.createElement('video'); + DOMRemoteVideo.setAttribute("style", "width: 320px; height: 240px;"); + DOMRemoteVideo.setAttribute("autoplay", "autoplay"); + DOMRemoteVideo.setAttribute("id", "remote_" + peerID); + var DOMcontainer = document.getElementById("remoteContainer"); + DOMcontainer.appendChild(DOMRemoteVideo); + attachMediaStream(DOMRemoteVideo, stream); + } + +}); +//-------- +SkywayDemo.on('peerLeft', function(peerID) +{ + console.log("peerLeft"); + var DOMvideo = document.getElementById("remote_" + peerID); + var DOMcontainer = document.getElementById("remoteContainer"); + DOMvideo.src = ''; + DOMcontainer.removeChild(DOMvideo); +}); \ No newline at end of file diff --git a/demo/simple-app/index.html b/demo/simple-app/index.html new file mode 100644 index 000000000..a4586807d --- /dev/null +++ b/demo/simple-app/index.html @@ -0,0 +1,28 @@ + + + + Temasys: My Room Example + + + + + + +

Simple Room

+ +
+
+ +
+
+

+ © Temasys Communications Pte Ltd 2014. All Rights Reserved. +

+
+
+ + + + + diff --git a/demo/test/index.html b/demo/test/index.html new file mode 100644 index 000000000..e241f336e --- /dev/null +++ b/demo/test/index.html @@ -0,0 +1,24 @@ + + + WebRTC with SkywayJS + + + + + + +
+ SkywayJS on Github + + +
+ + +
+ +
+
+
+ + + \ No newline at end of file diff --git a/demo/test/test.css b/demo/test/test.css new file mode 100644 index 000000000..749737e92 --- /dev/null +++ b/demo/test/test.css @@ -0,0 +1,32 @@ +header { + background: #eee; + padding: 20px; + margin-bottom: .4em; + font-family: Helvetica, Arial, sans-serif; +} + +header a:first-child { + float: right; + margin: 0 0 20px 30px; +} + +#container { + position: relative; + border: 1px #ddd solid; + height: 180px; + overflow-y: auto; +} + +#chatbox { + position: absolute; + bottom: 0px; +} + +.action { + font-style: italic; + color: gray; +} + +.you { + font-weight: bold; +} \ No newline at end of file diff --git a/demo/test/test.js b/demo/test/test.js new file mode 100644 index 000000000..3fe07a6ec --- /dev/null +++ b/demo/test/test.js @@ -0,0 +1,59 @@ +var skyway = new Skyway(); + +skyway.on('peerJoined', function(peerId, peerInfo, isSelf) { + var user = 'You'; + if(!isSelf) { + user = peerInfo ? peerInfo.userData || peerId : peerId; + } + addMessage(user + ' joined the room', 'action'); +}); + +skyway.on('peerUpdated', function(peerId, peerInfo, isSelf) { + if(isSelf) { + var user = peerInfo ? peerInfo.userData || peerId : peerId; + addMessage('You\'re now known as ' + user, 'action'); + } +}); + +skyway.on('peerLeft', function(peerId) { + var user = 'You'; + if(!isSelf) { + var peerInfo = skyway.getPeerInfo(peerId); + console.info(peerInfo); + user = peerInfo ? peerInfo.userData || peerId : peerId; + } + addMessage(user + ' left the room', 'action'); +}); + +skyway.on('incomingMessage', function(message, peerId, isSelf) { + var user = 'You'; + if(!isSelf) { + var peerInfo = skyway.getPeerInfo(peerId); + user = peerInfo ? peerInfo.userData || peerId : peerId; + } + addMessage(user + ': ' + message, isSelf ? 'you' : 'message'); +}); + +skyway.init('5f874168-0079-46fc-ab9d-13931c2baa39'); // Get your own key at developer.temasys.com.sg + +skyway.joinRoom(); + + +function setName() { + var input = document.getElementById('name'); + skyway.setUserData(input.value); +} + +function sendMessage() { + var input = document.getElementById('message'); + skyway.sendChatMessage(input.value); + input.value = ''; +} + +function addMessage(message, className) { + var chatbox = document.getElementById('chatbox'), + div = document.createElement('div'); + div.className = className; + div.innerHTML = message; + chatbox.appendChild(div); +} \ No newline at end of file diff --git a/doc/classes/Skyway.html b/doc/classes/Skyway.html index 378aeec92..fd1dd432f 100644 --- a/doc/classes/Skyway.html +++ b/doc/classes/Skyway.html @@ -22,7 +22,7 @@

- API Docs for: 0.3.1 + API Docs for: 0.4.0
@@ -101,13 +101,21 @@

Skyway Class

+

Available since 0.1.0

+

Please check on the init() function -on how you can initialize Skyway.

+on how you can initialize Skyway. Note that:

+
@@ -156,6 +164,8 @@

Skyway

+

Available since 0.1.0

+
@@ -255,13 +265,6 @@

Methods

- - -
  • - _chatHandler - - -
  • @@ -715,70 +718,70 @@

    Methods

  • - joinRoom + isRoomLocked
  • - leaveRoom + joinRoom
  • - lockRoom + leaveRoom
  • - off + lockRoom
  • - on + off
  • - sendBlobData + on
  • - sendChatMessage + respondBlobRequest
  • - sendDataChannelChatMessage + sendBlobData
  • - sendPrivateMessage + sendMessage
  • - sendPublicMessage + sendP2PMessage @@ -886,6 +889,10 @@

    Attributes

    _room
  • +
  • + _room_lock +
  • +
  • _roomCredentials
  • @@ -978,6 +985,10 @@

    Attributes

    PEER_CONNECTION_STATE +
  • + READY_STATE_CHANGE_ERROR +
  • +
  • REGIONAL_SERVER
  • @@ -1008,13 +1019,6 @@

    Events

    @@ -1258,7 +1285,8 @@

    Parameters:

    - +

    PeerId of the peer to send local stream to.

    +
    @@ -1323,7 +1351,7 @@

    _addStereo

    - source\skyway.js:2237 + source\skyway.js:2522

    @@ -1331,10 +1359,15 @@

    _addStereo

    +

    Available since 0.2.0

    +
    -

    Add Stereo to SDP. Requires OPUS

    +

    Adds stereo feature to the SDP.

    +
    @@ -1353,7 +1386,8 @@

    Parameters:

    - +

    Sdp received.

    +
    @@ -1432,7 +1466,7 @@

    _alphanumeric

    - source\skyway.js:3372 + source\skyway.js:3651

    @@ -1440,12 +1474,16 @@

    _alphanumeric

    +

    Available since 0.2.0

    +
    -

    Check if a text string consist of only alphanumeric characters. -If so, return true. -If not, return false.

    +

    Check if a string consist of only alphanumeric characters.

    +
    @@ -1545,7 +1583,7 @@

    Triggers:

    - source\skyway.js:2711 + source\skyway.js:2950

    @@ -1553,10 +1591,12 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    Handling reception of an answer (to a previous offer). handshake step 4.

    +

    Handles the reception of an answer (to a previous offer). handshake step 4.

    @@ -1710,7 +1750,7 @@

    _base64ToBlob

    - source\skyway.js:3296 + source\skyway.js:3573

    @@ -1718,13 +1758,15 @@

    _base64ToBlob

    +

    Available since 0.1.0

    +
    -

    Convert base64 to raw binary data held in a string. -Doesn't handle URLEncoded DataURIs

    +

    Converts base64 string to raw binary data.

    @@ -1745,7 +1787,8 @@

    Parameters:

    - +

    Blob base64 dataurl.

    +
    @@ -1811,7 +1854,7 @@

    Triggers:

    - source\skyway.js:1833 + source\skyway.js:2079

    @@ -1819,6 +1862,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -1841,7 +1886,8 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -1854,7 +1900,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -1868,7 +1914,7 @@

    Parameters:

    -

    TargetMid.

    +

    PeerId of the peer that has left the room.

    @@ -1882,7 +1928,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -1948,7 +1994,7 @@

    _candidateHandler

    - source\skyway.js:2665 + source\skyway.js:2903

    @@ -1956,10 +2002,12 @@

    _candidateHandler

    +

    Available since 0.1.0

    +
    -

    Handling reception of a candidate. handshake done, connection ongoing.

    +

    Handles the reception of a candidate. handshake done, connection ongoing.

    @@ -2095,8 +2143,8 @@

    Parameters:

    -
    -

    _chatHandler

    +
    +

    _checkDataChannelStatus

    @@ -2104,7 +2152,7 @@

    _chatHandler

  • - message + dc
  • @@ -2131,7 +2179,7 @@

    _chatHandler

    Triggers:

    - chatMessageReceived + dataChannelState

    @@ -2146,7 +2194,7 @@

    Triggers:

    - source\skyway.js:1700 + source\skyway.js:3116

    @@ -2154,10 +2202,16 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    Throw an event with the received chat message

    +

    Checks datachannel ready state.

    +
      +
    • If ready, it sends a +Skyway/CONN:event.
    • +
    @@ -2169,104 +2223,17 @@

    Parameters:

  • - message - JSON + dc + Object
    - -
    - - -
      - -
    • - - rid - String - - -
      -

      RoomId

      - -
      - - -
    • - -
    • - - mid - String - - -
      -

      TargetMid.

      - -
      - - -
    • - -
    • - - target - String - - -
      -

      targetPeerId. For private message

      - -
      - - -
    • - -
    • - - data - String - - -
      -

      Chat message

      - -
      - - -
    • - -
    • - - sender - String - - -
      -

      senderPeerId

      - -
      - - -
    • - -
    • - - type - String - - -
      -

      Message type

      +

      The datachannel object.

      -
      +
  • - - - - @@ -2279,8 +2246,8 @@

    Parameters:

    -
    -

    _checkDataChannelStatus

    +
    +

    _chunkFile

    @@ -2288,7 +2255,13 @@

    _checkDataChannelStatus

  • - dc + blob + +
  • + +
  • + + blobByteSize
  • @@ -2313,11 +2286,6 @@

    _checkDataChannelStatus

    -

    -

    Triggers:

    - dataChannelState -

    -
    @@ -2330,7 +2298,7 @@

    Triggers:

    - source\skyway.js:2869 + source\skyway.js:3596

    @@ -2338,10 +2306,12 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    Check DataChannel ReadyState. If ready, it sends a 'CONN'

    +

    Chunks blob data into chunks.

    @@ -2353,14 +2323,30 @@

    Parameters:

  • - dc - Object + blob + Blob + + + + +
    +

    The blob data to chunk.

    + +
    + + +
  • + +
  • + + blobByteSize + Integer
    -

    DataChannel object

    +

    The blob data size.

    @@ -2376,8 +2362,8 @@

    Parameters:

  • -
    -

    _chunkFile

    +
    +

    _clearDataChannelTimeout

    @@ -2385,126 +2371,13 @@

    _chunkFile

  • - blob + peerId
  • - blobByteSize - -
  • - - ) -
    - - - - - - - - private - - - - - - - - - - - - -
    - - - -

    - - Defined in - - - - - source\skyway.js:3318 - -

    - - - - - -
    - -
    -

    To chunk the File (which already is a blob) into smaller blob files. -For now please send files below or around 2KB till chunking is implemented

    - -
    - - -
    -

    Parameters:

    - -
      - -
    • - - blob - Blob - - - - -
      - -
      - - -
    • - -
    • - - blobByteSize - Integer - - - - -
      - -
      - - -
    • - -
    -
    - - - - - -
    - -
    -

    _clearDataChannelTimeout

    - - -
    - (
      - -
    • - - peerId - -
    • - -
    • - - isSender + isSender
    • @@ -2547,7 +2420,7 @@

      _clearDataChannelTimeout

      - source\skyway.js:3279 + source\skyway.js:3555

      @@ -2555,10 +2428,12 @@

      _clearDataChannelTimeout

      +

      Available since 0.1.0

      +
    -

    Clear the DataChannel timeout as a response is received

    +

    Clears the datachannel timeout.

    @@ -2577,7 +2452,8 @@

    Parameters:

    - +

    PeerId of the datachannel to clear timeout.

    +
    @@ -2592,7 +2468,8 @@

    Parameters:

    - +

    Is peer the sender or the receiver?

    +
    @@ -2607,7 +2484,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -2658,7 +2536,7 @@

    _closeChannel

    - source\skyway.js:2804 + source\skyway.js:3049

    @@ -2666,10 +2544,12 @@

    _closeChannel

    +

    Available since 0.1.0

    +
    -

    Close the Socket signaling connection.

    +

    Closes the socket signaling connection.

    @@ -2732,7 +2612,7 @@

    _closeDataChannel

    - source\skyway.js:2938 + source\skyway.js:3190

    @@ -2740,10 +2620,12 @@

    _closeDataChannel

    +

    Available since 0.1.0

    +
    -

    To obtain the Peer that it's connected to from the DataChannel

    +

    Closes the datachannel.

    @@ -2762,7 +2644,8 @@

    Parameters:

    - +

    PeerId of the peer's datachannel to close.

    +
    @@ -2777,7 +2660,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -2855,7 +2739,7 @@

    Triggers:

    - source\skyway.js:2818 + source\skyway.js:3064

    @@ -2863,6 +2747,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -2885,7 +2771,7 @@

    Parameters:

    -

    The peerId of which the dataChannel is connected to

    +

    PeerId of the peer which the datachannel is connected to

    @@ -2901,7 +2787,7 @@

    Parameters:

    -

    The callback which it returns the DataChannel object to

    +

    The callback fired when datachannel is created.

    @@ -2917,7 +2803,7 @@

    Parameters:

    -

    The DataChannel object passed inside

    +

    The datachannel object received.

    @@ -2983,7 +2869,7 @@

    _createPeerConnection

    - source\skyway.js:2540 + source\skyway.js:2776

    @@ -2991,10 +2877,12 @@

    _createPeerConnection

    +

    Available since 0.1.0

    +
    -

    Create a peerconnection to communicate with the peer whose ID is 'targetMid'. +

    Creates a peerconnection to communicate with the peer whose ID is 'targetMid'. All the peerconnection callbacks are set up here. This is a quite central piece.

    @@ -3106,7 +2994,7 @@

    Triggers:

    - source\skyway.js:3047 + source\skyway.js:3313

    @@ -3114,12 +3002,12 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    DataChannel TFTP Protocol Stage: ACK -The user sends a ACK of the request [accept/reject/nhe current -index of chunk to be sent over]

    +

    The user receives an acknowledge of the blob request.

    @@ -3138,7 +3026,8 @@

    Parameters:

    - +

    PeerId of the peer that is sending the acknowledgement.

    +
    @@ -3153,7 +3042,8 @@

    Parameters:

    - +

    The data object received from datachannel.

    +
    @@ -3168,7 +3058,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -3231,7 +3122,7 @@

    _dataChannelCHATHandler

    Triggers:

    - dataTransferState + incomingMessage

    @@ -3246,7 +3137,7 @@

    Triggers:

    - source\skyway.js:3103 + source\skyway.js:3368

    @@ -3254,11 +3145,12 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    DataChannel TFTP Protocol Stage: CHAT -The user receives a DataChannel CHAT message

    +

    The user receives a datachannel broadcast message.

    @@ -3277,7 +3169,8 @@

    Parameters:

    - +

    PeerId of the peer that is sending a broadcast message.

    +
    @@ -3292,7 +3185,8 @@

    Parameters:

    - +

    The data object received from datachannel.

    +
    @@ -3307,7 +3201,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -3391,7 +3286,7 @@

    Triggers:

    - source\skyway.js:3167 + source\skyway.js:3440

    @@ -3399,11 +3294,12 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    DataChannel TFTP Protocol Stage: DATA -This is when the data is sent from the sender to the receiving user

    +

    This is when the data is sent from the sender to the receiving user.

    @@ -3422,7 +3318,8 @@

    Parameters:

    - +

    PeerId of the peer that is sending the data.

    +
    @@ -3437,7 +3334,8 @@

    Parameters:

    - +

    The data received.

    +
    @@ -3452,7 +3350,8 @@

    Parameters:

    -

    [Rel: Skyway.DATA_TRANSFER_DATA_TYPE]

    +

    The data type received from datachannel. + [Rel: Skyway.DATA_TRANSFER_DATA_TYPE]

    @@ -3468,7 +3367,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -3546,7 +3446,7 @@

    Triggers:

    - source\skyway.js:3143 + source\skyway.js:3416

    @@ -3554,11 +3454,12 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    DataChannel TFTP Protocol Stage: ERROR -The user received an error, usually an exceeded timeout.

    +

    The user receives a timeout error.

    @@ -3577,7 +3478,8 @@

    Parameters:

    - +

    PeerId of the peer that is sending the error.

    +
    @@ -3592,7 +3494,8 @@

    Parameters:

    - +

    The data object received from datachannel.

    +
    @@ -3607,7 +3510,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -3668,7 +3572,7 @@

    _dataChannelHandler

    - source\skyway.js:2956 + source\skyway.js:3209

    @@ -3676,10 +3580,12 @@

    _dataChannelHandler

    +

    Available since 0.1.0

    +
    -

    The Handler for all DataChannel Protocol events

    +

    Handles all datachannel protocol events.

    @@ -3692,13 +3598,14 @@

    Parameters:

  • data - String + String | Object
    - +

    The data received from datachannel.

    +
    @@ -3767,7 +3674,7 @@

    _dataChannelPeer

    - source\skyway.js:2926 + source\skyway.js:3177

    @@ -3775,10 +3682,12 @@

    _dataChannelPeer

    +

    Available since 0.1.0

    +
    -

    To obtain the Peer that it's connected to from the DataChannel

    +

    Obtains the peerId of the peer connected to the datachannel.

    @@ -3797,7 +3706,8 @@

    Parameters:

    - +

    The datachannel name.

    +
    @@ -3812,7 +3722,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -3890,7 +3801,7 @@

    Triggers:

    - source\skyway.js:3003 + source\skyway.js:3250

    @@ -3898,11 +3809,12 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    DataChannel TFTP Protocol Stage: WRQ -The sender has sent a request to send file +

    The user receives a blob request. From here, it's up to the user to accept or reject it

    @@ -3922,7 +3834,8 @@

    Parameters:

    - +

    PeerId of the peer that is sending the request.

    +
    @@ -3937,7 +3850,8 @@

    Parameters:

    - +

    The data object received from datachannel.

    +
    @@ -3952,7 +3866,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -4013,7 +3928,7 @@

    _doAnswer

    - source\skyway.js:2083 + source\skyway.js:2361

    @@ -4021,6 +3936,8 @@

    _doAnswer

    +

    Available since 0.1.0

    +
    @@ -4044,7 +3961,7 @@

    Parameters:

    -

    The peer we should connect to.

    +

    PeerId of the peer to send answer to.

    @@ -4106,7 +4023,7 @@

    _doCall

    - source\skyway.js:2182 + source\skyway.js:2464

    @@ -4114,6 +4031,8 @@

    _doCall

    +

    Available since 0.1.0

    +
    @@ -4136,7 +4055,8 @@

    Parameters:

    - +

    PeerId of the peer to send offer to.

    +
    @@ -4187,7 +4107,7 @@

    _enterHandler

    Triggers:

    - handshakeProgress + handshakeProgress, peerJoined

    @@ -4202,7 +4122,7 @@

    Triggers:

    - source\skyway.js:1942 + source\skyway.js:2206

    @@ -4210,6 +4130,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -4233,7 +4155,8 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -4246,7 +4169,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -4260,7 +4183,7 @@

    Parameters:

    -

    TargetMid.

    +

    PeerId of the peer that is sending the enter shake.

    @@ -4274,7 +4197,7 @@

    Parameters:

    -

    Browser agent

    +

    Peer's browser agent.

    @@ -4288,7 +4211,7 @@

    Parameters:

    -

    Browser version

    +

    Peer's browser version.

    @@ -4302,7 +4225,7 @@

    Parameters:

    -

    Peer Skyway._user.info data.

    +

    Peer's user information.

    @@ -4316,7 +4239,7 @@

    Parameters:

    - Peer stream settings + Peer's stream settings
  • @@ -4415,7 +4338,7 @@

    Parameters:

    - If Peer's Audio stream is muted. + If peer's audio stream is muted.
    @@ -4426,7 +4349,7 @@

    Parameters:

    - If Peer's Video stream is muted. + If peer's video stream is muted.
    @@ -4518,7 +4441,7 @@

    _errorHandler

    - source\skyway.js:1718 + source\skyway.js:1955

    @@ -4526,6 +4449,8 @@

    _errorHandler

    +

    Available since 0.1.0

    +
    @@ -4561,7 +4486,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -4575,7 +4500,7 @@

    Parameters:

    -

    TargetMid.

    +

    PeerId of the peer that is sending the error message.

    @@ -4589,7 +4514,7 @@

    Parameters:

    -

    Error type

    +

    The error kind.

    @@ -4603,7 +4528,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -4685,7 +4610,7 @@

    _findSDPLine

    - source\skyway.js:2212 + source\skyway.js:2495

    @@ -4693,10 +4618,15 @@

    _findSDPLine

    +

    Available since 0.2.0

    +
    -

    Find a line in the SDP and return it

    +

    Finds a line in the SDP and returns it.

    +
    @@ -4715,7 +4645,8 @@

    Parameters:

    - +

    Sdp received.

    +
    @@ -4730,7 +4661,8 @@

    Parameters:

    - +

    The conditions.

    +
    @@ -4790,13 +4722,7 @@

    _handleAV

  • - isEnabled - -
  • - -
  • - - hasMedia + enableMedia
  • @@ -4838,7 +4764,7 @@

    Triggers:

    - source\skyway.js:3546 + source\skyway.js:3843

    @@ -4846,11 +4772,18 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    Restart the joinRoom() -process to initiate Audio and Video

    +

    Handles all audio and video mute events.

    +
    @@ -4869,22 +4802,9 @@

    Parameters:

    - -
    - - - - -
  • - - isEnabled - Boolean - +

    Media types expected to receive. + [Rel: 'audio' or 'video']

    - - -
    -
    @@ -4892,14 +4812,15 @@

    Parameters:

  • - hasMedia + enableMedia Boolean
    - +

    Enable it or disable it

    +
    @@ -4927,6 +4848,12 @@

    _handleLock

  • +
  • + + callback + +
  • + ) @@ -4965,7 +4892,7 @@

    Triggers:

    - source\skyway.js:3504 + source\skyway.js:3793

    @@ -4973,10 +4900,12 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    Handle the Lock actions

    +

    Handles all the room lock events.

    @@ -4995,7 +4924,25 @@

    Parameters:

    -

    [Rel: SkywayDemo.LOCK_ACTION]

    +

    Lock action to send to server for response. + [Rel: SkywayDemo.LOCK_ACTION]

    + +
    + + + + +
  • + + callback + Function + + + + +
    +

    The callback to return the response after + everything's loaded.

    @@ -5062,7 +5009,7 @@

    Triggers:

    - source\skyway.js:1901 + source\skyway.js:2164

    @@ -5070,6 +5017,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -5092,7 +5041,8 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -5100,12 +5050,12 @@

    Parameters:

  • - pc_config - JSON + rid + String
    -

    The PeerConnection configuration

    +

    RoomId of the connected room.

    @@ -5119,7 +5069,7 @@

    Parameters:

    -

    Self peerId.

    +

    PeerId of self.

    @@ -5128,12 +5078,12 @@

    Parameters:

  • - rid + mid String
    -

    RoomId

    +

    PeerId of the peer that is

    @@ -5142,12 +5092,13 @@

    Parameters:

  • - mid - String + pc_config + JSON
    -

    TargetMid.

    +

    The peerconnection configuration + sending the joinRoom message.

    @@ -5161,7 +5112,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -5232,7 +5183,7 @@

    Triggers:

    - source\skyway.js:712 + source\skyway.js:834

    @@ -5240,6 +5191,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -5329,7 +5282,7 @@

    Triggers:

    - source\skyway.js:1791 + source\skyway.js:2033

    @@ -5337,10 +5290,12 @@

    Triggers:

    +

    Available since 0.2.0

    +
    -

    Peer Audio is muted/unmuted

    +

    Peer Audio is muted/unmuted.

    @@ -5359,7 +5314,8 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -5372,7 +5328,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -5386,7 +5342,8 @@

    Parameters:

    -

    TargetMid.

    +

    PeerId of the peer that is sending + their own updated audio stream status.

    @@ -5414,7 +5371,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -5485,7 +5442,7 @@

    Triggers:

    - source\skyway.js:1812 + source\skyway.js:2056

    @@ -5493,10 +5450,12 @@

    Triggers:

    +

    Available since 0.2.0

    +
    -

    Peer Video is muted/unmuted

    +

    Peer Video is muted/unmuted.

    @@ -5515,7 +5474,8 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -5528,7 +5488,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -5542,7 +5502,8 @@

    Parameters:

    -

    TargetMid.

    +

    PeerId of the peer that is sending + their own updated video streams status.

    @@ -5570,7 +5531,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -5641,7 +5602,7 @@

    Triggers:

    - source\skyway.js:2048 + source\skyway.js:2326

    @@ -5649,6 +5610,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -5672,7 +5635,8 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -5685,7 +5649,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -5699,21 +5663,7 @@

    Parameters:

    -

    TargetMid.

    - -
    - - -
  • - -
  • - - target - String - - -
    -

    targetPeerId

    +

    PeerId of the peer that is sending the offer shake.

    @@ -5741,7 +5691,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -5818,7 +5768,7 @@

    Triggers:

    - source\skyway.js:2620 + source\skyway.js:2857

    @@ -5826,6 +5776,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -5922,7 +5874,7 @@

    _onRemoteStreamAdded

    Triggers:

    - addPeerStream + incomingStream

    @@ -5937,7 +5889,7 @@

    Triggers:

    - source\skyway.js:2168 + source\skyway.js:2449

    @@ -5945,6 +5897,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -5968,7 +5922,8 @@

    Parameters:

    - +

    PeerId of the peer that has remote stream to send.

    +
    @@ -6056,7 +6011,7 @@

    Triggers:

    - source\skyway.js:1580 + source\skyway.js:1838

    @@ -6064,6 +6019,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -6175,7 +6132,7 @@

    Triggers:

    - source\skyway.js:1559 + source\skyway.js:1811

    @@ -6183,6 +6140,8 @@

    Triggers:

    +

    Available since 0.3.0

    +
    @@ -6278,7 +6237,7 @@

    Triggers:

    - source\skyway.js:2756 + source\skyway.js:3000

    @@ -6286,10 +6245,12 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    Initiate a Socket signaling connection.

    +

    Initiate a socket signaling connection.

    @@ -6364,7 +6325,7 @@

    _openPeer

    - source\skyway.js:2110 + source\skyway.js:2389

    @@ -6372,6 +6333,8 @@

    _openPeer

    +

    Available since 0.1.0

    +
    @@ -6395,7 +6358,7 @@

    Parameters:

    -

    The peer we should connect to.

    +

    PeerId of the peer we should connect to.

    @@ -6411,7 +6374,7 @@

    Parameters:

    -

    The peer's browser

    +

    Peer's browser

    @@ -6516,7 +6479,7 @@

    Triggers:

    - source\skyway.js:659 + source\skyway.js:775

    @@ -6524,6 +6487,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -6624,7 +6589,7 @@

    _parseStreamSettings

    - source\skyway.js:3705 + source\skyway.js:4008

    @@ -6632,10 +6597,12 @@

    _parseStreamSettings

    +

    Available since 0.4.0

    +
    -

    Parse Stream settings

    +

    Parse stream settings

    @@ -6654,10 +6621,171 @@

    Parameters:

    - +

    Optional. Media Constraints.

    +
    + +
  • @@ -6720,7 +6848,7 @@

    Triggers:

    - source\skyway.js:1849 + source\skyway.js:2096

    @@ -6728,6 +6856,8 @@

    Triggers:

    +

    Available since 0.4.0

    +
    @@ -6750,26 +6880,13 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -7004,7 +7124,7 @@

    _processSigMessage

    - source\skyway.js:1600 + source\skyway.js:1859

    @@ -7012,12 +7132,16 @@

    _processSigMessage

    +

    Available since 0.1.0

    +
    -

    Handle every incoming message. If it's a bundle, extract single messages -Eventually handle the message(s) to -Skyway/_processSingleMessage:method

    +

    Handle every incoming message. If it's a bundle, extract single messages

    +
    @@ -7030,7 +7154,7 @@

    Parameters:

  • messageString - JSON + String @@ -7102,7 +7226,7 @@

    Triggers:

    - source\skyway.js:1867 + source\skyway.js:2121

    @@ -7110,6 +7234,8 @@

    Triggers:

    +

    Available since 0.4.0

    +
    @@ -7132,7 +7258,8 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -7140,12 +7267,12 @@

    Parameters:

  • - sender - String + data + JSON | String
    -

    The senderPeerId.

    +

    The data broadcasted

    @@ -7154,12 +7281,12 @@

    Parameters:

  • - data - JSON | String + rid + String
    -

    The Data broadcasted

    +

    RoomId of the connected room.

    @@ -7168,12 +7295,12 @@

    Parameters:

  • - nick + cid String
    -

    Deprecated. Nickname of the user

    +

    CredentialId of the room

    @@ -7187,7 +7314,8 @@

    Parameters:

    -

    TargetMid

    +

    PeerId of the peer that is sending a private + broadcast message

    @@ -7196,12 +7324,12 @@

    Parameters:

  • - cid - String + isDataChannel + Boolean
    -

    The credentialId

    +

    Is the message sent from datachannel

    @@ -7210,26 +7338,12 @@

    Parameters:

  • - rid + type String
    -

    RoomId

    - -
    - - -
  • - -
  • - - type - String - - -
    -

    Message type

    +

    The type of message received.

    @@ -7300,7 +7414,7 @@

    Triggers:

    - source\skyway.js:1733 + source\skyway.js:1971

    @@ -7308,6 +7422,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -7330,7 +7446,8 @@

    Parameters:

    - +

    The message object.

    +
    @@ -7343,21 +7460,7 @@

    Parameters:

    -

    RoomId

    - -
    - - -
  • - -
  • - - mid - String - - -
    -

    TargetMid.

    +

    RoomId of the connected room.

    @@ -7371,7 +7474,7 @@

    Parameters:

    -

    Deprecated. Url to redirect to

    +

    Deprecated. Url to redirect to.

    @@ -7385,7 +7488,7 @@

    Parameters:

    -

    Reason for redirect

    +

    The reason for redirect

    @@ -7399,7 +7502,7 @@

    Parameters:

    -

    Action of the redirect +

    The action of the redirect [Rel: Skyway.SYSTEM_ACTION]

    @@ -7414,7 +7517,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -7443,13 +7546,13 @@

    _reinit

  • - callback + options
  • - options + callback
  • @@ -7491,7 +7594,7 @@

    Triggers:

    - source\skyway.js:952 + source\skyway.js:1107

    @@ -7499,10 +7602,12 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    Reinitialize Skyway signaling credentials

    +

    Re-initialize Skyway signaling credentials.

    @@ -7512,22 +7617,6 @@

    Parameters:

    @@ -7748,7 +7853,7 @@

    Triggers:

    - source\skyway.js:1885 + source\skyway.js:2146

    @@ -7756,11 +7861,13 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    Actually clean the peerconnection and trigger an event. Can be called by _byHandler -and leaveRoom.

    +

    Actually clean the peerconnection and trigger an event. +Can be called by _byHandler and leaveRoom.

    @@ -7779,7 +7886,7 @@

    Parameters:

    -

    Id of the peer to remove

    +

    PeerId of the peer that has left.

    @@ -7859,7 +7966,7 @@

    _requestServerInfo

    - source\skyway.js:628 + source\skyway.js:743

    @@ -7867,6 +7974,8 @@

    _requestServerInfo

    +

    Available since 0.2.0

    +
    @@ -8004,7 +8113,7 @@

    Triggers:

    - source\skyway.js:1774 + source\skyway.js:2013

    @@ -8012,10 +8121,12 @@

    Triggers:

    +

    Available since 0.2.0

    +
    -

    Room Lock is Fired

    +

    Room lock status is changed.

    @@ -8047,7 +8158,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -8061,7 +8172,8 @@

    Parameters:

    -

    TargetMid.

    +

    PeerId of the peer that is sending the + updated room lock status.

    @@ -8089,7 +8201,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -8167,7 +8279,7 @@

    _sendBlobDataToPeer

    - source\skyway.js:3469 + source\skyway.js:3755

    @@ -8175,11 +8287,16 @@

    _sendBlobDataToPeer

    +

    Available since 0.1.0

    +
    -

    Method to send Blob data to individual peer. -This sends the 'WRQ' and initiate the TFTP protocol.

    +

    Sends blob data to individual peer.

    +
    @@ -8198,9 +8315,7 @@

    Parameters:

    - +

    The blob data to be sent over.

    @@ -8216,9 +8331,7 @@

    Parameters:

    - +

    The data information.

    @@ -8232,7 +8345,7 @@

    Parameters:

    -

    The transfer Id

    +

    TransferId of the data.

    @@ -8246,7 +8359,7 @@

    Parameters:

    -

    The Blob data name

    +

    Data name.

    @@ -8260,8 +8373,8 @@

    Parameters:

    -

    The timeout to wait for packets. - Default is 60.

    +

    Data timeout to wait for packets. + [Default is 60].

    @@ -8275,7 +8388,7 @@

    Parameters:

    -

    The Blob data size

    +

    Data size

    @@ -8295,7 +8408,9 @@

    Parameters:

    - +

    PeerId targeted to receive data. + Leave blank to send to all peers.

    +
    @@ -8362,7 +8477,7 @@

    _sendDataChannel

    - source\skyway.js:2890 + source\skyway.js:3140

    @@ -8370,10 +8485,12 @@

    _sendDataChannel

    +

    Available since 0.1.0

    +
    -

    Sending of String Data over the DataChannels

    +

    Sends data to the datachannel.

    @@ -8392,7 +8509,8 @@

    Parameters:

    - +

    PeerId of the peer's datachannel to send data.

    +
    @@ -8407,7 +8525,8 @@

    Parameters:

    - +

    The data to send.

    +
    @@ -8468,7 +8587,7 @@

    _sendMessage

    - source\skyway.js:2740 + source\skyway.js:2980

    @@ -8476,10 +8595,17 @@

    _sendMessage

    +

    Available since 0.1.0

    +
    -

    Send a message to the signaling server

    +

    Sends a message to the signaling server.

    +
    @@ -8577,7 +8703,7 @@

    _setDataChannelTimeout

    - source\skyway.js:3244 + source\skyway.js:3518

    @@ -8585,10 +8711,15 @@

    _setDataChannelTimeout

    +

    Available since 0.1.0

    +
    -

    Set the DataChannel timeout. If exceeded, send the 'ERROR' message

    +

    Sets the datachannel timeout.

    +
    @@ -8607,7 +8738,8 @@

    Parameters:

    - +

    PeerId of the datachannel to set timeout.

    +
    @@ -8622,7 +8754,8 @@

    Parameters:

    - +

    The timeout to set in seconds.

    +
    @@ -8637,7 +8770,8 @@

    Parameters:

    - +

    Is peer the sender or the receiver?

    +
    @@ -8652,7 +8786,8 @@

    Parameters:

    - +

    Skyway object.

    +
    @@ -8685,6 +8820,10 @@

    _setFirefoxIceServers

    + + JSON + + @@ -8713,7 +8852,7 @@

    _setFirefoxIceServers

    - source\skyway.js:2357 + source\skyway.js:2646

    @@ -8721,10 +8860,12 @@

    _setFirefoxIceServers

    +

    Available since 0.1.0

    +
    -

    This sets the STUN server specially for Firefox for ICE Connection

    +

    Sets the STUN server specially for Firefox for ICE Connection.

    @@ -8743,7 +8884,8 @@

    Parameters:

    - +

    Ice configuration servers url object.

    +
    @@ -8754,6 +8896,20 @@

    Parameters:

    +
    +

    Returns:

    + +
    + + + JSON: + +

    Updated configuration

    + + +
    +
    + @@ -8815,7 +8971,7 @@

    Triggers:

    - source\skyway.js:2295 + source\skyway.js:2583

    @@ -8823,6 +8979,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -8846,7 +9004,8 @@

    Parameters:

    - +

    PeerId of the peer to send offer/answer to.

    +
    @@ -8928,7 +9087,7 @@

    _setSDPBitrate

    - source\skyway.js:2265 + source\skyway.js:2552

    @@ -8936,6 +9095,8 @@

    _setSDPBitrate

    +

    Available since 0.2.0

    +
    @@ -8958,7 +9119,8 @@

    Parameters:

    - +

    Sdp received.

    +
    @@ -9037,7 +9199,7 @@

    _setStreams

    - source\skyway.js:2498 + source\skyway.js:2733

    @@ -9045,10 +9207,12 @@

    _setStreams

    +

    Available since 0.3.0

    +
    -

    Close/Open existing mediaStreams

    +

    Opens or closes existing MediaStreams.

    @@ -9178,7 +9342,7 @@

    _stripNonAlphanumeric

    - source\skyway.js:3347 + source\skyway.js:3625

    @@ -9186,10 +9350,12 @@

    _stripNonAlphanumeric

    +

    Available since 0.2.0

    +
    -

    Removes non-alphanumeric characters from a string and return it.

    +

    Removes non-alphanumeric characters from a string.

    @@ -9284,7 +9450,7 @@

    _trigger

    - source\skyway.js:804 + source\skyway.js:949

    @@ -9292,12 +9458,16 @@

    _trigger

    +

    Available since 0.1.0

    +
    -

    Trigger all the callbacks associated with an event -Note that extra arguments can be passed to the callback -which extra argument can be expected by callback is documented by each event

    +

    Trigger all the callbacks associated with an event

    +
    @@ -9382,7 +9552,7 @@

    Triggers:

    - source\skyway.js:1752 + source\skyway.js:1990

    @@ -9390,10 +9560,12 @@

    Triggers:

    +

    Available since 0.2.0

    +
    -

    User Information is updated

    +

    User information is updated.

    @@ -9412,7 +9584,8 @@

    Parameters:

    - +

    The message object.

    +
    @@ -9425,7 +9598,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -9439,7 +9612,8 @@

    Parameters:

    -

    TargetMid.

    +

    PeerId of the peer that is sending the + updated event.

    @@ -9453,7 +9627,7 @@

    Parameters:

    -

    The Skyway._user.info.userData data.

    +

    The peer's user data.

    @@ -9467,7 +9641,7 @@

    Parameters:

    -

    Message type

    +

    The type of message received.

    @@ -9539,7 +9713,7 @@

    _waitForMediaStream

    - source\skyway.js:2392 + source\skyway.js:2683

    @@ -9547,11 +9721,16 @@

    _waitForMediaStream

    +

    Available since 0.4.0

    +
    -

    Waits for MediaStream. Once the stream is loaded, callback is called -If there's not a need for stream, callback is called

    +

    Waits for MediaStream.

    +
    @@ -9798,7 +9977,7 @@

    _welcomeHandler

    Triggers:

    - handshakeProgress + handshakeProgress, peerJoined

    @@ -9813,7 +9992,7 @@

    Triggers:

    - source\skyway.js:2004 + source\skyway.js:2270

    @@ -9821,6 +10000,8 @@

    Triggers:

    +

    Available since 0.1.0

    +
    @@ -9844,7 +10025,8 @@

    Parameters:

    - +

    The message object received.

    +
    @@ -9857,7 +10039,7 @@

    Parameters:

    -

    RoomId

    +

    RoomId of the connected room.

    @@ -9871,7 +10053,7 @@

    Parameters:

    -

    TargetMid.

    +

    PeerId of the peer that is sending the welcome shake.

    @@ -10164,7 +10346,7 @@

    Triggers:

    - source\skyway.js:3633 + source\skyway.js:3967

    @@ -10172,11 +10354,15 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    Disable Microphone. If Microphone is not enabled from the -beginning, there is no effect.

    +

    Disable microphone.

    +
    @@ -10235,7 +10421,7 @@

    Triggers:

    - source\skyway.js:3683 + source\skyway.js:3995

    @@ -10243,11 +10429,15 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    Disable Webcam Video. If Webcam Video is not enabled from the -beginning, there is no effect.

    +

    Disable webcam video.

    +
    @@ -10306,7 +10496,7 @@

    Triggers:

    - source\skyway.js:3606 + source\skyway.js:3952

    @@ -10314,13 +10504,17 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    Enable Microphone. If Microphone is not enabled from the -beginning, user would have to reinitate the +

    Enable microphone.

    +
    @@ -10379,7 +10573,7 @@

    Triggers:

    - source\skyway.js:3655 + source\skyway.js:3980

    @@ -10387,13 +10581,17 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    Enable Webcam Video. If Webcam Video is not enabled from the -beginning, user would have to reinitate the +

    Enable webcam video.

    +
    @@ -10461,7 +10659,7 @@

    getPeerInfo

    - source\skyway.js:1133 + source\skyway.js:1295

    @@ -10469,10 +10667,16 @@

    getPeerInfo

    +

    Available since 0.4.0

    +
    -

    Get the Peer Information

    +

    Gets the peer information.

    +
    @@ -10522,7 +10726,10 @@

    Returns:

    Example:

    -                

    var peerInfo = SkywayDemo.getPeerInfo(peerId);

    +

    // Example 1: To get other peer's information + var peerInfo = SkywayDemo.getPeerInfo(peerId);

    +

    // Example 2: To get own information + var userInfo = SkywayDemo.getPeerInfo();

    @@ -10538,7 +10745,7 @@

    getUserData

    - JSON + JSON | @@ -10567,7 +10774,7 @@

    getUserData

    - source\skyway.js:1122 + source\skyway.js:1281

    @@ -10575,10 +10782,12 @@

    getUserData

    +

    Available since 0.4.0

    +
    -

    Get the User Information

    +

    Gets the user information.

    @@ -10591,7 +10800,7 @@

    Returns:

    - JSON: + JSON | :

    User information

    @@ -10661,7 +10870,7 @@

    Triggers:

    - source\skyway.js:1498 + source\skyway.js:1718

    @@ -10669,10 +10878,12 @@

    Triggers:

    +

    Available since 0.4.0

    +
    -

    Get the default cam and microphone

    +

    Get the default webcam and microphone

    @@ -10803,7 +11014,7 @@

    Example:

                     

    // Default is to get both audio and video - // Example 1: Get the default stream. + // Example 1: Get both audio and video by default. SkywayDemo.getUserMedia();

    // Example 2: Get the audio stream only SkywayDemo.getUserMedia({ @@ -10813,8 +11024,8 @@

    Example:

    // Example 3: Set the stream settings for the audio and video SkywayDemo.getUserMedia({ 'video' : { - resolution: SkywayDemo.VIDEO_RESOLUTION.HD, - frameRate: 50 + 'resolution': SkywayDemo.VIDEO_RESOLUTION.HD, + 'frameRate': 50 }, 'audio' : { stereo: true } });

    @@ -10873,7 +11084,7 @@

    Triggers:

    - source\skyway.js:824 + source\skyway.js:978

    @@ -10881,12 +11092,16 @@

    Triggers:

    +

    Available since 0.3.0

    +
    -

    IMPORTANT: Please call this method to load all server information before joining -the room or doing anything else. -This is Init function to load Skyway.

    +

    Initialize Skyway

    +
      +
    • IMPORTANT: Please call this method to load all server +information before joining the room or doing anything else.
    • +
    @@ -10974,7 +11189,7 @@

    Parameters:

  • iceTrickle - String + Boolean
    @@ -10989,7 +11204,7 @@

    Parameters:

  • dataChannel - String + Boolean
    @@ -11004,7 +11219,7 @@

    Parameters:

  • credentials - String + JSON
    @@ -11108,6 +11323,83 @@

    Example:

  • + + +
    +

    isRoomLocked

    + + + () + + + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + source\skyway.js:3930 + +

    + + + + + +

    Available since 0.4.0

    + +
    + +
    +

    Get the lock status of the room.

    +
      +
    • WARNING: If there's too many peers toggling the +room lock feature at the same time, the returned results may not +be completely correct since while retrieving the room lock status, +another peer may be toggling it.
    • +
    + +
    + + + + + + +
    +

    Example:

    + +
    +                

    if(SkywayDemo.isRoomLocked()) { + SkywayDemo.unlockRoom(); + } else { + SkywayDemo.lockRoom(); + }

    + +
    +
    +
    @@ -11165,7 +11457,7 @@

    Triggers:

    - source\skyway.js:3772 + source\skyway.js:4097

    @@ -11173,13 +11465,18 @@

    Triggers:

    +

    Available since 0.2.0

    +
    -

    User to join the room. -You may call getUserMedia() -first if you want to get -MediaStream and joining Room seperately.

    +

    User to join the room.

    +
    @@ -11343,7 +11640,7 @@

    Parameters:

  • audio - String + Integer
    @@ -11354,7 +11651,7 @@

    Parameters:

  • video - String + Integer
    @@ -11365,7 +11662,7 @@

    Parameters:

  • data - String + Integer
    @@ -11393,11 +11690,14 @@

    Example:

                     

    // To just join the default room without any video or audio + // Note that calling joinRoom without any parameters + // Still sends any available existing MediaStreams allowed. + // See Examples 2, 3, 4 and 5 etc to prevent video or audio stream SkywayDemo.joinRoom();

    // To just join the default room with bandwidth settings SkywayDemo.joinRoom({ - bandwidth: { - data: 14440 + 'bandwidth': { + 'data': 14440 } });

    // Example 1: To call getUserMedia and joinRoom seperately @@ -11417,7 +11717,7 @@

    Example:

    SkywayDemo.joinRoom('room', { 'audio' : true, 'video' : { - 'res' : { + 'resolution' : { 'width' : 640, 'height' : 320 } @@ -11425,9 +11725,9 @@

    Example:

    });

    // Example 5: Join a room with userData and settings with audio, video and bandwidth SkwayDemo.joinRoom({ - 'userData': { - item1: 'My custom data', - item2: 'Put whatever, string or JSON or array' + 'user': { + 'item1': 'My custom data', + 'item2': 'Put whatever, string or JSON or array' }, 'audio' : { 'stereo' : true @@ -11487,7 +11787,7 @@

    Triggers:

    - source\skyway.js:3896 + source\skyway.js:4228

    @@ -11495,10 +11795,12 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    User to leave the room

    +

    User to leave the room.

    @@ -11557,7 +11859,7 @@

    Triggers:

    - source\skyway.js:3580 + source\skyway.js:3906

    @@ -11565,10 +11867,12 @@

    Triggers:

    +

    Available since 0.2.0

    +
    -

    Lock the Room to prevent users from coming in

    +

    Lock the room to prevent peers from joining.

    @@ -11638,7 +11942,7 @@

    off

    - source\skyway.js:781 + source\skyway.js:925

    @@ -11646,10 +11950,12 @@

    off

    +

    Available since 0.1.0

    +
    -

    Let app unregister a callback function from an event

    +

    To unregister a callback function from an event.

    @@ -11668,7 +11974,8 @@

    Parameters:

    - +

    The Skyway event.

    +
    @@ -11683,7 +11990,8 @@

    Parameters:

    - +

    The callback everytime the event is fired.

    +
    @@ -11757,7 +12065,7 @@

    on

    - source\skyway.js:762 + source\skyway.js:905

    @@ -11765,10 +12073,12 @@

    on

    +

    Available since 0.1.0

    +
    -

    Let app register a callback function to an event

    +

    To register a callback function to an event.

    @@ -11787,7 +12097,8 @@

    Parameters:

    - +

    The Skyway event.

    +
    @@ -11802,7 +12113,8 @@

    Parameters:

    - +

    The callback everytime the event is fired.

    +
    @@ -11828,6 +12140,126 @@

    Example:

    + + +
    +

    respondBlobRequest

    + + +
    + (
      + +
    • + + peerId + +
    • + +
    • + + accept + +
    • + +
    ) +
    + + + + + + + + + + + + + + + + + +

    +

    Triggers:

    + dataTransferState +

    + + +
    + + + +

    + + Defined in + + + + + source\skyway.js:3286 + +

    + + + + + +

    Available since 0.4.0

    + +
    + +
    +

    User's response to accept or reject file.

    + +
    + + +
    +

    Parameters:

    + +
      + +
    • + + peerId + String + + + + +
      +

      PeerId of the peer that is expected to receive + the request response.

      + +
      + + +
    • + +
    • + + accept + Boolean + + + + +
      +

      Accept the Blob download request or not.

      + +
      + + +
    • + +
    +
    + + + + +
    @@ -11891,7 +12323,7 @@

    Triggers:

    - source\skyway.js:3389 + source\skyway.js:3669

    @@ -11899,11 +12331,18 @@

    Triggers:

    +

    Available since 0.1.0

    +
    -

    Method to send Blob data to peers. -Peers have the option to download or reject the file.

    +

    Sends blob data to peer(s).

    +
      +
    • Note that peers have the option to download or reject receiving the blob data.
    • +
    • This method is ideal for sending files.
    • +
    • To send a private file to a peer, input the peerId after the +data information.
    • +
    @@ -11922,9 +12361,7 @@

    Parameters:

    -
      -
    • The Blob data to be sent over
    • -
    +

    The blob data to be sent over.

    @@ -11940,15 +12377,27 @@

    Parameters:

    -
      -
    • The Blob data information
    • -
    +

    The data information.

    - - - - - - - -
    - -

    SIG_TYPE

    - JSON - - - - - private - - - - - - - - - - - - readonly - - -
    - - - -

    - - Defined in - - - - - source\skyway.js:222 - -

    - - - - -
    - -
    -

    Signaling message type. These message types are fixed. -(Legend: S - Send only. R - Received only. SR - Can be Both). -Signaling types are:

    - -
    - - - - - - -
    -

    Keys:

    - -
      -
    • - JOIN_ROOM - String + API_CREDENTIALS_NOT_MATCH + Integer
      -

      S. Join the Room

      +

      Api Key credentials does not + match what is expected.

      @@ -16747,14 +17065,15 @@

      Keys:

    • - IN_ROOM - String + API_INVALID_PARENT_KEY + Integer
      -

      R. User has already joined the Room

      +

      Api Key does not have a parent key + nor is a root key.

      @@ -16763,14 +17082,15 @@

      Keys:

    • - ENTER - String + API_NOT_ENOUGH_CREDIT + Integer
      -

      SR. Enter from handshake

      +

      Api Key does not have enough credits + to use.

      @@ -16779,14 +17099,15 @@

      Keys:

    • - WELCOME - String + API_NOT_ENOUGH_PREPAID_CREDIT + Integer
      -

      SR. Welcome from handshake

      +

      Api Key does not have enough + prepaid credits to use.

      @@ -16795,14 +17116,15 @@

      Keys:

    • - OFFER - String + API_FAILED_FINDING_PREPAID_CREDIT + Integer
      -

      SR. Offer from handshake

      +

      Api Key preapid payments + does not exist.

      @@ -16811,14 +17133,15 @@

      Keys:

    • - ANSWER - String + API_NO_MEETING_RECORD_FOUND + Integer
      -

      SR. Answer from handshake

      +

      Api Key does not have a meeting + record at this timing. This occurs when Api Key is a static one.

      @@ -16827,14 +17150,14 @@

      Keys:

    • - CANDIDATE - String + ROOM_LOCKED + Integer
      -

      SR. Candidate received

      +

      Room is locked.

      @@ -16843,14 +17166,14 @@

      Keys:

    • - BYE - String + NO_SOCKET_IO + Integer
      -

      R. Peer left the room

      +

      No socket.io dependency is loaded to use.

      @@ -16859,14 +17182,15 @@

      Keys:

    • - CHAT - String + NO_XMLHTTPREQUEST_SUPPORT + Integer
      -

      SR. Chat message relaying

      +

      Browser does not support + XMLHttpRequest to use.

      @@ -16875,14 +17199,14 @@

      Keys:

    • - REDIRECT - String + NO_WEBRTC_SUPPORT + Integer
      -

      R. Server redirecting User

      +

      Browser does not have WebRTC support.

      @@ -16891,14 +17215,14 @@

      Keys:

    • - ERROR - String + NO_PATH + Integer
      -

      R. Server occuring an error

      +

      No path is loaded yet.

      @@ -16907,62 +17231,98 @@

      Keys:

    • - INVITE - String + INVALID_XMLHTTPREQUEST_STATUS + Integer
      -

      SR. TODO.

      +

      Invalid XMLHttpRequest + when retrieving information.

    • -
    • - - UPDATE_USER - String - +
    +
    + - + +
    -
    -

    SR. Update of User information

    + +
    + +

    REGIONAL_SERVER

    + JSON -
    + - -
  • + + + + + + + + + + + + readonly + + +
    + -
  • - - ROOM_LOCK - String - + +

    + + Defined in + + + + + source\skyway.js:32 + +

    - + -
    -

    SR. Locking of Room

    + +

    Available since 0.3.0

    + +
    -
  • +
    +

    List of regional server for Skyway to connect to. +Default server is US1. Servers:

    - - +
    + + + + + + +
    +

    Keys:

    + +
    -
    - -

    SYSTEM_ACTION

    +
    + +

    SIG_TYPE

    JSON + private + @@ -17057,17 +17419,24 @@

    SYSTEM_ACTION

    - source\skyway.js:139 + source\skyway.js:293

    +

    Available since 0.3.0

    +
    -

    System actions received from Signaling server. System action outcomes are:

    +

    Signaling message type.

    +
      +
    • These message types are fixed.
    • +
    • (Legend: S - Send only. R - Received only. SR - Can be Both). +Signaling types are:
    • +
    @@ -17083,14 +17452,14 @@

    Keys:

  • - WARNING + JOIN_ROOM String
    -

    System is warning user that the room is closing

    +

    [S] Join the Room

    @@ -17099,14 +17468,14 @@

    Keys:

  • - REJECT + IN_ROOM String
    -

    System has rejected user from room

    +

    [R] User has already joined the Room

    @@ -17115,47 +17484,788 @@

    Keys:

  • - CLOSED + ENTER String
    -

    System has closed the room

    +

    [SR] Enter from handshake

  • - -
    - +
  • + + WELCOME + String + - - + + +
    +

    [SR] Welcome from handshake

    + +
    + + +
  • + +
  • + + OFFER + String + + + + +
    +

    [SR] Offer from handshake

    + +
    + + +
  • + +
  • + + ANSWER + String + + + + +
    +

    [SR] Answer from handshake

    + +
    + + +
  • + +
  • + + CANDIDATE + String + + + + +
    +

    [SR] Candidate received

    + +
    + + +
  • + +
  • + + BYE + String + + + + +
    +

    [R] Peer left the room

    + +
    + + +
  • + +
  • + + CHAT + String + + + + +
    +

    [SR] Deprecated. Chat message relaying

    + +
    + + +
  • + +
  • + + REDIRECT + String + + + + +
    +

    [R] Server redirecting User

    + +
    + + +
  • + +
  • + + ERROR + String + + + + +
    +

    [R] Server occuring an error

    + +
    + + +
  • + +
  • + + UPDATE_USER + String + + + + +
    +

    [SR] Update of User information

    + +
    + + +
  • + +
  • + + ROOM_LOCK + String + + + + +
    +

    [SR] Locking of Room

    + +
    + + +
  • + +
  • + + MUTE_VIDEO + String + + + + +
    +

    [SR] Muting of User's video

    + +
    + + +
  • + +
  • + + MUTE_AUDIO + String + + + + +
    +

    [SR] Muting of User's audio

    + +
    + + +
  • + +
  • + + PUBLIC_MESSAGE + String + + + + +
    +

    [SR] Sending a public broadcast message.

    + +
    + + +
  • + +
  • + + PRIVATE_MESSAGE + String + + + + +
    +

    [SR] Sending a private message

    + +
    + + +
  • + + + + + + + + + +
    + +

    SYSTEM_ACTION

    + JSON + + + + + + + + + + + + + + + readonly + + +
    + + + +

    + + Defined in + + + + + source\skyway.js:151 + +

    + + + + +

    Available since 0.1.0

    + +
    + +
    +

    System actions received from Signaling server. System action outcomes are:

    + +
    + + + + + + +
    +

    Keys:

    + +
      + +
    • + + WARNING + String + + + + +
      +

      System is warning user that the room is closing

      + +
      + + +
    • + +
    • + + REJECT + String + + + + +
      +

      System has rejected user from room

      + +
      + + +
    • + +
    • + + CLOSED + String + + + + +
      +

      System has closed the room

      + +
      + + +
    • + +
    +
    + + + +
    + + +
    + +

    VERSION

    + String + + + + + + + + + + + + + + + readonly + + +
    + + + +

    + + Defined in + + + + + source\skyway.js:24 + +

    + + + + +

    Available since 0.1.0

    + +
    + +
    +

    Version of Skyway

    + +
    + + + + + + + + +
    + + +
    + +

    VIDEO_RESOLUTION

    + JSON + + + + + + + + + + + + + + + readonly + + +
    + + + +

    + + Defined in + + + + + source\skyway.js:356 + +

    + + + + +

    Available since 0.2.0

    + +
    + +
    +

    Video Resolutions. Resolution types are:

    + +
    + + + + + + +
    +

    Keys:

    + +
      + +
    • + + QVGA + JSON + + + + +
      +

      QVGA video quality

      + +
      + + +
        + +
      • + + width + Integer + + +
        +

        320

        + +
        + + +
      • + +
      • + + height + Integer + + +
        +

        180

        + +
        + + +
      • + +
      + +
    • + +
    • + + VGA + JSON + + + + +
      +

      VGA video quality

      + +
      + + +
        + +
      • + + width + Integer + + +
        +

        640

        + +
        + + +
      • + +
      • + + height + Integer + + +
        +

        360

        + +
        + + +
      • + +
      + +
    • + +
    • + + HD + JSON + + + + +
      +

      HD video quality

      + +
      + + +
        + +
      • + + width + Integer + + +
        +

        1280

        + +
        + + +
      • + +
      • + + height + Integer + + +
        +

        720

        + +
        + + +
      • + +
      + +
    • + +
    • + + FHD + JSON + + + + +
      +

      Might not be supported. FullHD video quality.

      + +
      + + +
        + +
      • + + width + Integer + + +
        +

        1920

        + +
        + + +
      • + +
      • + + height + Integer + + +
        +

        1080

        + +
        + + +
      • + +
      + +
    • + +
    +
    + + + +
    + + + + + + +
    +

    Events

    + + +
    +

    candidateGenerationState

    + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + source\skyway.js:1369 + +

    - -
    - -

    VERSION

    - String + - + +

    Available since 0.1.0

    + +
    + +
    +

    Event fired during ICE gathering

    + +
    +
    +

    Event Payload:

    + +
      + +
    • + + state + String + + + + +
      +

      The current ice candidate generation state. + [Rel: Skyway.CANDIDATE_GENERATION_STATE]

      + +
      + + +
    • + +
    • + + peerId + String + + + + +
      +

      PeerId of the peer that had an ice candidate + generation state change.

      + +
      + +
    • + +
    +
    + +
    + + +
    +

    channelClose

    + - readonly +
    @@ -17169,49 +18279,109 @@

    VERSION

    - source\skyway.js:19 + source\skyway.js:1325

    +

    Available since 0.1.0

    +
    -

    Version of Skyway

    +

    Event fired when the channel has been closed.

    + +
    + + +
    +

    channelError

    + -
    - -
    - -

    VIDEO_RESOLUTION

    - JSON + +
    + + + +

    + + Defined in + + + + + source\skyway.js:1338 + +

    + + + + +

    Available since 0.1.0

    + +
    + +
    +

    Event fired when there was an error with the connection channel to the sig server.

    + +
    + +
    +

    Event Payload:

    + +
      + +
    • + + error + Object | String + + + + +
      +

      Error message or object thrown.

      + +
      + +
    • + +
    +
    + +
    + + +
    +

    channelMessage

    + - readonly +
    @@ -17225,245 +18395,201 @@

    VIDEO_RESOLUTION

    - source\skyway.js:283 + source\skyway.js:1331

    +

    Available since 0.1.0

    +
    -

    Video Resolutions. Resolution types are:

    +

    Event fired when we received a message from the signaling server.

    - - - -
    -

    Keys:

    +

    Event Payload:

    • - QVGA + message JSON
      -

      QVGA video quality

      - +
      -
        - -
      • - - width - Integer - +
      • + +
      +
    + -
    -

    320

    -
    + +
    - - - -
  • - - height - Integer - + +
    +

    channelOpen

    + -
    -

    180

    + -
    + - -
  • - - - - + + + + +
    + -
  • - - VGA - JSON - + +

    + + Defined in + + + + + source\skyway.js:1318 + +

    - + -
    -

    VGA video quality

    + +

    Available since 0.1.0

    + +
    -
  • +
    +

    Event fired when a successfull connection channel has been established +with the signaling server

    - -
      - -
    • - - width - Integer - +
    + + + + + +
    + + +
    +

    Datachannel: ACK

    + + + + + + private + + + + + + +
    + + + +

    + + Defined in + + + + + source\skyway.js:1602 + +

    -
    -

    640

    + -
    + +

    Available since 0.4.0

    + +
    - - - -
  • - - height - Integer - +
    +

    Fired when a datachannel has a blob data send request acknowledgement.

    +
      +
    • 0: User accepts the request.
    • +
    • -1: User rejects the request.
    • +
    • Above 0: User acknowledges the blob data packet.
    • +
    -
    -

    360

    +
    -
    + +
    +

    Event Payload:

    - -
  • - - - - +
    • - HD - JSON + ackN + Integer
      -

      HD video quality

      +

      The acknowledge number.

      -
        - -
      • - - width - Integer - - -
        -

        1280

        - -
        - - -
      • - -
      • - - height - Integer - - -
        -

        720

        - -
        - - -
      • - -
      -
    • - FHD - JSON + userAgent + Integer
      -

      Might not be supported. FullHD video quality.

      +

      The user's browser agent.

      -
        - -
      • - - width - Integer - - -
        -

        1920

        - -
        - - -
      • - -
      • - - height - Integer - - -
        -

        1080

        - -
        - - -
      • - -
      -
    +
    - - - - -
    -

    Events

    - - -
    -

    addPeerStream

    +
    +

    Datachannel: CHAT

    + private + @@ -17480,17 +18606,19 @@

    addPeerStream

    - source\skyway.js:1290 + source\skyway.js:1623

    +

    Available since 0.4.0

    +
    -

    Event fired when a remote stream has become available

    +

    Fired when a datachannel chat has been received.

    @@ -17502,14 +18630,19 @@

    Event Payload:

  • - peerId + type String
    - +

    If the message is a private or group message.

    +
      +
    • PRIVATE: This message is a private message targeted to a peer.
    • +
    • GROUP: This message is to be sent to all peers.
    • +
    +
    @@ -17517,14 +18650,15 @@

    Event Payload:

  • - stream - Object + peerId + String
    - +

    PeerId of the sender.

    +
    @@ -17532,14 +18666,15 @@

    Event Payload:

  • - isSelf - Boolean + message + JSON | String
    - +

    The message data or object.

    +
    @@ -17554,13 +18689,15 @@

    Event Payload:

  • -
    -

    candidateGenerationState

    +
    +

    Datachannel: CONN

    + private + @@ -17577,17 +18714,19 @@

    candidateGenerationState

    - source\skyway.js:1189 + source\skyway.js:1581

    +

    Available since 0.4.0

    +
    -

    Event fired during ICE gathering

    +

    Fired when a datachannel is successfully connected.

    @@ -17599,23 +18738,7 @@

    Event Payload:

  • - state - String - - - - -
    -

    [Rel: Skyway.CANDIDATE_GENERATION_STATE]

    - -
    - - -
  • - -
  • - - peerId + UNKNOWN String @@ -17637,13 +18760,15 @@

    Event Payload:

  • -
    -

    channelClose

    +
    +

    Datachannel: ERROR

    + private + @@ -17660,34 +18785,78 @@

    channelClose

    - source\skyway.js:1156 + source\skyway.js:1614

    +

    Available since 0.4.0

    +
    -

    Event fired when the channel has been closed.

    +

    Fired when a datachannel transfer has an error occurred.

    +
    +

    Event Payload:

    + +
      + +
    • + + message + String + + + + +
      +

      The error message.

      + +
      + + +
    • + +
    • + + isSender + Boolean + + + + +
      +

      If user's the uploader.

      + +
      + + +
    • + +
    +
    +
    -
    -

    channelError

    +
    +

    Datachannel: WRQ

    + private + @@ -17702,38 +18871,105 @@

    channelError

    Defined in - - - source\skyway.js:1167 - -

    + + + source\skyway.js:1590 + +

    + + + + +

    Available since 0.4.0

    + +
    + +
    +

    Fired when a datachannel has a blob data send request.

    + +
    + + +
    +

    Event Payload:

    + +
      + +
    • + + userAgent + String + + + + +
      +

      The user's browser agent.

      + +
      + + +
    • + +
    • + + name + String + + + + +
      +

      The blob data name.

      + +
      + + +
    • + +
    • + + size + Integer + - + - -
    +
    +

    The blob data size.

    -
    -

    Event fired when there was an error with the connection channel to the sig server.

    +
    -
    + + + +
  • + + chunkSize + Integer + - -
    -

    Event Payload:

    + -
      +
      +

      The expected chunk size.

      + +
      + + +
    • - error - String + timeout + Integer
      - +

      The timeout in seconds.

      +
      @@ -17748,8 +18984,8 @@

      Event Payload:

    -
    -

    channelMessage

    +
    +

    dataChannelState

    @@ -17771,17 +19007,19 @@

    channelMessage

    - source\skyway.js:1161 + source\skyway.js:1538

    +

    Available since 0.1.0

    +
    -

    Event fired when we received a message from the sig server..

    +

    Event fired when a peer's datachannel state has changed.

    @@ -17793,66 +19031,39 @@

    Event Payload:

  • - message - JSON + state + String
    - +

    The current datachannel state. + [Rel: Skyway.DATA_CHANNEL_STATE]

    +
  • - -
    - - - - -
    - - -
    -

    channelOpen

    - - - +
  • + + peerId + String + - + - +
    +

    PeerId of peer that has a datachannel state change.

    - +
    -
    - - - -

    - - Defined in - + +

  • - - - source\skyway.js:1150 - -

    - - - - -
    - -
    -

    Event fired when a successfull connection channel has been established -with the signaling server

    - -
    - + + @@ -17860,8 +19071,8 @@

    channelOpen

    -
    -

    chatMessageReceived

    +
    +

    dataTransferState

    @@ -17883,17 +19094,19 @@

    chatMessageReceived

    - source\skyway.js:1222 + source\skyway.js:1547

    +

    Available since 0.1.0

    +
    -

    Event fired when a chat message is received from other peers

    +

    Event fired when a data transfer state has changed.

    @@ -17905,14 +19118,16 @@

    Event Payload:

  • - message + state String
    - +

    The current data transfer state. + [Rel: Skyway.DATA_TRANSFER_STATE]

    +
    @@ -17920,14 +19135,15 @@

    Event Payload:

  • - senderPeerId + transferId String
    - +

    TransferId of the data

    +
    @@ -17935,14 +19151,16 @@

    Event Payload:

  • - userData - String | JSON + peerId + String
    - +

    PeerId of the peer that has a data + transfer state change.

    +
    @@ -17950,31 +19168,120 @@

    Event Payload:

  • - isPrivate - Boolean + transferInfo + JSON
    - +

    Transfer information.

    +
    -
  • - -
  • - - isSelf - Boolean - +
      + +
    • + + percentage + JSON + - +
      +

      The percetange of data being + uploaded / downloaded

      -
      - -
      +
      + + +
    • + +
    • + + senderPeerId + JSON + + +
      + +
      + + +
    • + +
    • + + data + JSON + + +
      +

      Blob data URL

      + +
      + + +
    • + +
    • + + name + JSON + + +
      +

      Blob data name

      + +
      + + +
    • + +
    • + + size + JSON + + +
      +

      Blob data size

      + +
      + + +
    • + +
    • + + message + JSON + + +
      +

      Error object thrown.

      + +
      + + +
    • + +
    • + + type + JSON + +
      +

      Where the error message occurred. + [Rel: Skyway.DATA_TRANSFER_TYPE]

      + +
      + + +
    • + +
  • @@ -17987,8 +19294,8 @@

    Event Payload:

    -
    -

    dataChannelState

    +
    +

    handshakeProgress

    @@ -18010,17 +19317,20 @@

    dataChannelState

    - source\skyway.js:1314 + source\skyway.js:1358

    +

    Available since 0.3.0

    +
    -

    Event fired when a DataChannel's state has changed

    +

    Event fired when a step of the handshake has happened. Usefull for diagnostic +or progress bar.

    @@ -18032,14 +19342,31 @@

    Event Payload:

  • - state + step + String + + + + +
    +

    The current handshake progress step. + [Rel: Skyway.HANDSHAKE_PROGRESS]

    + +
    + + +
  • + +
  • + + peerId String
    -

    [Rel: Skyway.DATA_CHANNEL_STATE]

    +

    PeerId of the peer's handshake progress.

    @@ -18048,14 +19375,15 @@

    Event Payload:

  • - peerId - String + error + JSON | Object | String
    - +

    Error message or object thrown.

    +
    @@ -18070,8 +19398,8 @@

    Event Payload:

  • -
    -

    dataTransferState

    +
    +

    incomingMessage

    @@ -18093,17 +19421,19 @@

    dataTransferState

    - source\skyway.js:1321 + source\skyway.js:1500

    +

    Available since 0.4.0

    +
    -

    Event fired when a Peer there is a Data Transfer going on

    +

    Event fired when a message being broadcasted is received.

    @@ -18115,62 +19445,14 @@

    Event Payload:

  • - state - String - - - - -
    -

    [Rel: Skyway.DATA_TRANSFER_STATE]

    - -
    - - -
  • - -
  • - - transferId - String - - - - -
    -

    ID of the Data Transfer

    - -
    - - -
  • - -
  • - - peerId - String - - - - -
    -

    Peer's ID

    - -
    - - -
  • - -
  • - - transferInfo + message JSON
    -

    Available data may vary at different state.

    +

    Message object that is received.

    @@ -18179,13 +19461,12 @@

    Event Payload:

  • - percentage - JSON + content + JSON | String
    -

    The percetange of data being - uploaded / downloaded

    +

    Data that is broadcasted.

    @@ -18194,12 +19475,13 @@

    Event Payload:

  • - senderPeerId - JSON + sendPeerId + String
    - +

    PeerId of the sender peer.

    +
    @@ -18207,12 +19489,13 @@

    Event Payload:

  • - data - JSON + targetPeerId + String
    -

    Blob data URL

    +

    PeerId that is specifically + targeted to receive the message.

    @@ -18221,12 +19504,12 @@

    Event Payload:

  • - name - JSON + isPrivate + Boolean
    -

    Data name

    +

    Is data received a private message.

    @@ -18235,48 +19518,51 @@

    Event Payload:

  • - size - JSON + isDataChannel + Boolean
    -

    Data size

    +

    Is data received from a data channel.

  • -
  • - - message - JSON - + + +
  • + +
  • + + peerId + String + -
    -

    Error message

    + -
    +
    +

    PeerId of the sender peer.

    - -
  • - -
  • - - type - JSON - +
  • -
    -

    Where the error message occurred. - [Rel: Skyway.DATA_TRANSFER_TYPE]

    + + + +
  • + + isSelf + Boolean + -
  • + + +
    +

    Check if message is sent to self

    + +
    - - - - @@ -18289,8 +19575,8 @@

    Event Payload:

    -
    -

    handshakeProgress

    +
    +

    incomingStream

    @@ -18312,18 +19598,24 @@

    handshakeProgress

    - source\skyway.js:1180 + source\skyway.js:1488

    +

    Available since 0.4.0

    +
    -

    Event fired when a step of the handshake has happened. Usefull for diagnostic -or progress bar.

    +

    Event fired when a remote stream has become available.

    +
      +
    • This occurs after the user joins the room.
    • +
    • This is changed from addPeerStream event. Note that +addPeerStream is removed from the specs.
    • +
    @@ -18335,14 +19627,14 @@

    Event Payload:

  • - step - String + stream + Object
    -

    [Rel: Skyway.HANDSHAKE_PROGRESS]

    +

    MediaStream object.

    @@ -18358,7 +19650,8 @@

    Event Payload:

    - +

    PeerId of the peer that is sending the stream.

    +
    @@ -18366,14 +19659,14 @@

    Event Payload:

  • - error - JSON | Object | String + isSelf + Boolean
    -

    Error message when error occurs

    +

    Is the peer self.

    @@ -18412,13 +19705,15 @@

    mediaAccessError

    - source\skyway.js:1210 + source\skyway.js:1399

    +

    Available since 0.1.0

    +
  • @@ -18441,7 +19736,8 @@

    Event Payload:

    - +

    Error message or object thrown.

    +
    @@ -18479,13 +19775,15 @@

    mediaAccessSuccess

    - source\skyway.js:1216 + source\skyway.js:1406

    +

    Available since 0.1.0

    +
    @@ -18508,7 +19806,8 @@

    Event Payload:

    - +

    MediaStream object.

    +
    @@ -18546,13 +19845,15 @@

    peerConnectionState

    - source\skyway.js:1196 + source\skyway.js:1379

    +

    Available since 0.1.0

    +
    @@ -18575,7 +19876,25 @@

    Event Payload:

    -

    [Rel: Skyway.PEER_CONNECTION_STATE]

    +

    The current peer connection state. + [Rel: Skyway.PEER_CONNECTION_STATE]

    + +
    + + + + +
  • + + peerId + String + + + + +
    +

    PeerId of the peer that had a peer connection state + change.

    @@ -18614,13 +19933,15 @@

    peerJoined

    - source\skyway.js:1232 + source\skyway.js:1413

    +

    Available since 0.3.0

    +
  • @@ -18644,7 +19965,8 @@

    Event Payload:

    - +

    PeerId of the peer that joined the room.

    +
    @@ -18659,7 +19981,8 @@

    Event Payload:

    - +

    Peer Information of the peer

    +
    @@ -18848,100 +20171,19 @@

    peerLeft

    - source\skyway.js:1274 + source\skyway.js:1457

    -
    - -
    -

    Event fired when a peer leaves the room

    - -
    - - -
    -

    Event Payload:

    - - -
    - - - - - - - -
    -

    peerUpdated

    - - - - - - - - - - -
    - - - -

    - - Defined in - - - - - source\skyway.js:1253 - -

    - - - +

    Available since 0.3.0

    -

    Event fired when a peer information is updated. Inactive audio or video means that the -audio is muted or video is muted.

    +

    Event fired when a peer leaves the room

    @@ -18960,7 +20202,8 @@

    Event Payload:

    - +

    PeerId of the peer that left.

    +
    @@ -18975,7 +20218,8 @@

    Event Payload:

    - +

    Peer Information of the peer

    +
    @@ -19125,7 +20369,7 @@

    Event Payload:

    -

    Is the Peer self.

    +

    Is the peer self.

    @@ -19141,17 +20385,13 @@

    Event Payload:

    -
    -

    presenceChanged

    +
    +

    peerUpdated

    - deprecated - - private - @@ -19168,17 +20408,20 @@

    presenceChanged

    - source\skyway.js:1281 + source\skyway.js:1435

    +

    Available since 0.3.0

    +
    -

    TODO Event fired when a peer joins the room

    +

    Event fired when a peer information is updated. Inactive audio or video means that the +audio is muted or video is muted.

    @@ -19190,118 +20433,168 @@

    Event Payload:

  • - users - JSON + peerId + String
    -

    The list of users

    +

    PeerId of the peer that had information updaed.

  • - -
    - - - - - - - -
    -

    privateMessage

    - - - +
  • + + peerInfo + JSON + - + - +
    +

    Peer Information of the peer

    - +
    -
    - - - -

    - - Defined in - - - - - source\skyway.js:1347 - -

    + +
      + +
    • + + settings + JSON + - +
      +

      Peer stream settings

      - -
      +
    -
    -

    Event fired when a private message is broadcasted.

    + +
      + +
    • + audio + Boolean | JSON -
    +
    + +
    +
  • + +
  • + audio.stereo + Boolean - -
    -

    Event Payload:

    +
    + +
    +
  • + +
  • + video + Boolean | JSON -
      - -
    • - - data - JSON | String - +
      + +
      +
    • + +
    • + video.resolution + JSON - +
      + [Rel: Skyway.VIDEO_RESOLUTION] +
      +
    • + +
    • + video.resolution.width + Integer -
      -

      Data to be sent over. Data is based on - what the user has set.

      +
      + +
      +
    • + +
    • + video.resolution.height + Integer -
  • +
    + +
    + + +
  • + video.frameRate + Integer - -
  • - -
  • - - senderPeerId - String - +
    + +
    +
  • + + + + + +
  • + + mediaStatus + JSON + - +
    +

    Peer stream status.

    -
    -

    Sender

    +
    -
    + + + +
  • + +
  • + + userData + String | JSON + -
    -

    Targeted Peer to receive the data

    +
    +

    Peer custom data

    -
    +
    + +
  • + + @@ -19314,7 +20607,7 @@

    Event Payload:

    -

    Check if message is sent to self

    +

    Is the peer self.

    @@ -19330,13 +20623,17 @@

    Event Payload:

    -
    -

    publicMessage

    +
    +

    presenceChanged

    + deprecated + + private + @@ -19353,17 +20650,19 @@

    publicMessage

    - source\skyway.js:1357 + source\skyway.js:1478

    +

    Available since 0.1.0

    +
    -

    Event fired when a public message is broadcasted.

    +

    TODO Event fired when a peer joins the room

    @@ -19375,47 +20674,14 @@

    Event Payload:

  • - data - JSON | String - - - - -
    -

    Data to be sent over. Data is based on - what the user has set.

    - -
    - - -
  • - -
  • - - senderPeerId - String - - - - -
    -

    Sender

    - -
    - - -
  • - -
  • - - isSelf - Boolean + users + JSON
    -

    Check if message is sent to self

    +

    The list of users

    @@ -19454,13 +20720,15 @@

    readyStateChange

    - source\skyway.js:1173 + source\skyway.js:1345

    +

    Available since 0.4.0

    +
  • @@ -19493,85 +20761,64 @@

    Event Payload:

  • error - String + JSON
    -

    Error message when there's an error

    +

    Error object thrown.

    -
  • - - -
    - - - - - - - -
    -

    removePeerStream

    - - - - - - private - - - - - - -
    - - - -

    - - Defined in - - - - - source\skyway.js:1298 - -

    +
      + +
    • + + status + Integer + - +
      +

      HTTP status when retrieving information. + May be empty for other errors.

      - -
      +
    -
    -

    TODO Event fired when a remote stream has become unavailable

    + + + +
  • + + content + String + -
  • +
    +

    A short description of the error

    - -
    -

    Event Payload:

    +
    -
      - -
    • - - peerId - String - + +
    • + +
    • + + errorCode + Integer + - +
      +

      The error code for the type of error + [Rel: Skyway.READY_STATE_CHANGE_ERROR]

      -
      - -
      +
      + +
    • + +
    @@ -19607,17 +20854,19 @@

    roomLock

    - source\skyway.js:1305 + source\skyway.js:1515

    +

    Available since 0.4.0

    +
    -

    Event fired when a room is locked

    +

    Event fired when a room lock status has changed.

    @@ -19629,14 +20878,15 @@

    Event Payload:

  • - success + isLocked Boolean
    - +

    Is the room locked.

    +
    @@ -19644,14 +20894,15 @@

    Event Payload:

  • - isLocked - Boolean + peerId + String
    - +

    PeerId of the peer that is locking/unlocking the room.

    +
    @@ -19659,14 +20910,166 @@

    Event Payload:

  • - error - String + peerInfo + JSON
    - +

    Peer Information of the peer

    + +
    + + +
      + +
    • + + settings + JSON + + +
      +

      Peer stream settings

      + +
      + + +
        + +
      • + audio + Boolean | JSON + +
        + +
        +
      • + +
      • + audio.stereo + Boolean + +
        + +
        +
      • + +
      • + video + Boolean | JSON + +
        + +
        +
      • + +
      • + video.resolution + JSON + +
        + [Rel: Skyway.VIDEO_RESOLUTION] +
        +
      • + +
      • + video.resolution.width + Integer + +
        + Video width +
        +
      • + +
      • + video.resolution.height + Integer + +
        + Video height +
        +
      • + +
      • + video.frameRate + Integer + +
        + +
        +
      • + +
      + +
    • + +
    • + + mediaStatus + JSON + + +
      +

      Peer stream status.

      + +
      + + +
        + +
      • + audioMuted + Boolean + +
        + If Peer's Audio stream is muted. +
        +
      • + +
      • + videoMuted + Boolean + +
        + If Peer's Video stream is muted. +
        +
      • + +
      + +
    • + +
    • + + userData + String | JSON + + +
      +

      Peer custom data

      + +
      + + +
    • + +
    + +
  • + +
  • + + isSelf + Boolean + + + + +
    +

    Is the peer self.

    +
    @@ -19704,13 +21107,15 @@

    systemAction

    - source\skyway.js:1339 + source\skyway.js:1568

    +

    Available since 0.1.0

    +
  • @@ -19734,7 +21139,8 @@

    Event Payload:

    -

    [Rel: Skyway.SYSTEM_ACTION]

    +

    The action that is required for the current peer to + follow. [Rel: Skyway.SYSTEM_ACTION]

    @@ -19750,7 +21156,7 @@

    Event Payload:

    -

    The reason of the action

    +

    Reason for the action

    diff --git a/doc/data.json b/doc/data.json index 3dc0c5c6f..1de836387 100644 --- a/doc/data.json +++ b/doc/data.json @@ -2,7 +2,7 @@ "project": { "name": "skywayjs", "description": "WebRTC real-time video conversation library", - "version": "0.3.1", + "version": "0.4.0", "url": "https://www.temasys.com.sg/" }, "files": { @@ -30,27 +30,29 @@ "extension_for": [], "file": "source\\skyway.js", "line": 5, - "description": "Please check on the {{#crossLink \"Skyway/init:method\"}}init(){{/crossLink}} function\non how you can initialize Skyway.", + "description": "Please check on the {{#crossLink \"Skyway/init:method\"}}init(){{/crossLink}} function\non how you can initialize Skyway. Note that:\n- You will have to subscribe all Skyway events first before calling\n {{#crossLink \"Skyway/init:method\"}}init(){{/crossLink}}.\n- If you need an api key, please [register an api key](http://\n developer.temasys.com.sg) at our developer console.", "is_constructor": 1, "example": [ "\n // Getting started on how to use Skyway\n var SkywayDemo = new Skyway();\n SkywayDemo.init('apiKey');" - ] + ], + "since": "0.1.0" } }, "classitems": [ { "file": "source\\skyway.js", - "line": 19, + "line": 24, "description": "Version of Skyway", "itemtype": "attribute", "name": "VERSION", "type": "String", "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 26, + "line": 32, "description": "List of regional server for Skyway to connect to.\nDefault server is US1. Servers:", "itemtype": "attribute", "name": "REGIONAL_SERVER", @@ -78,11 +80,12 @@ } ], "readonly": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 43, + "line": 50, "description": "ICE Connection States. States that would occur are:", "itemtype": "attribute", "name": "ICE_CONNECTION_STATE", @@ -125,11 +128,12 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 65, + "line": 73, "description": "Peer Connection States. States that would occur are:", "itemtype": "attribute", "name": "PEER_CONNECTION_STATE", @@ -172,11 +176,12 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 87, + "line": 96, "description": "ICE Candidate Generation States. States that would occur are:", "itemtype": "attribute", "name": "CANDIDATE_GENERATION_STATE", @@ -194,11 +199,12 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 99, + "line": 109, "description": "Handshake Progress Steps. Steps that would occur are:", "type": "JSON", "itemtype": "attribute", @@ -231,11 +237,12 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 117, + "line": 128, "description": "Data Channel Connection States. Steps that would occur are:", "itemtype": "attribute", "name": "DATA_CHANNEL_STATE", @@ -278,11 +285,12 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 139, + "line": 151, "description": "System actions received from Signaling server. System action outcomes are:", "itemtype": "attribute", "name": "SYSTEM_ACTION", @@ -305,11 +313,12 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 153, + "line": 166, "description": "State to check if Skyway initialization is ready. Steps that would occur are:", "itemtype": "attribute", "name": "DATA_CHANNEL_STATE", @@ -337,11 +346,105 @@ } ], "readonly": "", + "since": "0.1.0", + "class": "Skyway" + }, + { + "file": "source\\skyway.js", + "line": 186, + "description": "Error states that occurs when retrieving server information. States are:", + "itemtype": "attribute", + "name": "READY_STATE_CHANGE_ERROR", + "type": "JSON", + "params": [ + { + "name": "API_INVALID", + "description": "Api Key provided does not exist.", + "type": "Integer" + }, + { + "name": "API_DOMAIN_NOT_MATCH", + "description": "Api Key used in domain does not match.", + "type": "Integer" + }, + { + "name": "API_CORS_DOMAIN_NOT_MATCH", + "description": "Api Key used in CORS domain does\n not match.", + "type": "Integer" + }, + { + "name": "API_CREDENTIALS_INVALID", + "description": "Api Key credentials does not exist.", + "type": "Integer" + }, + { + "name": "API_CREDENTIALS_NOT_MATCH", + "description": "Api Key credentials does not\n match what is expected.", + "type": "Integer" + }, + { + "name": "API_INVALID_PARENT_KEY", + "description": "Api Key does not have a parent key\n nor is a root key.", + "type": "Integer" + }, + { + "name": "API_NOT_ENOUGH_CREDIT", + "description": "Api Key does not have enough credits\n to use.", + "type": "Integer" + }, + { + "name": "API_NOT_ENOUGH_PREPAID_CREDIT", + "description": "Api Key does not have enough\n prepaid credits to use.", + "type": "Integer" + }, + { + "name": "API_FAILED_FINDING_PREPAID_CREDIT", + "description": "Api Key preapid payments\n does not exist.", + "type": "Integer" + }, + { + "name": "API_NO_MEETING_RECORD_FOUND", + "description": "Api Key does not have a meeting\n record at this timing. This occurs when Api Key is a static one.", + "type": "Integer" + }, + { + "name": "ROOM_LOCKED", + "description": "Room is locked.", + "type": "Integer" + }, + { + "name": "NO_SOCKET_IO", + "description": "No socket.io dependency is loaded to use.", + "type": "Integer" + }, + { + "name": "NO_XMLHTTPREQUEST_SUPPORT", + "description": "Browser does not support\n XMLHttpRequest to use.", + "type": "Integer" + }, + { + "name": "NO_WEBRTC_SUPPORT", + "description": "Browser does not have WebRTC support.", + "type": "Integer" + }, + { + "name": "NO_PATH", + "description": "No path is loaded yet.", + "type": "Integer" + }, + { + "name": "INVALID_XMLHTTPREQUEST_STATUS", + "description": "Invalid XMLHttpRequest\n when retrieving information.", + "type": "Integer" + } + ], + "readonly": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 171, + "line": 238, "description": "Data Channel Transfer Type. Types are:", "itemtype": "attribute", "name": "DATA_TRANSFER_TYPE", @@ -359,11 +462,12 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 183, + "line": 251, "description": "Data Channel Transfer State. State that would occur are:", "itemtype": "attribute", "name": "DATA_TRANSFER_STATE", @@ -411,12 +515,13 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 207, - "description": "TODO : ArrayBuffer and Blob in DataChannel\nData Channel Transfer Data type. Data Types are:", + "line": 277, + "description": "TODO : ArrayBuffer and Blob in DataChannel.\nData Channel Transfer Data type. Data Types are:", "itemtype": "attribute", "name": "DATA_TRANSFER_DATA_TYPE", "type": "JSON", @@ -438,12 +543,13 @@ } ], "readonly": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 222, - "description": "Signaling message type. These message types are fixed.\n(Legend: S - Send only. R - Received only. SR - Can be Both).\nSignaling types are:", + "line": 293, + "description": "Signaling message type.\n- These message types are fixed.\n- (Legend: S - Send only. R - Received only. SR - Can be Both).\nSignaling types are:", "itemtype": "attribute", "name": "SIG_TYPE", "type": "JSON", @@ -451,102 +557,98 @@ "params": [ { "name": "JOIN_ROOM", - "description": "S. Join the Room", + "description": "[S] Join the Room", "type": "String" }, { "name": "IN_ROOM", - "description": "R. User has already joined the Room", + "description": "[R] User has already joined the Room", "type": "String" }, { "name": "ENTER", - "description": "SR. Enter from handshake", + "description": "[SR] Enter from handshake", "type": "String" }, { "name": "WELCOME", - "description": "SR. Welcome from handshake", + "description": "[SR] Welcome from handshake", "type": "String" }, { "name": "OFFER", - "description": "SR. Offer from handshake", + "description": "[SR] Offer from handshake", "type": "String" }, { "name": "ANSWER", - "description": "SR. Answer from handshake", + "description": "[SR] Answer from handshake", "type": "String" }, { "name": "CANDIDATE", - "description": "SR. Candidate received", + "description": "[SR] Candidate received", "type": "String" }, { "name": "BYE", - "description": "R. Peer left the room", + "description": "[R] Peer left the room", "type": "String" }, { "name": "CHAT", - "description": "SR. Chat message relaying", + "description": "[SR] Deprecated. Chat message relaying", "type": "String" }, { "name": "REDIRECT", - "description": "R. Server redirecting User", + "description": "[R] Server redirecting User", "type": "String" }, { "name": "ERROR", - "description": "R. Server occuring an error", - "type": "String" - }, - { - "name": "INVITE", - "description": "SR. TODO.", + "description": "[R] Server occuring an error", "type": "String" }, { "name": "UPDATE_USER", - "description": "SR. Update of User information", + "description": "[SR] Update of User information", "type": "String" }, { "name": "ROOM_LOCK", - "description": "SR. Locking of Room", + "description": "[SR] Locking of Room", "type": "String" }, { "name": "MUTE_VIDEO", - "description": "SR. Muting of User's video", + "description": "[SR] Muting of User's video", "type": "String" }, { "name": "MUTE_AUDIO", - "description": "SR. Muting of User's audio", + "description": "[SR] Muting of User's audio", "type": "String" }, { "name": "PUBLIC_MESSAGE", - "description": "SR. Sending a public broadcast message.", + "description": "[SR] Sending a public broadcast message.", "type": "String" }, { "name": "PRIVATE_MESSAGE", - "description": "SR. Sending a private message", + "description": "[SR] Sending a private message", "type": "String" } ], "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 269, + "line": 341, "description": "Lock Action States", "itemtype": "attribute", "name": "LOCK_ACTION", @@ -569,11 +671,12 @@ } ], "readonly": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 283, + "line": 356, "description": "Video Resolutions. Resolution types are:", "params": [ { @@ -649,11 +752,12 @@ "name": "VIDEO_RESOLUTION", "type": "JSON", "readonly": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 319, + "line": 393, "description": "NOTE ALEX: check if last char is '/'", "itemtype": "attribute", "name": "_path", @@ -663,11 +767,12 @@ "required": 1, "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 329, + "line": 404, "description": "Url Skyway makes API calls to", "itemtype": "attribute", "name": "_serverPath", @@ -676,11 +781,12 @@ "required": 1, "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 338, + "line": 414, "description": "The server region the room connects to", "itemtype": "attribute", "name": "_serverRegion", @@ -688,44 +794,48 @@ "default": "REGIONAL_SERVER.US1", "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 346, + "line": 423, "description": "The Room server User connects to", "itemtype": "attribute", "name": "_roomServer", "type": "String", "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 353, + "line": 431, "description": "The Application Key ID", "itemtype": "attribute", "name": "_apiKey", "type": "String", "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 360, + "line": 439, "description": "The default room that the User connects to", "itemtype": "attribute", "name": "_defaultRoom", "type": "String", "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 367, + "line": 447, "description": "The room that the User connects to", "itemtype": "attribute", "name": "_selectedRoom", @@ -733,11 +843,12 @@ "default": "_defaultRoom", "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 375, + "line": 456, "description": "The room start datetime in ISO format", "itemtype": "attribute", "name": "_roomStart", @@ -745,11 +856,12 @@ "access": "private", "tagname": "", "optional": 1, + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 383, + "line": 465, "description": "The room duration before closing", "itemtype": "attribute", "name": "_roomDuration", @@ -757,11 +869,12 @@ "access": "private", "tagname": "", "optional": 1, + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 391, + "line": 474, "description": "The room credentials to set the start time and duration", "itemtype": "attribute", "name": "_roomCredentials", @@ -769,22 +882,24 @@ "access": "private", "tagname": "", "optional": 1, + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 399, + "line": 483, "description": "The Server Key", "itemtype": "attribute", "name": "_key", "type": "String", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 406, + "line": 491, "description": "The actual socket that handle the connection", "itemtype": "attribute", "name": "_socket", @@ -792,22 +907,24 @@ "required": 1, "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 414, + "line": 500, "description": "The socket version of the socket.io used", "itemtype": "attribute", "name": "_socketVersion", "type": "Integer", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 421, + "line": 508, "description": "User Information, credential and the local stream(s).", "itemtype": "attribute", "name": "_user", @@ -923,11 +1040,12 @@ "required": 1, "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 449, + "line": 537, "itemtype": "attribute", "name": "_room", "type": "JSON", @@ -1038,71 +1156,77 @@ "required": 1, "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 481, - "description": "Internal array of peerconnections", + "line": 570, + "description": "Internal array of peer connections", "itemtype": "attribute", "name": "_peerConnections", - "type": "Array", + "type": "Object", "required": 1, "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 489, + "line": 579, "description": "Internal array of peer informations", "itemtype": "attribute", "name": "_peerInformations", - "type": "Array", + "type": "Object", "access": "private", "tagname": "", "required": 1, + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 497, + "line": 588, "description": "Internal array of dataChannels", "itemtype": "attribute", "name": "_dataChannels", - "type": "Array", + "type": "Object", "access": "private", "tagname": "", "required": 1, + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 505, + "line": 597, "description": "Internal array of dataChannel peers", "itemtype": "attribute", "name": "_dataChannelPeers", - "type": "Array", + "type": "Object", "access": "private", "tagname": "", "required": 1, + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 513, - "description": "The current ReadyState\n-1 'failed', 0 'false', 1 'in process', 2 'done'", + "line": 606, + "description": "The current ReadyState\n[Rel: Skyway.READY_STATE_CHANGE]", "itemtype": "attribute", "name": "_readyState", "type": "Integer", "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 522, + "line": 616, "description": "State if Channel is opened or not", "itemtype": "attribute", "name": "_channel_open", @@ -1110,11 +1234,25 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", + "class": "Skyway" + }, + { + "file": "source\\skyway.js", + "line": 625, + "description": "State if Room is locked or not", + "itemtype": "attribute", + "name": "_room_lock", + "type": "Boolean", + "access": "private", + "tagname": "", + "required": 1, + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 530, + "line": 634, "description": "State if User is in room or not", "itemtype": "attribute", "name": "_in_room", @@ -1122,11 +1260,12 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 538, + "line": 643, "description": "Stores the upload data chunks", "itemtype": "attribute", "name": "_uploadDataTransfers", @@ -1134,11 +1273,12 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 546, + "line": 652, "description": "Stores the upload data session information", "itemtype": "attribute", "name": "_uploadDataSessions", @@ -1146,11 +1286,12 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 554, + "line": 661, "description": "Stores the download data chunks", "itemtype": "attribute", "name": "_downloadDataTransfers", @@ -1158,11 +1299,12 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 562, + "line": 670, "description": "Stores the download data session information", "itemtype": "attribute", "name": "_downloadDataSessions", @@ -1170,11 +1312,12 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 570, + "line": 679, "description": "Stores the data transfers timeout", "itemtype": "attribute", "name": "_dataTransfersTimeout", @@ -1182,11 +1325,12 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 578, + "line": 688, "description": "Standard File Size of each chunk", "itemtype": "attribute", "name": "_chunkFileSize", @@ -1195,11 +1339,12 @@ "tagname": "", "final": 1, "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 587, + "line": 698, "description": "Standard File Size of each chunk for Firefox", "itemtype": "attribute", "name": "_mozChunkFileSize", @@ -1208,11 +1353,12 @@ "tagname": "", "final": 1, "required": 1, + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 596, + "line": 708, "description": "If ICE trickle should be disabled or not", "itemtype": "attribute", "name": "_enableIceTrickle", @@ -1221,11 +1367,12 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 605, + "line": 718, "description": "If DataChannel should be disabled or not", "itemtype": "attribute", "name": "_enableDataChannel", @@ -1234,23 +1381,25 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 614, - "description": "User stream settings", + "line": 728, + "description": "User stream settings. By default, all is false.", "itemtype": "attribute", "name": "_streamSettings", "type": "JSON", - "default": "{\n 'audio' : true,\n 'video' : true\n}", + "default": "{\n 'audio' : false,\n 'video' : false\n}", "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 628, + "line": 743, "description": "Get information from server", "itemtype": "method", "name": "_requestServerInfo", @@ -1278,11 +1427,12 @@ ], "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 659, + "line": 775, "description": "Parse information from server", "itemtype": "method", "name": "_parseInfo", @@ -1302,11 +1452,12 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 712, + "line": 834, "description": "Load information from server", "itemtype": "method", "name": "_loadInfo", @@ -1321,58 +1472,61 @@ "access": "private", "tagname": "", "required": 1, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 762, - "description": "Let app register a callback function to an event", + "line": 905, + "description": "To register a callback function to an event.", "itemtype": "method", "name": "on", "params": [ { "name": "eventName", - "description": "", + "description": "The Skyway event.", "type": "String" }, { "name": "callback", - "description": "", + "description": "The callback everytime the event is fired.", "type": "Function" } ], "example": [ "\n SkywayDemo.on('peerJoined', function (peerId, peerInfo) {\n console.info(peerId + ' has joined the room');\n console.log('Peer information are:');\n console.info(peerInfo);\n });" ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 781, - "description": "Let app unregister a callback function from an event", + "line": 925, + "description": "To unregister a callback function from an event.", "itemtype": "method", "name": "off", "params": [ { "name": "eventName", - "description": "", + "description": "The Skyway event.", "type": "String" }, { "name": "callback", - "description": "", + "description": "The callback everytime the event is fired.", "type": "Function" } ], "example": [ "\n SkywayDemo.off('peerJoined', callback);" ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 804, - "description": "Trigger all the callbacks associated with an event\nNote that extra arguments can be passed to the callback\nwhich extra argument can be expected by callback is documented by each event", + "line": 949, + "description": "Trigger all the callbacks associated with an event\n- Note that extra arguments can be passed to the callback which\n extra argument can be expected by callback is documented by each event.", "itemtype": "method", "name": "_trigger", "params": [ @@ -1384,12 +1538,13 @@ ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 824, - "description": "IMPORTANT: Please call this method to load all server information before joining\nthe room or doing anything else.\nThis is Init function to load Skyway.", + "line": 978, + "description": "Initialize Skyway\n- IMPORTANT: Please call this method to load all server\n information before joining the room or doing anything else.", "itemtype": "method", "name": "init", "params": [ @@ -1421,17 +1576,17 @@ { "name": "iceTrickle", "description": "Optional. The option to enable iceTrickle or not.\n Default is true.", - "type": "String" + "type": "Boolean" }, { "name": "dataChannel", "description": "Optional. The option to enable dataChannel or not.\n Default is true.", - "type": "String" + "type": "Boolean" }, { "name": "credentials", "description": "Optional. Credentials options", - "type": "String", + "type": "JSON", "props": [ { "name": "startDateTime", @@ -1458,20 +1613,16 @@ ], "trigger": "readyStateChange", "required": 1, + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 952, - "description": "Reinitialize Skyway signaling credentials", + "line": 1107, + "description": "Re-initialize Skyway signaling credentials.", "itemtype": "method", "name": "_reinit", "params": [ - { - "name": "callback", - "description": "Once everything is done", - "type": "Function" - }, { "name": "options", "description": "", @@ -1505,17 +1656,17 @@ { "name": "iceTrickle", "description": "", - "type": "String" + "type": "Boolean" }, { "name": "dataChannel", "description": "", - "type": "String" + "type": "Boolean" }, { "name": "credentials", "description": "", - "type": "String", + "type": "JSON", "props": [ { "name": "startDateTime", @@ -1535,17 +1686,23 @@ ] } ] + }, + { + "name": "callback", + "description": "Once everything is initialized.", + "type": "Function" } ], "trigger": "readyStateChange", "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1069, - "description": "Set and Update the User information. Please note that the custom\ndata would be overrided so please call getUser and then modify the\ninformation you want individually.", + "line": 1234, + "description": "Updates the User information.\n- Please note that the custom data would be overrided so please call\n {{#crossLink \"Skyway/getUserData:method\"}}getUserData(){{/crossLink}}\n and then modify the information you want individually.\n- {{#crossLink \"Skyway/peerUpdated:event\"}}peerUpdated{{/crossLink}}\n only fires after setUserData() is fired\n after the user joins the room.", "itemtype": "method", "name": "setUserData", "params": [ @@ -1559,27 +1716,29 @@ "\n // Example 1: Intial way of setting data before user joins the room\n SkywayDemo.setUserData({\n displayName: 'Bobby Rays',\n fbUserId: 'blah'\n });\n\n // Example 2: Way of setting data after user joins the room\n var userData = SkywayDemo.getUserData();\n userData.userData.displayName = 'New Name';\n userData.userData.fbUserId = 'another Id';\n SkywayDemo.setUserData(userData);" ], "trigger": "peerUpdated", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1122, - "description": "Get the User Information", + "line": 1281, + "description": "Gets the user information.", "itemtype": "method", "name": "getUserData", "return": { "description": "User information", - "type": "JSON" + "type": "JSON|" }, "example": [ "\n var userInfo = SkywayDemo.getUserData();" ], + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1133, - "description": "Get the Peer Information", + "line": 1295, + "description": "Gets the peer information.\n- If input peerId is user's id or empty, getPeerInfo()\n would return user's peer information.", "itemtype": "method", "name": "getPeerInfo", "params": [ @@ -1594,30 +1753,33 @@ "type": "JSON" }, "example": [ - "\n var peerInfo = SkywayDemo.getPeerInfo(peerId);" + "\n // Example 1: To get other peer's information\n var peerInfo = SkywayDemo.getPeerInfo(peerId);\n\n // Example 2: To get own information\n var userInfo = SkywayDemo.getPeerInfo();" ], + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1150, + "line": 1318, "description": "Event fired when a successfull connection channel has been established\nwith the signaling server", "itemtype": "event", "name": "channelOpen", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1156, + "line": 1325, "description": "Event fired when the channel has been closed.", "itemtype": "event", "name": "channelClose", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1161, - "description": "Event fired when we received a message from the sig server..", + "line": 1331, + "description": "Event fired when we received a message from the signaling server.", "itemtype": "event", "name": "channelMessage", "params": [ @@ -1627,26 +1789,28 @@ "type": "JSON" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1167, + "line": 1338, "description": "Event fired when there was an error with the connection channel to the sig server.", "itemtype": "event", "name": "channelError", "params": [ { "name": "error", - "description": "", - "type": "String" + "description": "Error message or object thrown.", + "type": "Object|String" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1173, + "line": 1345, "description": "Event fired whether the room is ready for use", "itemtype": "event", "name": "readyStateChange", @@ -1658,171 +1822,165 @@ }, { "name": "error", - "description": "Error message when there's an error", - "type": "String" + "description": "Error object thrown.", + "type": "JSON", + "props": [ + { + "name": "status", + "description": "HTTP status when retrieving information.\n May be empty for other errors.", + "type": "Integer" + }, + { + "name": "content", + "description": "A short description of the error", + "type": "String" + }, + { + "name": "errorCode", + "description": "The error code for the type of error\n [Rel: Skyway.READY_STATE_CHANGE_ERROR]", + "type": "Integer" + } + ] } ], + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1180, + "line": 1358, "description": "Event fired when a step of the handshake has happened. Usefull for diagnostic\nor progress bar.", "itemtype": "event", "name": "handshakeProgress", "params": [ { "name": "step", - "description": "[Rel: Skyway.HANDSHAKE_PROGRESS]", + "description": "The current handshake progress step.\n [Rel: Skyway.HANDSHAKE_PROGRESS]", "type": "String" }, { "name": "peerId", - "description": "", + "description": "PeerId of the peer's handshake progress.", "type": "String" }, { "name": "error", - "description": "Error message when error occurs", + "description": "Error message or object thrown.", "type": "JSON|Object|String" } ], + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1189, + "line": 1369, "description": "Event fired during ICE gathering", "itemtype": "event", "name": "candidateGenerationState", "params": [ { "name": "state", - "description": "[Rel: Skyway.CANDIDATE_GENERATION_STATE]", + "description": "The current ice candidate generation state.\n [Rel: Skyway.CANDIDATE_GENERATION_STATE]", "type": "String" }, { "name": "peerId", - "description": "", + "description": "PeerId of the peer that had an ice candidate\n generation state change.", "type": "String" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1196, + "line": 1379, "description": "Event fired during Peer Connection state change", "itemtype": "event", "name": "peerConnectionState", "params": [ { "name": "state", - "description": "[Rel: Skyway.PEER_CONNECTION_STATE]", + "description": "The current peer connection state.\n [Rel: Skyway.PEER_CONNECTION_STATE]", + "type": "String" + }, + { + "name": "peerId", + "description": "PeerId of the peer that had a peer connection state\n change.", "type": "String" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1202, + "line": 1389, "description": "Event fired during ICE connection", "iceconnectionstate": "", "params": [ { "name": "state", - "description": "[Rel: Skyway.ICE_CONNECTION_STATE]", + "description": "The current ice connection state.\n [Rel: Skyway.ICE_CONNECTION_STATE]", "type": "String" }, { "name": "peerId", - "description": "", + "description": "PeerId of the peer that had an ice connection state change.", "type": "String" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1210, + "line": 1399, "description": "Event fired when allowing webcam media stream fails", "itemtype": "event", "name": "mediaAccessError", "params": [ { "name": "error", - "description": "", + "description": "Error message or object thrown.", "type": "Object|String" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1216, + "line": 1406, "description": "Event fired when allowing webcam media stream passes", "itemtype": "event", "name": "mediaAccessSuccess", "params": [ { "name": "stream", - "description": "", + "description": "MediaStream object.", "type": "Object" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1222, - "description": "Event fired when a chat message is received from other peers", - "itemtype": "event", - "name": "chatMessageReceived", - "params": [ - { - "name": "message", - "description": "", - "type": "String" - }, - { - "name": "senderPeerId", - "description": "", - "type": "String" - }, - { - "name": "userData", - "description": "", - "type": "String|JSON" - }, - { - "name": "isPrivate", - "description": "", - "type": "Boolean" - }, - { - "name": "isSelf", - "description": "", - "type": "Boolean" - } - ], - "class": "Skyway" - }, - { - "file": "source\\skyway.js", - "line": 1232, + "line": 1413, "description": "Event fired when a peer joins the room. Inactive audio or video means that the\naudio is muted or video is muted.", "itemtype": "event", "name": "peerJoined", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer that joined the room.", "type": "String" }, { "name": "peerInfo", - "description": "", + "description": "Peer Information of the peer", "type": "JSON", "props": [ { @@ -1897,23 +2055,24 @@ "type": "Boolean" } ], + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1253, + "line": 1435, "description": "Event fired when a peer information is updated. Inactive audio or video means that the\naudio is muted or video is muted.", "itemtype": "event", "name": "peerUpdated", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer that had information updaed.", "type": "String" }, { "name": "peerInfo", - "description": "", + "description": "Peer Information of the peer", "type": "JSON", "props": [ { @@ -1984,35 +2143,108 @@ }, { "name": "isSelf", - "description": "Is the Peer self.", + "description": "Is the peer self.", "type": "Boolean" } ], + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1274, + "line": 1457, "description": "Event fired when a peer leaves the room", "itemtype": "event", "name": "peerLeft", "params": [ { - "name": "peerId,", - "description": "", + "name": "peerId", + "description": "PeerId of the peer that left.", "type": "String" }, + { + "name": "peerInfo", + "description": "Peer Information of the peer", + "type": "JSON", + "props": [ + { + "name": "settings", + "description": "Peer stream settings", + "type": "JSON", + "props": [ + { + "name": "audio", + "description": "", + "type": "Boolean|JSON" + }, + { + "name": "audio.stereo", + "description": "", + "type": "Boolean" + }, + { + "name": "video", + "description": "", + "type": "Boolean|JSON" + }, + { + "name": "video.resolution", + "description": "[Rel: Skyway.VIDEO_RESOLUTION]", + "type": "JSON" + }, + { + "name": "video.resolution.width", + "description": "", + "type": "Integer" + }, + { + "name": "video.resolution.height", + "description": "", + "type": "Integer" + }, + { + "name": "video.frameRate", + "description": "", + "type": "Integer" + } + ] + }, + { + "name": "mediaStatus", + "description": "Peer stream status.", + "type": "JSON", + "props": [ + { + "name": "audioMuted", + "description": "If Peer's Audio stream is muted.", + "type": "Boolean" + }, + { + "name": "videoMuted", + "description": "If Peer's Video stream is muted.", + "type": "Boolean" + } + ] + }, + { + "name": "userData", + "description": "Peer custom data", + "type": "String|JSON" + } + ] + }, { "name": "isSelf", - "description": "", + "description": "Is the peer self.", "type": "Boolean" } ], + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1281, + "line": 1478, "description": "TODO Event fired when a peer joins the room", "itemtype": "event", "name": "presenceChanged", @@ -2026,120 +2258,231 @@ "access": "private", "tagname": "", "deprecated": true, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1290, - "description": "Event fired when a remote stream has become available", + "line": 1488, + "description": "Event fired when a remote stream has become available.\n- This occurs after the user joins the room.\n- This is changed from addPeerStream event. Note that\n addPeerStream is removed from the specs.", "itemtype": "event", - "name": "addPeerStream", + "name": "incomingStream", "params": [ - { - "name": "peerId", - "description": "", - "type": "String" - }, { "name": "stream", - "description": "", + "description": "MediaStream object.", "type": "Object" }, + { + "name": "peerId", + "description": "PeerId of the peer that is sending the stream.", + "type": "String" + }, { "name": "isSelf", - "description": "", + "description": "Is the peer self.", "type": "Boolean" } ], + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1298, - "description": "TODO Event fired when a remote stream has become unavailable", + "line": 1500, + "description": "Event fired when a message being broadcasted is received.", "itemtype": "event", - "name": "removePeerStream", + "name": "incomingMessage", "params": [ { - "name": "peerId", - "description": "", - "type": "String" - } - ], - "access": "private", - "tagname": "", + "name": "message", + "description": "Message object that is received.", + "type": "JSON", + "props": [ + { + "name": "content", + "description": "Data that is broadcasted.", + "type": "JSON|String" + }, + { + "name": "sendPeerId", + "description": "PeerId of the sender peer.", + "type": "String" + }, + { + "name": "targetPeerId", + "description": "PeerId that is specifically\n targeted to receive the message.", + "type": "String" + }, + { + "name": "isPrivate", + "description": "Is data received a private message.", + "type": "Boolean" + }, + { + "name": "isDataChannel", + "description": "Is data received from a data channel.", + "type": "Boolean" + } + ] + }, + { + "name": "peerId", + "description": "PeerId of the sender peer.", + "type": "String" + }, + { + "name": "isSelf", + "description": "Check if message is sent to self", + "type": "Boolean" + } + ], + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1305, - "description": "Event fired when a room is locked", + "line": 1515, + "description": "Event fired when a room lock status has changed.", "itemtype": "event", "name": "roomLock", "params": [ - { - "name": "success", - "description": "", - "type": "Boolean" - }, { "name": "isLocked", - "description": "", + "description": "Is the room locked.", "type": "Boolean" }, { - "name": "error", - "description": "", + "name": "peerId", + "description": "PeerId of the peer that is locking/unlocking the room.", "type": "String" + }, + { + "name": "peerInfo", + "description": "Peer Information of the peer", + "type": "JSON", + "props": [ + { + "name": "settings", + "description": "Peer stream settings", + "type": "JSON", + "props": [ + { + "name": "audio", + "description": "", + "type": "Boolean|JSON" + }, + { + "name": "audio.stereo", + "description": "", + "type": "Boolean" + }, + { + "name": "video", + "description": "", + "type": "Boolean|JSON" + }, + { + "name": "video.resolution", + "description": "[Rel: Skyway.VIDEO_RESOLUTION]", + "type": "JSON" + }, + { + "name": "video.resolution.width", + "description": "Video width", + "type": "Integer" + }, + { + "name": "video.resolution.height", + "description": "Video height", + "type": "Integer" + }, + { + "name": "video.frameRate", + "description": "", + "type": "Integer" + } + ] + }, + { + "name": "mediaStatus", + "description": "Peer stream status.", + "type": "JSON", + "props": [ + { + "name": "audioMuted", + "description": "If Peer's Audio stream is muted.", + "type": "Boolean" + }, + { + "name": "videoMuted", + "description": "If Peer's Video stream is muted.", + "type": "Boolean" + } + ] + }, + { + "name": "userData", + "description": "Peer custom data", + "type": "String|JSON" + } + ] + }, + { + "name": "isSelf", + "description": "Is the peer self.", + "type": "Boolean" } ], + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1314, - "description": "Event fired when a DataChannel's state has changed", + "line": 1538, + "description": "Event fired when a peer's datachannel state has changed.", "itemtype": "event", "name": "dataChannelState", "params": [ { "name": "state", - "description": "[Rel: Skyway.DATA_CHANNEL_STATE]", + "description": "The current datachannel state.\n [Rel: Skyway.DATA_CHANNEL_STATE]", "type": "String" }, { "name": "peerId", - "description": "", + "description": "PeerId of peer that has a datachannel state change.", "type": "String" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1321, - "description": "Event fired when a Peer there is a Data Transfer going on", + "line": 1547, + "description": "Event fired when a data transfer state has changed.", "itemtype": "event", "name": "dataTransferState", "params": [ { "name": "state", - "description": "[Rel: Skyway.DATA_TRANSFER_STATE]", + "description": "The current data transfer state.\n [Rel: Skyway.DATA_TRANSFER_STATE]", "type": "String" }, { "name": "transferId", - "description": "ID of the Data Transfer", + "description": "TransferId of the data", "type": "String" }, { "name": "peerId", - "description": "Peer's ID", + "description": "PeerId of the peer that has a data\n transfer state change.", "type": "String" }, { "name": "transferInfo", - "description": "Available data may vary at different state.", + "description": "Transfer information.", "type": "JSON", "props": [ { @@ -2159,17 +2502,17 @@ }, { "name": "name", - "description": "Data name", + "description": "Blob data name", "type": "JSON" }, { "name": "size", - "description": "Data size", + "description": "Blob data size", "type": "JSON" }, { "name": "message", - "description": "Error message", + "description": "Error object thrown.", "type": "JSON" }, { @@ -2180,180 +2523,215 @@ ] } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1339, + "line": 1568, "description": "Event fired when the Signalling server responds to user regarding\nthe state of the room", "itemtype": "event", "name": "systemAction", "params": [ { "name": "action", - "description": "[Rel: Skyway.SYSTEM_ACTION]", + "description": "The action that is required for the current peer to\n follow. [Rel: Skyway.SYSTEM_ACTION]", "type": "String" }, { "name": "message", - "description": "The reason of the action", + "description": "Reason for the action", "type": "String" } ], + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1347, - "description": "Event fired when a private message is broadcasted.", + "line": 1581, + "description": "Fired when a datachannel is successfully connected.", "itemtype": "event", - "name": "privateMessage", + "name": "Datachannel: CONN", "params": [ { - "name": "data", - "description": "Data to be sent over. Data is based on\n what the user has set.", - "type": "JSON|String" - }, + "name": "UNKNOWN", + "description": "", + "type": "String" + } + ], + "trigger": "dataChannelState", + "access": "private", + "tagname": "", + "since": "0.4.0", + "class": "Skyway" + }, + { + "file": "source\\skyway.js", + "line": 1590, + "description": "Fired when a datachannel has a blob data send request.", + "itemtype": "event", + "name": "Datachannel: WRQ", + "params": [ { - "name": "senderPeerId", - "description": "Sender", + "name": "userAgent", + "description": "The user's browser agent.", "type": "String" }, { - "name": "peerId", - "description": "Targeted Peer to receive the data", + "name": "name", + "description": "The blob data name.", "type": "String" }, { - "name": "isSelf", - "description": "Check if message is sent to self", - "type": "Boolean" + "name": "size", + "description": "The blob data size.", + "type": "Integer" + }, + { + "name": "chunkSize", + "description": "The expected chunk size.", + "type": "Integer" + }, + { + "name": "timeout", + "description": "The timeout in seconds.", + "type": "Integer" } ], + "access": "private", + "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1357, - "description": "Event fired when a public message is broadcasted.", + "line": 1602, + "description": "Fired when a datachannel has a blob data send request acknowledgement.\n- 0: User accepts the request.\n- -1: User rejects the request.\n- Above 0: User acknowledges the blob data packet.", "itemtype": "event", - "name": "publicMessage", + "name": "Datachannel: ACK", "params": [ { - "name": "data", - "description": "Data to be sent over. Data is based on\n what the user has set.", - "type": "JSON|String" - }, - { - "name": "senderPeerId", - "description": "Sender", - "type": "String" + "name": "ackN", + "description": "The acknowledge number.", + "type": "Integer" }, { - "name": "isSelf", - "description": "Check if message is sent to self", - "type": "Boolean" + "name": "userAgent", + "description": "The user's browser agent.", + "type": "Integer" } ], + "access": "private", + "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1368, - "description": "Send a chat message", - "itemtype": "method", - "name": "sendChatMessage", + "line": 1614, + "description": "Fired when a datachannel transfer has an error occurred.", + "itemtype": "event", + "name": "Datachannel: ERROR", "params": [ { "name": "message", - "description": "", + "description": "The error message.", "type": "String" }, { - "name": "targetPeerId", - "description": "Optional. Specified when peer wants to\n send a private chat message to the targeted peer.", - "type": "String" + "name": "isSender", + "description": "If user's the uploader.", + "type": "Boolean" } ], - "example": [ - "\n // Example 1: Send to all peers\n SkywayDemo.sendChatMessage('Hi there!');\n\n // Example 2: Send to specific peer\n SkywayDemo.sendChatMessage('Hi there peer!', targetPeerId)" - ], - "trigger": "chatMessageReceived", + "access": "private", + "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1398, - "description": "Send a chat message via DataChannel", - "itemtype": "method", - "name": "sendDataChannelChatMessage", + "line": 1623, + "description": "Fired when a datachannel chat has been received.", + "itemtype": "event", + "name": "Datachannel: CHAT", "params": [ { - "name": "message", - "description": "", + "name": "type", + "description": "If the message is a private or group message.\n- PRIVATE: This message is a private message targeted to a peer.\n- GROUP: This message is to be sent to all peers.", "type": "String" }, { - "name": "targetPeerId", - "description": "Optional. Specified when peer wants to\n send a private chat message to the targeted peer.", + "name": "peerId", + "description": "PeerId of the sender.", "type": "String" + }, + { + "name": "message", + "description": "The message data or object.", + "type": "JSON|String" } ], - "example": [ - "\n // Example 1: Send to all peers\n SkywayDemo.sendDataChannelChatMessage('Hi there!');\n\n // Example 2: Send to specific peer\n SkywayDemo.sendDataChannelChatMessage('Hi there peer!', targetPeerId)" - ], - "trigger": "chatMessageReceived", + "access": "private", + "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1438, - "description": "Broadcasts a private message", + "line": 1637, + "description": "Broadcast a message to all peers.\n- WARNING: Map arrays data would be lost when stringified\n in JSON, so refrain from using map arrays.", "itemtype": "method", - "name": "sendPrivateMessage", + "name": "sendMessage", "params": [ { - "name": "data", - "description": "", + "name": "message", + "description": "The message data to send.", "type": "String|JSON" }, { "name": "targetPeerId", - "description": "", + "description": "PeerId of the peer to send a private\n message data to.", "type": "String" } ], "example": [ - "\n // Example 1: Send JSON\n SkywayDemo.sendPrivateMessage({\n item1: data1,\n item2: data2\n }, targetPeerId);\n\n // Example 2: Send a String\n SkywayDemo.sendPrivateMessage(data1 + '-' + data2, targetPeerId);" + "\n // Example 1: Send to all peers\n SkywayDemo.sendMessage('Hi there!');\n\n // Example 2: Send to a targeted peer\n SkywayDemo.sendMessage('Hi there peer!', targetPeerId);" ], - "trigger": "privateMessage", - "beta": 1, + "trigger": "incomingMessage", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1469, - "description": "Broadcasts a public broadcast message", + "line": 1676, + "description": "Broadcasts to all P2P datachannel messages and broadcasts to a\npeer only when targetPeerId is provided.\n- This is ideal for sending strings or json objects lesser than 40KB.\n For huge data, please check out\n {{#crossLink \"Skyway/sendBlobData:method\"}}sendBlobData(){{/crossLink}}.\n- WARNING: Map arrays data would be lost when stringified\n in JSON, so refrain from using map arrays.", "itemtype": "method", - "name": "sendPublicMessage", + "name": "sendP2PMessage", "params": [ { - "name": "data", - "description": "", + "name": "message", + "description": "The message data to send.", "type": "String|JSON" + }, + { + "name": "targetPeerId", + "description": "Optional. Provide if you want to send to\n only one peer", + "type": "String" } ], "example": [ - "\n // Example 1: Send JSON\n SkywayDemo.sendPublicMessage({\n item1: data1,\n item2: data2\n });\n\n // Example 2: Send a String\n SkywayDemo.sendPublicMessage(data1 + '-' + data2);" + "\n // Example 1: Send to all peers\n SkywayDemo.sendP2PMessage('Hi there! This is from a DataChannel!');\n\n // Example 2: Send to specific peer\n SkywayDemo.sendP2PMessage('Hi there peer! This is from a DataChannel!', targetPeerId);" ], - "trigger": "publicMessage", - "beta": 1, + "trigger": "incomingMessage", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1498, - "description": "Get the default cam and microphone", + "line": 1718, + "description": "Get the default webcam and microphone", "itemtype": "method", "name": "getUserMedia", "params": [ @@ -2405,14 +2783,15 @@ } ], "example": [ - "\n // Default is to get both audio and video\n // Example 1: Get the default stream.\n SkywayDemo.getUserMedia();\n\n // Example 2: Get the audio stream only\n SkywayDemo.getUserMedia({\n 'video' : false,\n 'audio' : true\n });\n\n // Example 3: Set the stream settings for the audio and video\n SkywayDemo.getUserMedia({\n 'video' : {\n resolution: SkywayDemo.VIDEO_RESOLUTION.HD,\n frameRate: 50\n },\n 'audio' : { stereo: true }\n });" + "\n // Default is to get both audio and video\n // Example 1: Get both audio and video by default.\n SkywayDemo.getUserMedia();\n\n // Example 2: Get the audio stream only\n SkywayDemo.getUserMedia({\n 'video' : false,\n 'audio' : true\n });\n\n // Example 3: Set the stream settings for the audio and video\n SkywayDemo.getUserMedia({\n 'video' : {\n 'resolution': SkywayDemo.VIDEO_RESOLUTION.HD,\n 'frameRate': 50\n },\n 'audio' : { stereo: true }\n });" ], "trigger": "mediaAccessSuccess, mediaAccessError", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1559, + "line": 1811, "description": "Stream is available, let's throw the corresponding event with the stream attached.", "itemtype": "method", "name": "_onUserMediaSuccess", @@ -2431,11 +2810,12 @@ "trigger": "mediaAccessSuccess", "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1580, + "line": 1838, "description": "getUserMedia could not succeed.", "itemtype": "method", "name": "_onUserMediaError", @@ -2454,28 +2834,30 @@ "trigger": "mediaAccessFailure", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1600, - "description": "Handle every incoming message. If it's a bundle, extract single messages\nEventually handle the message(s) to\n{{#crossLink \"Skyway/_processSingleMessage:method\"}}_processSingleMessage(){{/crossLink}}", + "line": 1859, + "description": "Handle every incoming message. If it's a bundle, extract single messages\n- Eventually handle the message(s) to\n {{#crossLink \"Skyway/_processSingleMessage:method\"}}\n _processSingleMessage(){{/crossLink}}", "itemtype": "method", "name": "_processSigMessage", "params": [ { "name": "messageString", "description": "", - "type": "JSON" + "type": "String" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1620, + "line": 1881, "description": "This dispatch all the messages from the infrastructure to their respective handler", "itemtype": "method", "name": "_processingSingleMessage", @@ -2488,61 +2870,12 @@ ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1700, - "description": "Throw an event with the received chat message", - "itemtype": "method", - "name": "_chatHandler", - "params": [ - { - "name": "message", - "description": "", - "type": "JSON", - "props": [ - { - "name": "rid", - "description": "RoomId", - "type": "String" - }, - { - "name": "mid", - "description": "TargetMid.", - "type": "String" - }, - { - "name": "target", - "description": "targetPeerId. For private message", - "type": "String" - }, - { - "name": "data", - "description": "Chat message", - "type": "String" - }, - { - "name": "sender", - "description": "senderPeerId", - "type": "String" - }, - { - "name": "type", - "description": "Message type", - "type": "String" - } - ] - } - ], - "trigger": "chatMessageReceived", - "access": "private", - "tagname": "", - "class": "Skyway" - }, - { - "file": "source\\skyway.js", - "line": 1718, + "line": 1955, "description": "Signaling server error message", "itemtype": "method", "name": "_errorHandler", @@ -2554,22 +2887,22 @@ "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", + "description": "PeerId of the peer that is sending the error message.", "type": "String" }, { "name": "kind", - "description": "Error type", + "description": "The error kind.", "type": "String" }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2577,48 +2910,44 @@ ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1733, + "line": 1971, "description": "Signaling server wants us to move out.", "itemtype": "method", "name": "_redirectHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object.", "type": "JSON", "props": [ { "name": "rid", - "description": "RoomId", - "type": "String" - }, - { - "name": "mid", - "description": "TargetMid.", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "url", - "description": "Deprecated. Url to redirect to", + "description": "Deprecated. Url to redirect to.", "type": "String" }, { "name": "info", - "description": "Reason for redirect", + "description": "The reason for redirect", "type": "String" }, { "name": "action", - "description": "Action of the redirect\n [Rel: Skyway.SYSTEM_ACTION]", + "description": "The action of the redirect\n [Rel: Skyway.SYSTEM_ACTION]", "type": "String" }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2627,38 +2956,39 @@ "trigger": "systemAction", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1752, - "description": "User Information is updated", + "line": 1990, + "description": "User information is updated.", "itemtype": "method", "name": "_updateUserEventHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object.", "type": "JSON", "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", + "description": "PeerId of the peer that is sending the\n updated event.", "type": "String" }, { "name": "userData", - "description": "The Skyway._user.info.userData data.", + "description": "The peer's user data.", "type": "String" }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2667,12 +2997,13 @@ "trigger": "peerUpdated", "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1774, - "description": "Room Lock is Fired", + "line": 2013, + "description": "Room lock status is changed.", "itemtype": "method", "name": "_roomLockEventHandler", "params": [ @@ -2683,12 +3014,12 @@ "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", + "description": "PeerId of the peer that is sending the\n updated room lock status.", "type": "String" }, { @@ -2698,7 +3029,7 @@ }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2707,28 +3038,29 @@ "trigger": "roomLock", "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1791, - "description": "Peer Audio is muted/unmuted", + "line": 2033, + "description": "Peer Audio is muted/unmuted.", "itemtype": "method", "name": "_muteAudioEventHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", + "description": "PeerId of the peer that is sending\n their own updated audio stream status.", "type": "String" }, { @@ -2738,7 +3070,7 @@ }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2747,28 +3079,29 @@ "trigger": "peerUpdated", "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1812, - "description": "Peer Video is muted/unmuted", + "line": 2056, + "description": "Peer Video is muted/unmuted.", "itemtype": "method", "name": "_muteVideoEventHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", + "description": "PeerId of the peer that is sending\n their own updated video streams status.", "type": "String" }, { @@ -2778,7 +3111,7 @@ }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2787,33 +3120,34 @@ "trigger": "peerUpdated", "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1833, + "line": 2079, "description": "A peer left, let's clean the corresponding connection, and trigger an event.", "itemtype": "method", "name": "_byeHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", + "description": "PeerId of the peer that has left the room.", "type": "String" }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2822,53 +3156,49 @@ "trigger": "peerLeft", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1849, + "line": 2096, "description": "Throw an event with the received private message", "itemtype": "method", "name": "_privateMessageHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ - { - "name": "sender", - "description": "The senderPeerId.", - "type": "String" - }, { "name": "data", - "description": "The Data broadcasted", + "description": "The data broadcasted", "type": "JSON|String" }, { - "name": "nick", - "description": "Deprecated. Nickname of the user", + "name": "rid", + "description": "RoomId of the connected room.", "type": "String" }, { - "name": "mid", - "description": "TargetMid", + "name": "cid", + "description": "CredentialId of the room", "type": "String" }, { - "name": "cid", - "description": "The credentialId", + "name": "mid", + "description": "PeerId of the peer that is sending a private\n broadcast message", "type": "String" }, { - "name": "rid", - "description": "RoomId", - "type": "String" + "name": "isDataChannel", + "description": "Is the message sent from datachannel", + "type": "Boolean" }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2877,53 +3207,49 @@ "trigger": "privateMessage", "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1867, + "line": 2121, "description": "Throw an event with the received private message", "itemtype": "method", "name": "_publicMessageHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ - { - "name": "sender", - "description": "The senderPeerId.", - "type": "String" - }, { "name": "data", - "description": "The Data broadcasted", + "description": "The data broadcasted", "type": "JSON|String" }, { - "name": "nick", - "description": "Deprecated. Nickname of the user", + "name": "rid", + "description": "RoomId of the connected room.", "type": "String" }, { - "name": "mid", - "description": "TargetMid", + "name": "cid", + "description": "CredentialId of the room", "type": "String" }, { - "name": "cid", - "description": "The credentialId", + "name": "mid", + "description": "PeerId of the peer that is sending a private\n broadcast message", "type": "String" }, { - "name": "rid", - "description": "RoomId", - "type": "String" + "name": "isDataChannel", + "description": "Is the message sent from datachannel", + "type": "Boolean" }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2932,61 +3258,63 @@ "trigger": "publicMessage", "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1885, - "description": "Actually clean the peerconnection and trigger an event. Can be called by _byHandler\nand leaveRoom.", + "line": 2146, + "description": "Actually clean the peerconnection and trigger an event.\nCan be called by _byHandler and leaveRoom.", "itemtype": "method", "name": "_removePeer", "params": [ { "name": "peerId", - "description": "Id of the peer to remove", + "description": "PeerId of the peer that has left.", "type": "String" } ], "trigger": "peerLeft", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1901, + "line": 2164, "description": "We just joined a room! Let's send a nice message to all to let them know I'm in.", "itemtype": "method", "name": "_inRoomHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ { - "name": "pc_config", - "description": "The PeerConnection configuration", - "type": "JSON" + "name": "rid", + "description": "RoomId of the connected room.", + "type": "String" }, { "name": "sid", - "description": "Self peerId.", + "description": "PeerId of self.", "type": "String" }, { - "name": "rid", - "description": "RoomId", + "name": "mid", + "description": "PeerId of the peer that is", "type": "String" }, { - "name": "mid", - "description": "TargetMid.", - "type": "String" + "name": "pc_config", + "description": "The peerconnection configuration\n sending the joinRoom message.", + "type": "JSON" }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -2995,48 +3323,49 @@ "trigger": "peerJoined", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 1942, + "line": 2206, "description": "Someone just entered the room. If we don't have a connection with him/her,\nsend him a welcome. Handshake step 2 and 3.", "itemtype": "method", "name": "_enterHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", + "description": "PeerId of the peer that is sending the enter shake.", "type": "String" }, { "name": "agent", - "description": "Browser agent", + "description": "Peer's browser agent.", "type": "String" }, { "name": "version", - "description": "Browser version", + "description": "Peer's browser version.", "type": "String" }, { "name": "userInfo", - "description": "Peer Skyway._user.info data.", + "description": "Peer's user information.", "type": "String", "props": [ { "name": "settings", - "description": "Peer stream settings", + "description": "Peer's stream settings", "type": "JSON" }, { @@ -3081,12 +3410,12 @@ }, { "name": "mediaStatus.audioMuted", - "description": "If Peer's Audio stream is muted.", + "description": "If peer's audio stream is muted.", "type": "Boolean" }, { "name": "mediaStatus.videoMuted", - "description": "If Peer's Video stream is muted.", + "description": "If peer's video stream is muted.", "type": "Boolean" }, { @@ -3104,31 +3433,32 @@ ] } ], - "trigger": "handshakeProgress", + "trigger": "handshakeProgress, peerJoined", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2004, + "line": 2270, "description": "We have just received a welcome. If there is no existing connection with this peer,\ncreate one, then set the remotedescription and answer.", "itemtype": "method", "name": "_welcomeHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", + "description": "PeerId of the peer that is sending the welcome shake.", "type": "String" }, { @@ -3231,36 +3561,32 @@ ] } ], - "trigger": "handshakeProgress", + "trigger": "handshakeProgress, peerJoined", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2048, + "line": 2326, "description": "We have just received an offer. If there is no existing connection with this peer,\ncreate one, then set the remotedescription and answer.", "itemtype": "method", "name": "_offerHandler", "params": [ { "name": "message", - "description": "", + "description": "The message object received.", "type": "JSON", "props": [ { "name": "rid", - "description": "RoomId", + "description": "RoomId of the connected room.", "type": "String" }, { "name": "mid", - "description": "TargetMid.", - "type": "String" - }, - { - "name": "target", - "description": "targetPeerId", + "description": "PeerId of the peer that is sending the offer shake.", "type": "String" }, { @@ -3270,7 +3596,7 @@ }, { "name": "type", - "description": "Message type", + "description": "The type of message received.", "type": "String" } ] @@ -3279,40 +3605,42 @@ "trigger": "handshakeProgress", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2083, + "line": 2361, "description": "We have succesfully received an offer and set it locally. This function will take care\nof cerating and sendng the corresponding answer. Handshake step 4.", "itemtype": "method", "name": "_doAnswer", "params": [ { "name": "targetMid", - "description": "The peer we should connect to.", + "description": "PeerId of the peer to send answer to.", "type": "String" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2110, + "line": 2389, "description": "We have a peer, this creates a peerconnection object to handle the call.\nif we are the initiator, we then starts the O/A handshake.", "itemtype": "method", "name": "_openPeer", "params": [ { "name": "targetMid", - "description": "The peer we should connect to.", + "description": "PeerId of the peer we should connect to.", "type": "String" }, { "name": "peerAgentBrowser", - "description": "The peer's browser", + "description": "Peer's browser", "type": "String" }, { @@ -3328,35 +3656,37 @@ ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2142, + "line": 2422, "description": "Sends our Local MediaStream to other Peers.\nBy default, it sends all it's other stream", "itemtype": "method", "name": "_addLocalStream", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer to send local stream to.", "type": "String" } ], "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2168, + "line": 2449, "description": "The remote peer advertised streams, that we are forwarding to the app. This is part\nof the peerConnection's addRemoteDescription() API's callback.", "itemtype": "method", "name": "_onRemoteStreamAdded", "params": [ { "name": "targetMid", - "description": "", + "description": "PeerId of the peer that has remote stream to send.", "type": "String" }, { @@ -3365,43 +3695,45 @@ "type": "Event" } ], - "trigger": "addPeerStream", + "trigger": "incomingStream", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2182, + "line": 2464, "description": "It then sends it to the peer. Handshake step 3 (offer) or 4 (answer)", "itemtype": "method", "name": "_doCall", "params": [ { "name": "targetMid", - "description": "", + "description": "PeerId of the peer to send offer to.", "type": "String" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2212, - "description": "Find a line in the SDP and return it", + "line": 2495, + "description": "Finds a line in the SDP and returns it.\n- To set the value to the line, add an additional parameter to the method.", "itemtype": "method", "name": "_findSDPLine", "params": [ { "name": "sdpLines", - "description": "", + "description": "Sdp received.", "type": "Array" }, { "name": "condition", - "description": "", + "description": "The conditions.", "type": "Array" }, { @@ -3416,18 +3748,19 @@ }, "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2237, - "description": "Add Stereo to SDP. Requires OPUS", + "line": 2522, + "description": "Adds stereo feature to the SDP.\n- This requires OPUS to be enabled in the SDP or it will not work.", "itemtype": "method", "name": "_addStereo", "params": [ { "name": "sdpLines", - "description": "", + "description": "Sdp received.", "type": "Array" } ], @@ -3437,18 +3770,19 @@ }, "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2265, + "line": 2552, "description": "Set Audio, Video and Data Bitrate in SDP", "itemtype": "method", "name": "_setSDPBitrate", "params": [ { "name": "sdpLines", - "description": "", + "description": "Sdp received.", "type": "Array" } ], @@ -3458,18 +3792,19 @@ }, "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2295, + "line": 2583, "description": "This takes an offer or an aswer generated locally and set it in the peerconnection\nit then sends it to the peer. Handshake step 3 (offer) or 4 (answer)", "itemtype": "method", "name": "_setLocalAndSendMessage", "params": [ { "name": "targetMid", - "description": "", + "description": "PeerId of the peer to send offer/answer to.", "type": "String" }, { @@ -3481,29 +3816,35 @@ "trigger": "handshakeProgress", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2357, - "description": "This sets the STUN server specially for Firefox for ICE Connection", + "line": 2646, + "description": "Sets the STUN server specially for Firefox for ICE Connection.", "itemtype": "method", "name": "_setFirefoxIceServers", "params": [ { "name": "config", - "description": "", + "description": "Ice configuration servers url object.", "type": "JSON" } ], + "return": { + "description": "Updated configuration", + "type": "JSON" + }, "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2392, - "description": "Waits for MediaStream. Once the stream is loaded, callback is called\nIf there's not a need for stream, callback is called", + "line": 2683, + "description": "Waits for MediaStream.\n- Once the stream is loaded, callback is called\n- If there's not a need for stream, callback is called", "itemtype": "method", "name": "_waitForMediaStream", "params": [ @@ -3588,12 +3929,13 @@ ], "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2498, - "description": "Close/Open existing mediaStreams", + "line": 2733, + "description": "Opens or closes existing MediaStreams.", "itemtype": "method", "name": "_setStreams", "params": [ @@ -3621,12 +3963,13 @@ }, "access": "private", "tagname": "", + "since": "0.3.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2540, - "description": "Create a peerconnection to communicate with the peer whose ID is 'targetMid'.\nAll the peerconnection callbacks are set up here. This is a quite central piece.", + "line": 2776, + "description": "Creates a peerconnection to communicate with the peer whose ID is 'targetMid'.\nAll the peerconnection callbacks are set up here. This is a quite central piece.", "itemtype": "method", "name": "_createPeerConnection", "params": [ @@ -3642,11 +3985,12 @@ }, "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2620, + "line": 2857, "description": "A candidate has just been generated (ICE gathering) and will be sent to the peer.\nPart of connection establishment.", "itemtype": "method", "name": "_onIceCandidate", @@ -3665,12 +4009,13 @@ "trigger": "candidateGenerationState", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2665, - "description": "Handling reception of a candidate. handshake done, connection ongoing.", + "line": 2903, + "description": "Handles the reception of a candidate. handshake done, connection ongoing.", "itemtype": "method", "name": "_candidateHandler", "params": [ @@ -3719,12 +4064,13 @@ ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2711, - "description": "Handling reception of an answer (to a previous offer). handshake step 4.", + "line": 2950, + "description": "Handles the reception of an answer (to a previous offer). handshake step 4.", "itemtype": "method", "name": "_answerHandler", "params": [ @@ -3764,12 +4110,13 @@ "trigger": "handshakeProgress", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2740, - "description": "Send a message to the signaling server", + "line": 2980, + "description": "Sends a message to the signaling server.\n- Not to be confused with method\n {{#crossLink \"Skyway/sendMessage:method\"}}sendMessage(){{/crossLink}}\n that broadcasts messages. This is for sending socket messages.", "itemtype": "method", "name": "_sendMessage", "params": [ @@ -3781,407 +4128,447 @@ ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2756, - "description": "Initiate a Socket signaling connection.", + "line": 3000, + "description": "Initiate a socket signaling connection.", "itemtype": "method", "name": "_openChannel", "trigger": "channelMessage, channelOpen, channelError, channelClose", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2804, - "description": "Close the Socket signaling connection.", + "line": 3049, + "description": "Closes the socket signaling connection.", "itemtype": "method", "name": "_closeChannel", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2818, + "line": 3064, "description": "Create a DataChannel. Only SCTPDataChannel support", "itemtype": "method", "name": "_createDataChannel", "params": [ { "name": "peerId", - "description": "The peerId of which the dataChannel is connected to", + "description": "PeerId of the peer which the datachannel is connected to", "type": "String" }, { "name": "callback", - "description": "The callback which it returns the DataChannel object to", + "description": "The callback fired when datachannel is created.", "type": "Function" }, { "name": "dc", - "description": "The DataChannel object passed inside", + "description": "The datachannel object received.", "type": "Object" } ], "trigger": "dataChannelState", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2869, - "description": "Check DataChannel ReadyState. If ready, it sends a 'CONN'", + "line": 3116, + "description": "Checks datachannel ready state.\n- If ready, it sends a\n {{#crossLink \"Skyway/CONN:event\"}}CONN{{/crossLink}}.", "itemtype": "method", "name": "_checkDataChannelStatus", "params": [ { "name": "dc", - "description": "DataChannel object", + "description": "The datachannel object.", "type": "Object" } ], "trigger": "dataChannelState", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2890, - "description": "Sending of String Data over the DataChannels", + "line": 3140, + "description": "Sends data to the datachannel.", "itemtype": "method", "name": "_sendDataChannel", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer's datachannel to send data.", "type": "String" }, { "name": "data", - "description": "", + "description": "The data to send.", "type": "JSON" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2926, - "description": "To obtain the Peer that it's connected to from the DataChannel", + "line": 3177, + "description": "Obtains the peerId of the peer connected to the datachannel.", "itemtype": "method", "name": "_dataChannelPeer", "params": [ { "name": "channel", - "description": "", + "description": "The datachannel name.", "type": "String" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], "access": "private", "tagname": "", "deprecated": true, + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2938, - "description": "To obtain the Peer that it's connected to from the DataChannel", + "line": 3190, + "description": "Closes the datachannel.", "itemtype": "method", "name": "_closeDataChannel", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer's datachannel to close.", "type": "String" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 2956, - "description": "The Handler for all DataChannel Protocol events", + "line": 3209, + "description": "Handles all datachannel protocol events.", "itemtype": "method", "name": "_dataChannelHandler", "params": [ { "name": "data", - "description": "", - "type": "String" + "description": "The data received from datachannel.", + "type": "String|Object" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3003, - "description": "DataChannel TFTP Protocol Stage: WRQ\nThe sender has sent a request to send file\nFrom here, it's up to the user to accept or reject it", + "line": 3250, + "description": "The user receives a blob request.\nFrom here, it's up to the user to accept or reject it", "itemtype": "method", "name": "_dataChannelWRQHandler", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer that is sending the request.", "type": "String" }, { "name": "data", - "description": "", + "description": "The data object received from datachannel.", "type": "Array" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], "trigger": "dataTransferState", "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3047, - "description": "DataChannel TFTP Protocol Stage: ACK\nThe user sends a ACK of the request [accept/reject/nhe current\nindex of chunk to be sent over]", + "line": 3286, + "description": "User's response to accept or reject file.", + "itemtype": "method", + "name": "respondBlobRequest", + "params": [ + { + "name": "peerId", + "description": "PeerId of the peer that is expected to receive\n the request response.", + "type": "String" + }, + { + "name": "accept", + "description": "Accept the Blob download request or not.", + "type": "Boolean" + } + ], + "trigger": "dataTransferState", + "since": "0.4.0", + "class": "Skyway" + }, + { + "file": "source\\skyway.js", + "line": 3313, + "description": "The user receives an acknowledge of the blob request.", "itemtype": "method", "name": "_dataChannelACKHandler", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer that is sending the acknowledgement.", "type": "String" }, { "name": "data", - "description": "", + "description": "The data object received from datachannel.", "type": "Array" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], "trigger": "dataTransferState", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3103, - "description": "DataChannel TFTP Protocol Stage: CHAT\nThe user receives a DataChannel CHAT message", + "line": 3368, + "description": "The user receives a datachannel broadcast message.", "itemtype": "method", "name": "_dataChannelCHATHandler", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer that is sending a broadcast message.", "type": "String" }, { "name": "data", - "description": "", + "description": "The data object received from datachannel.", "type": "Array" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], - "trigger": "dataTransferState", + "trigger": "incomingMessage", "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3143, - "description": "DataChannel TFTP Protocol Stage: ERROR\nThe user received an error, usually an exceeded timeout.", + "line": 3416, + "description": "The user receives a timeout error.", "itemtype": "method", "name": "_dataChannelERRORHandler", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer that is sending the error.", "type": "String" }, { "name": "data", - "description": "", + "description": "The data object received from datachannel.", "type": "Array" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], "trigger": "dataTransferState", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3167, - "description": "DataChannel TFTP Protocol Stage: DATA\nThis is when the data is sent from the sender to the receiving user", + "line": 3440, + "description": "This is when the data is sent from the sender to the receiving user.", "itemtype": "method", "name": "_dataChannelDATAHandler", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the peer that is sending the data.", "type": "String" }, { "name": "dataString", - "description": "", + "description": "The data received.", "type": "ArrayBuffer|Blob|String" }, { "name": "dataType", - "description": "[Rel: Skyway.DATA_TRANSFER_DATA_TYPE]", + "description": "The data type received from datachannel.\n [Rel: Skyway.DATA_TRANSFER_DATA_TYPE]", "type": "String" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], "trigger": "dataTransferState", "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3244, - "description": "Set the DataChannel timeout. If exceeded, send the 'ERROR' message", + "line": 3518, + "description": "Sets the datachannel timeout.\n- If timeout is met, it will send the 'ERROR' message", "itemtype": "method", "name": "_setDataChannelTimeout", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the datachannel to set timeout.", "type": "String" }, { "name": "timeout", - "description": "", + "description": "The timeout to set in seconds.", "type": "Integer" }, { "name": "isSender", - "description": "", + "description": "Is peer the sender or the receiver?", "type": "Boolean" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3279, - "description": "Clear the DataChannel timeout as a response is received", + "line": 3555, + "description": "Clears the datachannel timeout.", "itemtype": "method", "name": "_clearDataChannelTimeout", "params": [ { "name": "peerId", - "description": "", + "description": "PeerId of the datachannel to clear timeout.", "type": "String" }, { "name": "isSender", - "description": "", + "description": "Is peer the sender or the receiver?", "type": "Boolean" }, { "name": "self", - "description": "", + "description": "Skyway object.", "type": "Skyway" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3296, - "description": "Convert base64 to raw binary data held in a string.\nDoesn't handle URLEncoded DataURIs\n- see StackOverflow answer #6850276 for code that does this\nThis is to convert the base64 binary string to a blob", + "line": 3573, + "description": "Converts base64 string to raw binary data.\n- Doesn't handle URLEncoded DataURIs\n- See StackOverflow answer #6850276 for code that does this\nThis is to convert the base64 binary string to a blob", "author": "Code from devnull69 @ stackoverflow.com", "itemtype": "method", "name": "_base64ToBlob", "params": [ { "name": "dataURL", - "description": "", + "description": "Blob base64 dataurl.", "type": "String" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3318, - "description": "To chunk the File (which already is a blob) into smaller blob files.\nFor now please send files below or around 2KB till chunking is implemented", + "line": 3596, + "description": "Chunks blob data into chunks.", "itemtype": "method", "name": "_chunkFile", "params": [ { "name": "blob", - "description": "", + "description": "The blob data to chunk.", "type": "Blob" }, { "name": "blobByteSize", - "description": "", + "description": "The blob data size.", "type": "Integer" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3347, - "description": "Removes non-alphanumeric characters from a string and return it.", + "line": 3625, + "description": "Removes non-alphanumeric characters from a string.", "itemtype": "method", "name": "_stripNonAlphanumeric", "params": [ @@ -4197,12 +4584,13 @@ }, "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3372, - "description": "Check if a text string consist of only alphanumeric characters.\nIf so, return true.\nIf not, return false.", + "line": 3651, + "description": "Check if a string consist of only alphanumeric characters.\n- If alphanumeric characters are found, it will return true,\n else it returns false.", "itemtype": "method", "name": "_alphanumeric", "params": [ @@ -4218,247 +4606,340 @@ }, "access": "private", "tagname": "", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3389, - "description": "Method to send Blob data to peers.\nPeers have the option to download or reject the file.", + "line": 3669, + "description": "Sends blob data to peer(s).\n- Note that peers have the option to download or reject receiving the blob data.\n- This method is ideal for sending files.\n- To send a private file to a peer, input the peerId after the\n data information.", "itemtype": "method", "name": "sendBlobData", "params": [ { "name": "data", - "description": "- The Blob data to be sent over", + "description": "The blob data to be sent over.", "type": "Blob" }, { "name": "dataInfo", - "description": "- The Blob data information", + "description": "The data information.", "type": "JSON", "props": [ + { + "name": "transferId", + "description": "TransferId of the data.", + "type": "String" + }, { "name": "name", - "description": "The Blob data name", + "description": "Data name.", "type": "String" }, { "name": "timeout", - "description": "The timeout to wait for packets", + "description": "Data timeout to wait for packets.\n [Default is 60].", "type": "Integer" }, { "name": "size", - "description": "The Blob data size. Default is 60.", + "description": "Data size", "type": "Integer" } ] }, { "name": "targetPeerId", - "description": "The specific peerId to send to.\n Leave blank to send to all peers.", + "description": "PeerId targeted to receive data.\n Leave blank to send to all peers.", "type": "String" } ], - "bubbles": "dataTransferState", "example": [ "\n // Send file to all peers connected\n SkywayDemo.sendBlobData(file, {\n 'name' : file.name,\n 'size' : file.size,\n 'timeout' : 67\n });\n\n // Send file to individual peer\n SkywayDemo.sendBlobData(blob, {\n 'name' : 'My Html',\n 'size' : blob.size,\n 'timeout' : 87\n }, targetPeerId);" ], "trigger": "dataTransferState", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3469, - "description": "Method to send Blob data to individual peer.\nThis sends the 'WRQ' and initiate the TFTP protocol.", + "line": 3755, + "description": "Sends blob data to individual peer.\n- This sends the {{#crossLink \"Skyway/WRQ:event\"}}WRQ{{/crossLink}}\n and to initiate the TFTP protocol.", "itemtype": "method", "name": "_sendBlobDataToPeer", "params": [ { "name": "data", - "description": "- The Blob data to be sent over", + "description": "The blob data to be sent over.", "type": "Blob" }, { "name": "dataInfo", - "description": "- The Blob data information", + "description": "The data information.", "type": "JSON", "props": [ { "name": "transferId", - "description": "The transfer Id", + "description": "TransferId of the data.", "type": "String" }, { "name": "name", - "description": "The Blob data name", + "description": "Data name.", "type": "String" }, { "name": "timeout", - "description": "The timeout to wait for packets.\n Default is 60.", + "description": "Data timeout to wait for packets.\n [Default is 60].", "type": "Integer" }, { "name": "size", - "description": "The Blob data size", + "description": "Data size", "type": "Integer" } ] }, { "name": "targetPeerId", - "description": "", + "description": "PeerId targeted to receive data.\n Leave blank to send to all peers.", "type": "String" } ], "access": "private", "tagname": "", + "since": "0.1.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3504, - "description": "Handle the Lock actions", + "line": 3793, + "description": "Handles all the room lock events.", "itemtype": "method", "name": "_handleLock", "params": [ { "name": "lockAction", - "description": "[Rel: SkywayDemo.LOCK_ACTION]", + "description": "Lock action to send to server for response.\n [Rel: SkywayDemo.LOCK_ACTION]", "type": "String" + }, + { + "name": "callback", + "description": "The callback to return the response after\n everything's loaded.", + "type": "Function" } ], "trigger": "roomLock", "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3546, - "description": "Restart the {{#crossLink \"Skyway/joinRoom:method\"}}joinRoom(){{/crossLink}}\nprocess to initiate Audio and Video", + "line": 3843, + "description": "Handles all audio and video mute events.\n- If there is no available audio or video stream, it will call\n {{#crossLink \"Skyway/leaveRoom:method\"}}leaveRoom(){{/crossLink}}\n and call {{#crossLink \"Skyway/joinRoom:method\"}}joinRoom(){{/crossLink}}\n to join user in the room to send their audio and video stream.", "itemtype": "method", "name": "_handleAV", "params": [ { "name": "mediaType", - "description": "", + "description": "Media types expected to receive.\n [Rel: 'audio' or 'video']", "type": "String" }, { - "name": "isEnabled", - "description": "", - "type": "Boolean" - }, - { - "name": "hasMedia", - "description": "", + "name": "enableMedia", + "description": "Enable it or disable it", "type": "Boolean" } ], "trigger": "peerUpdated", "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3580, - "description": "Lock the Room to prevent users from coming in", + "line": 3906, + "description": "Lock the room to prevent peers from joining.", "itemtype": "method", "name": "lockRoom", - "bubbles": "lockRoom", "example": [ "\n SkywayDemo.lockRoom();" ], "trigger": "lockRoom", - "beta": 1, + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3593, - "description": "Unlock the Room to allow users to come in", + "line": 3918, + "description": "Unlock the room to allow peers to join.", "itemtype": "method", "name": "unlockRoom", - "bubbles": "lockRoom", "example": [ "\n SkywayDemo.unlockRoom();" ], "trigger": "lockRoom", + "since": "0.2.0", + "class": "Skyway" + }, + { + "file": "source\\skyway.js", + "line": 3930, + "description": "Get the lock status of the room.\n- WARNING: If there's too many peers toggling the\n room lock feature at the same time, the returned results may not\n be completely correct since while retrieving the room lock status,\n another peer may be toggling it.", + "itemtype": "method", + "name": "isRoomLocked", + "example": [ + "\n if(SkywayDemo.isRoomLocked()) {\n SkywayDemo.unlockRoom();\n } else {\n SkywayDemo.lockRoom();\n }" + ], "beta": 1, + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3606, - "description": "Enable Microphone. If Microphone is not enabled from the\nbeginning, user would have to reinitate the\n{{#crossLink \"Skyway/joinRoom:method\"}}joinRoom(){{/crossLink}}\nprocess and ask for Microphone again.", + "line": 3952, + "description": "Enable microphone.\n- If microphone is not enabled from the beginning, user would have to reinitate the\n {{#crossLink \"Skyway/joinRoom:method\"}}joinRoom(){{/crossLink}}\n process and ask for microphone again.", "itemtype": "method", "name": "enableAudio", "trigger": "peerUpdated", "example": [ "\n SkywayDemo.enableAudio();" ], + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3633, - "description": "Disable Microphone. If Microphone is not enabled from the\nbeginning, there is no effect.", + "line": 3967, + "description": "Disable microphone.\n- If microphone is not enabled from the beginning, there is no effect.", "itemtype": "method", "name": "disableAudio", "example": [ "\n SkywayDemo.disableAudio();" ], "trigger": "peerUpdated", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3655, - "description": "Enable Webcam Video. If Webcam Video is not enabled from the\nbeginning, user would have to reinitate the\n{{#crossLink \"Skyway/joinRoom:method\"}}joinRoom(){{/crossLink}}\nprocess and ask for Webcam video again.", + "line": 3980, + "description": "Enable webcam video.\n- If webcam is not enabled from the beginning, user would have to reinitate the\n {{#crossLink \"Skyway/joinRoom:method\"}}joinRoom(){{/crossLink}}\n process and ask for webcam again.", "itemtype": "method", "name": "enableVideo", "example": [ "\n SkywayDemo.enableVideo();" ], "trigger": "peerUpdated", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3683, - "description": "Disable Webcam Video. If Webcam Video is not enabled from the\nbeginning, there is no effect.", + "line": 3995, + "description": "Disable webcam video.\n- If webcam is not enabled from the beginning, there is no effect.", "itemtype": "method", "name": "disableVideo", "example": [ "\n SkywayDemo.disableVideo();" ], "trigger": "peerUpdated", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3705, - "description": "Parse Stream settings", + "line": 4008, + "description": "Parse stream settings", "itemtype": "method", "name": "_parseStreamSettings", "params": [ { "name": "options", - "description": "", - "type": "JSON" + "description": "Optional. Media Constraints.", + "type": "JSON", + "props": [ + { + "name": "user", + "description": "Optional. User custom data.", + "type": "JSON" + }, + { + "name": "audio", + "description": "This call requires audio", + "type": "Boolean|JSON", + "props": [ + { + "name": "stereo", + "description": "Enabled stereo or not", + "type": "Boolean" + } + ] + }, + { + "name": "video", + "description": "This call requires video", + "type": "Boolean|JSON", + "props": [ + { + "name": "resolution", + "description": "[Rel: Skyway.VIDEO_RESOLUTION]", + "type": "JSON" + }, + { + "name": "resolution.width", + "description": "Video width", + "type": "Integer" + }, + { + "name": "resolution.height", + "description": "Video height", + "type": "Integer" + }, + { + "name": "frameRate", + "description": "Mininum frameRate of Video", + "type": "Integer" + } + ] + }, + { + "name": "bandwidth", + "description": "Bandwidth settings", + "type": "String", + "props": [ + { + "name": "audio", + "description": "Audio Bandwidth", + "type": "String" + }, + { + "name": "video", + "description": "Video Bandwidth", + "type": "String" + }, + { + "name": "data", + "description": "Data Bandwidth", + "type": "String" + } + ] + } + ] } ], "access": "private", "tagname": "", + "since": "0.4.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3772, - "description": "User to join the room.\nYou may call {{#crossLink \"Skyway/getUserMedia:method\"}}getUserMedia(){{/crossLink}}\nfirst if you want to get\nMediaStream and joining Room seperately.", + "line": 4097, + "description": "User to join the room.\n- You may call {{#crossLink \"Skyway/getUserMedia:method\"}}\n getUserMedia(){{/crossLink}} first if you want to get\n MediaStream and joining Room seperately.\n- If joinRoom() parameters is empty, it simply uses\n any previous media or user data settings.", "itemtype": "method", "name": "joinRoom", "params": [ @@ -4524,17 +5005,17 @@ { "name": "audio", "description": "Audio Bandwidth", - "type": "String" + "type": "Integer" }, { "name": "video", "description": "Video Bandwidth", - "type": "String" + "type": "Integer" }, { "name": "data", "description": "Data Bandwidth", - "type": "String" + "type": "Integer" } ] } @@ -4542,228 +5023,230 @@ } ], "example": [ - "\n // To just join the default room without any video or audio\n SkywayDemo.joinRoom();\n\n // To just join the default room with bandwidth settings\n SkywayDemo.joinRoom({\n bandwidth: {\n data: 14440\n }\n });\n\n // Example 1: To call getUserMedia and joinRoom seperately\n SkywayDemo.getUserMedia();\n SkywayDemo.on('mediaAccessSuccess', function (stream)) {\n attachMediaStream($('.localVideo')[0], stream);\n SkywayDemo.joinRoom();\n });\n\n // Example 2: Join a room without any video or audio\n SkywayDemo.joinRoom('room');\n\n // Example 3: Join a room with audio only\n SkywayDemo.joinRoom('room', {\n 'audio' : true,\n 'video' : false\n });\n\n // Example 4: Join a room with prefixed video width and height settings\n SkywayDemo.joinRoom('room', {\n 'audio' : true,\n 'video' : {\n 'res' : {\n 'width' : 640,\n 'height' : 320\n }\n }\n });\n\n // Example 5: Join a room with userData and settings with audio, video and bandwidth\n SkwayDemo.joinRoom({\n 'userData': {\n item1: 'My custom data',\n item2: 'Put whatever, string or JSON or array'\n },\n 'audio' : {\n 'stereo' : true\n },\n 'video' : {\n 'res' : SkywayDemo.VIDEO_RESOLUTION.VGA,\n 'frameRate' : 50\n },\n 'bandwidth' : {\n 'audio' : 48,\n 'video' : 256,\n 'data' : 14480\n }\n });" + "\n // To just join the default room without any video or audio\n // Note that calling joinRoom without any parameters\n // Still sends any available existing MediaStreams allowed.\n // See Examples 2, 3, 4 and 5 etc to prevent video or audio stream\n SkywayDemo.joinRoom();\n\n // To just join the default room with bandwidth settings\n SkywayDemo.joinRoom({\n 'bandwidth': {\n 'data': 14440\n }\n });\n\n // Example 1: To call getUserMedia and joinRoom seperately\n SkywayDemo.getUserMedia();\n SkywayDemo.on('mediaAccessSuccess', function (stream)) {\n attachMediaStream($('.localVideo')[0], stream);\n SkywayDemo.joinRoom();\n });\n\n // Example 2: Join a room without any video or audio\n SkywayDemo.joinRoom('room');\n\n // Example 3: Join a room with audio only\n SkywayDemo.joinRoom('room', {\n 'audio' : true,\n 'video' : false\n });\n\n // Example 4: Join a room with prefixed video width and height settings\n SkywayDemo.joinRoom('room', {\n 'audio' : true,\n 'video' : {\n 'resolution' : {\n 'width' : 640,\n 'height' : 320\n }\n }\n });\n\n // Example 5: Join a room with userData and settings with audio, video and bandwidth\n SkwayDemo.joinRoom({\n 'user': {\n 'item1': 'My custom data',\n 'item2': 'Put whatever, string or JSON or array'\n },\n 'audio' : {\n 'stereo' : true\n },\n 'video' : {\n 'res' : SkywayDemo.VIDEO_RESOLUTION.VGA,\n 'frameRate' : 50\n },\n 'bandwidth' : {\n 'audio' : 48,\n 'video' : 256,\n 'data' : 14480\n }\n });" ], "trigger": "peerJoined", + "since": "0.2.0", "class": "Skyway" }, { "file": "source\\skyway.js", - "line": 3896, - "description": "User to leave the room", + "line": 4228, + "description": "User to leave the room.", "itemtype": "method", "name": "leaveRoom", "example": [ "\n SkywayDemo.leaveRoom();" ], "trigger": "peerLeft, channelClose", + "since": "0.1.0", "class": "Skyway" } ], "warnings": [ { "message": "unknown tag: trigger", - "line": " source\\skyway.js:659" + "line": " source\\skyway.js:775" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:712" + "line": " source\\skyway.js:834" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:824" + "line": " source\\skyway.js:978" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:952" + "line": " source\\skyway.js:1107" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1069" + "line": " source\\skyway.js:1234" }, { "message": "unknown tag: iceconnectionstate", - "line": " source\\skyway.js:1202" + "line": " source\\skyway.js:1389" }, { - "message": "unknown tag: trigger", - "line": " source\\skyway.js:1368" + "message": "param name missing: {String}", + "line": " source\\skyway.js:1581" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1398" + "line": " source\\skyway.js:1581" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1438" + "line": " source\\skyway.js:1637" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1469" + "line": " source\\skyway.js:1676" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1498" + "line": " source\\skyway.js:1718" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1559" + "line": " source\\skyway.js:1811" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1580" + "line": " source\\skyway.js:1838" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1700" + "line": " source\\skyway.js:1971" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1733" + "line": " source\\skyway.js:1990" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1752" + "line": " source\\skyway.js:2013" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1774" + "line": " source\\skyway.js:2033" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1791" + "line": " source\\skyway.js:2056" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1812" + "line": " source\\skyway.js:2079" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1833" + "line": " source\\skyway.js:2096" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1849" + "line": " source\\skyway.js:2121" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1867" + "line": " source\\skyway.js:2146" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1885" + "line": " source\\skyway.js:2164" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1901" + "line": " source\\skyway.js:2206" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:1942" + "line": " source\\skyway.js:2270" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2004" + "line": " source\\skyway.js:2326" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2048" + "line": " source\\skyway.js:2449" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2168" + "line": " source\\skyway.js:2583" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2295" + "line": " source\\skyway.js:2857" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2620" + "line": " source\\skyway.js:2950" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2711" + "line": " source\\skyway.js:3000" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2756" + "line": " source\\skyway.js:3064" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2818" + "line": " source\\skyway.js:3116" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:2869" + "line": " source\\skyway.js:3250" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3003" + "line": " source\\skyway.js:3286" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3047" + "line": " source\\skyway.js:3313" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3103" + "line": " source\\skyway.js:3368" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3143" + "line": " source\\skyway.js:3416" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3167" + "line": " source\\skyway.js:3440" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3389" + "line": " source\\skyway.js:3669" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3504" + "line": " source\\skyway.js:3793" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3546" + "line": " source\\skyway.js:3843" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3580" + "line": " source\\skyway.js:3906" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3593" + "line": " source\\skyway.js:3918" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3606" + "line": " source\\skyway.js:3952" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3633" + "line": " source\\skyway.js:3967" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3655" + "line": " source\\skyway.js:3980" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3683" + "line": " source\\skyway.js:3995" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3772" + "line": " source\\skyway.js:4097" }, { "message": "unknown tag: trigger", - "line": " source\\skyway.js:3896" + "line": " source\\skyway.js:4228" }, { "message": "Missing item type\nEvent fired during ICE connection", - "line": " source\\skyway.js:1202" + "line": " source\\skyway.js:1389" } ] } \ No newline at end of file diff --git a/doc/files/source_skyway.js.html b/doc/files/source_skyway.js.html index ecae8b7c5..a997e2ff9 100644 --- a/doc/files/source_skyway.js.html +++ b/doc/files/source_skyway.js.html @@ -22,7 +22,7 @@

    - API Docs for: 0.3.1 + API Docs for: 0.4.0
    @@ -96,13 +96,18 @@

    File: source\skyway.js

    (function() { /** * Please check on the {{#crossLink "Skyway/init:method"}}init(){{/crossLink}} function - * on how you can initialize Skyway. + * on how you can initialize Skyway. Note that: + * - You will have to subscribe all Skyway events first before calling + * {{#crossLink "Skyway/init:method"}}init(){{/crossLink}}. + * - If you need an api key, please [register an api key](http:// + * developer.temasys.com.sg) at our developer console. * @class Skyway * @constructor * @example * // Getting started on how to use Skyway * var SkywayDemo = new Skyway(); * SkywayDemo.init('apiKey'); + * @since 0.1.0 */ function Skyway() { if (!(this instanceof Skyway)) { @@ -113,6 +118,7 @@

    File: source\skyway.js

    * @attribute VERSION * @type String * @readOnly + * @since 0.1.0 */ this.VERSION = '@@version'; /** @@ -125,6 +131,7 @@

    File: source\skyway.js

    * @param {String} SG Singapore server * @param {String} EU Europe server * @readOnly + * @since 0.3.0 */ this.REGIONAL_SERVER = { US1: 'us1', @@ -144,6 +151,7 @@

    File: source\skyway.js

    * @param {String} CONNECTED ICE Connection to Peer has been connected * @param {String} COMPLETED ICE Connection to Peer has been completed * @readOnly + * @since 0.1.0 */ this.ICE_CONNECTION_STATE = { STARTING: 'starting', @@ -166,6 +174,7 @@

    File: source\skyway.js

    * @param {String} ESTABLISHED All description is set and is applied * @param {String} CLOSED Connection closed. * @readOnly + * @since 0.1.0 */ this.PEER_CONNECTION_STATE = { STABLE: 'stable', @@ -183,6 +192,7 @@

    File: source\skyway.js

    * @param {String} GATHERING ICE Gathering to Peer has just started * @param {String} DONE ICE Gathering to Peer has been completed * @readOnly + * @since 0.1.0 */ this.CANDIDATE_GENERATION_STATE = { GATHERING: 'gathering', @@ -198,6 +208,7 @@

    File: source\skyway.js

    * @param {String} ANSWER Step 4. Received answer from Peer * @param {String} ERROR Error state * @readOnly + * @since 0.1.0 */ this.HANDSHAKE_PROGRESS = { ENTER: 'enter', @@ -218,6 +229,7 @@

    File: source\skyway.js

    * @param {String} CLOSED DataChannel has been closed. [WebRTC Standard] * @param {String} ERROR DataChannel has an error ocurring. * @readOnly + * @since 0.1.0 */ this.DATA_CHANNEL_STATE = { CONNECTING: 'connecting', @@ -236,6 +248,7 @@

    File: source\skyway.js

    * @param {String} REJECT System has rejected user from room * @param {String} CLOSED System has closed the room * @readOnly + * @since 0.1.0 */ this.SYSTEM_ACTION = { WARNING: 'warning', @@ -253,6 +266,7 @@

    File: source\skyway.js

    * Socket.io begins connection. * @param {Integer} ERROR Error state. Occurs when ReadyState fails loading. * @readOnly + * @since 0.1.0 */ this.READY_STATE_CHANGE = { INIT: 0, @@ -260,6 +274,59 @@

    File: source\skyway.js

    COMPLETED: 2, ERROR: -1 }; + + /** + * Error states that occurs when retrieving server information. States are: + * @attribute READY_STATE_CHANGE_ERROR + * @type JSON + * @param {Integer} API_INVALID Api Key provided does not exist. + * @param {Integer} API_DOMAIN_NOT_MATCH Api Key used in domain does not match. + * @param {Integer} API_CORS_DOMAIN_NOT_MATCH Api Key used in CORS domain does + * not match. + * @param {Integer} API_CREDENTIALS_INVALID Api Key credentials does not exist. + * @param {Integer} API_CREDENTIALS_NOT_MATCH Api Key credentials does not + * match what is expected. + * @param {Integer} API_INVALID_PARENT_KEY Api Key does not have a parent key + * nor is a root key. + * @param {Integer} API_NOT_ENOUGH_CREDIT Api Key does not have enough credits + * to use. + * @param {Integer} API_NOT_ENOUGH_PREPAID_CREDIT Api Key does not have enough + * prepaid credits to use. + * @param {Integer} API_FAILED_FINDING_PREPAID_CREDIT Api Key preapid payments + * does not exist. + * @param {Integer} API_NO_MEETING_RECORD_FOUND Api Key does not have a meeting + * record at this timing. This occurs when Api Key is a static one. + * @param {Integer} ROOM_LOCKED Room is locked. + * @param {Integer} NO_SOCKET_IO No socket.io dependency is loaded to use. + * @param {Integer} NO_XMLHTTPREQUEST_SUPPORT Browser does not support + * XMLHttpRequest to use. + * @param {Integer} NO_WEBRTC_SUPPORT Browser does not have WebRTC support. + * @param {Integer} NO_PATH No path is loaded yet. + * @param {Integer} INVALID_XMLHTTPREQUEST_STATUS Invalid XMLHttpRequest + * when retrieving information. + * @readOnly + * @since 0.4.0 + */ + this.READY_STATE_CHANGE_ERROR = { + API_INVALID: 4001, + API_DOMAIN_NOT_MATCH: 4002, + API_CORS_DOMAIN_NOT_MATCH: 4003, + API_CREDENTIALS_INVALID: 4004, + API_CREDENTIALS_NOT_MATCH: 4005, + API_INVALID_PARENT_KEY: 4006, + API_NOT_ENOUGH_CREDIT: 4007, + API_NOT_ENOUGH_PREPAID_CREDIT: 4008, + API_FAILED_FINDING_PREPAID_CREDIT: 4009, + API_NO_MEETING_RECORD_FOUND: 4010, + ROOM_LOCKED: 5001, + NO_SOCKET_IO: 1, + NO_XMLHTTPREQUEST_SUPPORT: 2, + NO_WEBRTC_SUPPORT: 3, + NO_PATH: 4, + INVALID_XMLHTTPREQUEST_STATUS: 5, + SCRIPT_ERROR: 6 + }; + /** * Data Channel Transfer Type. Types are: * @attribute DATA_TRANSFER_TYPE @@ -267,6 +334,7 @@

    File: source\skyway.js

    * @param {String} UPLOAD Error occurs at UPLOAD state * @param {String} DOWNLOAD Error occurs at DOWNLOAD state * @readOnly + * @since 0.1.0 */ this.DATA_TRANSFER_TYPE = { UPLOAD: 'upload', @@ -285,10 +353,12 @@

    File: source\skyway.js

    * @param {String} UPLOAD_COMPLETED Data Transfer of Upload has completed * @param {String} DOWNLOAD_COMPLETED Data Transfer of Download has completed * @readOnly + * @since 0.1.0 */ this.DATA_TRANSFER_STATE = { UPLOAD_STARTED: 'uploadStarted', DOWNLOAD_STARTED: 'downloadStarted', + UPLOAD_REQUEST: 'request', REJECTED: 'rejected', ERROR: 'error', UPLOADING: 'uploading', @@ -297,7 +367,7 @@

    File: source\skyway.js

    DOWNLOAD_COMPLETED: 'downloadCompleted' }; /** - * TODO : ArrayBuffer and Blob in DataChannel + * TODO : ArrayBuffer and Blob in DataChannel. * Data Channel Transfer Data type. Data Types are: * @attribute DATA_TRANSFER_DATA_TYPE * @type JSON @@ -305,6 +375,7 @@

    File: source\skyway.js

    * @param {String} ARRAY_BUFFER ArrayBuffer data * @param {String} BLOB Blob data * @readOnly + * @since 0.1.0 */ this.DATA_TRANSFER_DATA_TYPE = { BINARY_STRING: 'binaryString', @@ -312,31 +383,32 @@

    File: source\skyway.js

    BLOB: 'blob' }; /** - * Signaling message type. These message types are fixed. - * (Legend: S - Send only. R - Received only. SR - Can be Both). + * Signaling message type. + * - These message types are fixed. + * - (Legend: S - Send only. R - Received only. SR - Can be Both). * Signaling types are: * @attribute SIG_TYPE * @type JSON * @readOnly - * @param {String} JOIN_ROOM S. Join the Room - * @param {String} IN_ROOM R. User has already joined the Room - * @param {String} ENTER SR. Enter from handshake - * @param {String} WELCOME SR. Welcome from handshake - * @param {String} OFFER SR. Offer from handshake - * @param {String} ANSWER SR. Answer from handshake - * @param {String} CANDIDATE SR. Candidate received - * @param {String} BYE R. Peer left the room - * @param {String} CHAT SR. Chat message relaying - * @param {String} REDIRECT R. Server redirecting User - * @param {String} ERROR R. Server occuring an error - * @param {String} INVITE SR. TODO. - * @param {String} UPDATE_USER SR. Update of User information - * @param {String} ROOM_LOCK SR. Locking of Room - * @param {String} MUTE_VIDEO SR. Muting of User's video - * @param {String} MUTE_AUDIO SR. Muting of User's audio - * @param {String} PUBLIC_MESSAGE SR. Sending a public broadcast message. - * @param {String} PRIVATE_MESSAGE SR. Sending a private message + * @param {String} JOIN_ROOM [S] Join the Room + * @param {String} IN_ROOM [R] User has already joined the Room + * @param {String} ENTER [SR] Enter from handshake + * @param {String} WELCOME [SR] Welcome from handshake + * @param {String} OFFER [SR] Offer from handshake + * @param {String} ANSWER [SR] Answer from handshake + * @param {String} CANDIDATE [SR] Candidate received + * @param {String} BYE [R] Peer left the room + * @param {String} CHAT [SR] Deprecated. Chat message relaying + * @param {String} REDIRECT [R] Server redirecting User + * @param {String} ERROR [R] Server occuring an error + * @param {String} UPDATE_USER [SR] Update of User information + * @param {String} ROOM_LOCK [SR] Locking of Room + * @param {String} MUTE_VIDEO [SR] Muting of User's video + * @param {String} MUTE_AUDIO [SR] Muting of User's audio + * @param {String} PUBLIC_MESSAGE [SR] Sending a public broadcast message. + * @param {String} PRIVATE_MESSAGE [SR] Sending a private message * @private + * @since 0.3.0 */ this.SIG_TYPE = { JOIN_ROOM: 'joinRoom', @@ -350,13 +422,13 @@

    File: source\skyway.js

    CHAT: 'chat', REDIRECT: 'redirect', ERROR: 'error', - INVITE: 'invite', UPDATE_USER: 'updateUserEvent', ROOM_LOCK: 'roomLockEvent', MUTE_VIDEO: 'muteVideoEvent', MUTE_AUDIO: 'muteAudioEvent', PUBLIC_MESSAGE: 'public', - PRIVATE_MESSAGE: 'private' + PRIVATE_MESSAGE: 'private', + GROUP: 'group' }; /** * Lock Action States @@ -366,6 +438,7 @@

    File: source\skyway.js

    * @param {String} UNLOCK Unlock the room * @param {String} STATUS Get the status of the room if it's locked or not * @readOnly + * @since 0.2.0 */ this.LOCK_ACTION = { LOCK: 'lock', @@ -389,6 +462,7 @@

    File: source\skyway.js

    * @attribute VIDEO_RESOLUTION * @type JSON * @readOnly + * @since 0.2.0 */ this.VIDEO_RESOLUTION = { QVGA: { @@ -416,6 +490,7 @@

    File: source\skyway.js

    * @final * @required * @private + * @since 0.1.0 */ this._path = null; /** @@ -425,6 +500,7 @@

    File: source\skyway.js

    * @final * @required * @private + * @since 0.2.0 */ this._serverPath = '//api.temasys.com.sg'; /** @@ -433,6 +509,7 @@

    File: source\skyway.js

    * @type String * @default REGIONAL_SERVER.US1 * @private + * @since 0.3.0 */ this._serverRegion = null; /** @@ -440,6 +517,7 @@

    File: source\skyway.js

    * @attribute _roomServer * @type String * @private + * @since 0.3.0 */ this._roomServer = null; /** @@ -447,6 +525,7 @@

    File: source\skyway.js

    * @attribute _apiKey * @type String * @private + * @since 0.3.0 */ this._apiKey = null; /** @@ -454,6 +533,7 @@

    File: source\skyway.js

    * @attribute _defaultRoom * @type String * @private + * @since 0.3.0 */ this._defaultRoom = null; /** @@ -462,6 +542,7 @@

    File: source\skyway.js

    * @type String * @default _defaultRoom * @private + * @since 0.3.0 */ this._selectedRoom = null; /** @@ -470,6 +551,7 @@

    File: source\skyway.js

    * @type String * @private * @optional + * @since 0.3.0 */ this._roomStart = null; /** @@ -478,6 +560,7 @@

    File: source\skyway.js

    * @type Integer * @private * @optional + * @since 0.3.0 */ this._roomDuration = null; /** @@ -486,6 +569,7 @@

    File: source\skyway.js

    * @type String * @private * @optional + * @since 0.3.0 */ this._roomCredentials = null; /** @@ -493,6 +577,7 @@

    File: source\skyway.js

    * @attribute _key * @type String * @private + * @since 0.1.0 */ this._key = null; /** @@ -501,6 +586,7 @@

    File: source\skyway.js

    * @type Object * @required * @private + * @since 0.1.0 */ this._socket = null; /** @@ -508,6 +594,7 @@

    File: source\skyway.js

    * @attribute _socketVersion * @type Integer * @private + * @since 0.1.0 */ this._socketVersion = null; /** @@ -536,6 +623,7 @@

    File: source\skyway.js

    * @param {String|JSON} info.userData Peer custom data * @required * @private + * @since 0.3.0 */ this._user = null; /** @@ -568,47 +656,53 @@

    File: source\skyway.js

    * @param {Array} [room.pcHelper.sdpConstraints.optional] * @required * @private + * @since 0.3.0 */ this._room = null; /** - * Internal array of peerconnections + * Internal array of peer connections * @attribute _peerConnections - * @type Array + * @type Object * @required * @private + * @since 0.1.0 */ this._peerConnections = []; /** * Internal array of peer informations * @attribute _peerInformations - * @type Array + * @type Object * @private * @required + * @since 0.3.0 */ this._peerInformations = []; /** * Internal array of dataChannels * @attribute _dataChannels - * @type Array + * @type Object * @private * @required + * @since 0.2.0 */ this._dataChannels = []; /** * Internal array of dataChannel peers * @attribute _dataChannelPeers - * @type Array + * @type Object * @private * @required + * @since 0.2.0 */ this._dataChannelPeers = []; /** * The current ReadyState - * -1 'failed', 0 'false', 1 'in process', 2 'done' + * [Rel: Skyway.READY_STATE_CHANGE] * @attribute _readyState * @type Integer * @private * @required + * @since 0.1.0 */ this._readyState = 0; /** @@ -617,14 +711,25 @@

    File: source\skyway.js

    * @type Boolean * @private * @required + * @since 0.1.0 */ this._channel_open = false; + /** + * State if Room is locked or not + * @attribute _room_lock + * @type Boolean + * @private + * @required + * @since 0.4.0 + */ + this._room_lock = false; /** * State if User is in room or not * @attribute _in_room * @type Boolean * @private * @required + * @since 0.1.0 */ this._in_room = false; /** @@ -633,6 +738,7 @@

    File: source\skyway.js

    * @type JSON * @private * @required + * @since 0.1.0 */ this._uploadDataTransfers = {}; /** @@ -641,6 +747,7 @@

    File: source\skyway.js

    * @type JSON * @private * @required + * @since 0.1.0 */ this._uploadDataSessions = {}; /** @@ -649,6 +756,7 @@

    File: source\skyway.js

    * @type JSON * @private * @required + * @since 0.1.0 */ this._downloadDataTransfers = {}; /** @@ -657,6 +765,7 @@

    File: source\skyway.js

    * @type JSON * @private * @required + * @since 0.1.0 */ this._downloadDataSessions = {}; /** @@ -665,6 +774,7 @@

    File: source\skyway.js

    * @type JSON * @private * @required + * @since 0.1.0 */ this._dataTransfersTimeout = {}; /** @@ -674,6 +784,7 @@

    File: source\skyway.js

    * @private * @final * @required + * @since 0.1.0 */ this._chunkFileSize = 49152; // [25KB because Plugin] 60 KB Limit | 4 KB for info /** @@ -683,6 +794,7 @@

    File: source\skyway.js

    * @private * @final * @required + * @since 0.2.0 */ this._mozChunkFileSize = 16384; // Firefox the sender chunks 49152 but receives as 16384 /** @@ -692,6 +804,7 @@

    File: source\skyway.js

    * @default true * @private * @required + * @since 0.3.0 */ this._enableIceTrickle = true; /** @@ -701,21 +814,23 @@

    File: source\skyway.js

    * @default true * @private * @required + * @since 0.3.0 */ this._enableDataChannel = true; /** - * User stream settings + * User stream settings. By default, all is false. * @attribute _streamSettings * @type JSON * @default { - * 'audio' : true, - * 'video' : true + * 'audio' : false, + * 'video' : false * } * @private + * @since 0.2.0 */ this._streamSettings = { - audio: true, - video: true + audio: false, + video: false }; /** * Get information from server @@ -725,6 +840,7 @@

    File: source\skyway.js

    * @param {Function} callback Callback function after request is laoded * @param {JSON} params HTTP Params * @private + * @since 0.2.0 */ this._requestServerInfo = function(method, url, callback, params) { var xhr = new window.XMLHttpRequest(); @@ -756,12 +872,17 @@

    File: source\skyway.js

    * @trigger readyStateChange * @private * @required + * @since 0.1.0 */ this._parseInfo = function(info, self) { console.log(info); if (!info.pc_constraints && !info.offer_constraints) { - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, info.info); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: 200, + content: info.info, + errorCode: info.error + }); return; } console.log(JSON.parse(info.pc_constraints)); @@ -773,7 +894,8 @@

    File: source\skyway.js

    token: info.userCred, timeStamp: info.timeStamp, apiOwner: info.apiOwner, - streams: [] + streams: [], + info: {} }; self._room = { id: info.room_key, @@ -808,39 +930,60 @@

    File: source\skyway.js

    * @trigger readyStateChange * @private * @required + * @since 0.1.0 */ this._loadInfo = function(self) { if (!window.io) { console.error('API - Socket.io not loaded.'); - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, - 'Socket.io not found'); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: null, + content: 'Socket.io not found', + errorCode: self.READY_STATE_CHANGE_ERROR.NO_SOCKET_IO + }); return; } if (!window.XMLHttpRequest) { console.error('XHR - XMLHttpRequest not supported'); - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, - 'XMLHttpRequest not available'); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: null, + content: 'XMLHttpRequest not available', + errorCode: self.READY_STATE_CHANGE_ERROR.NO_XMLHTTPREQUEST_SUPPORT + }); return; } if (!window.RTCPeerConnection) { console.error('RTC - WebRTC not supported.'); - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, - 'WebRTC not available'); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: null, + content: 'WebRTC not available', + errorCode: self.READY_STATE_CHANGE_ERROR.NO_WEBRTC_SUPPORT + }); return; } if (!self._path) { console.error('API - No connection info. Call init() first.'); - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, - 'No API Path is found'); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: null, + content: 'No API Path is found', + errorCode: self.READY_STATE_CHANGE_ERROR.NO_PATH + }); return; } self._readyState = 1; self._trigger('readyStateChange', self.READY_STATE_CHANGE.LOADING); self._requestServerInfo('GET', self._path, function(status, response) { if (status !== 200) { + // 403 - Room is locked + // 401 - API Not authorized + // 402 - run out of credits var errorMessage = 'XMLHttpRequest status not OK\nStatus was: ' + status; self._readyState = 0; - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, errorMessage); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: status, + content: (response) ? (response.info || errorMessage) : errorMessage, + errorCode: response.error || + self.READY_STATE_CHANGE_ERROR.INVALID_XMLHTTPREQUEST_STATUS + }); console.error(errorMessage); return; } @@ -852,16 +995,17 @@

    File: source\skyway.js

    } this.Skyway = Skyway; /** - * Let app register a callback function to an event + * To register a callback function to an event. * @method on - * @param {String} eventName - * @param {Function} callback + * @param {String} eventName The Skyway event. + * @param {Function} callback The callback everytime the event is fired. * @example * SkywayDemo.on('peerJoined', function (peerId, peerInfo) { * console.info(peerId + ' has joined the room'); * console.log('Peer information are:'); * console.info(peerInfo); * }); + * @since 0.1.0 */ Skyway.prototype.on = function(eventName, callback) { if ('function' === typeof callback) { @@ -871,12 +1015,13 @@

    File: source\skyway.js

    }; /** - * Let app unregister a callback function from an event + * To unregister a callback function from an event. * @method off - * @param {String} eventName - * @param {Function} callback + * @param {String} eventName The Skyway event. + * @param {Function} callback The callback everytime the event is fired. * @example * SkywayDemo.off('peerJoined', callback); + * @since 0.1.0 */ Skyway.prototype.off = function(eventName, callback) { if (callback === undefined) { @@ -895,28 +1040,37 @@

    File: source\skyway.js

    /** * Trigger all the callbacks associated with an event - * Note that extra arguments can be passed to the callback - * which extra argument can be expected by callback is documented by each event + * - Note that extra arguments can be passed to the callback which + * extra argument can be expected by callback is documented by each event. * @method _trigger * @param {String} eventName * @for Skyway * @private + * @since 0.1.0 */ Skyway.prototype._trigger = function(eventName) { var args = Array.prototype.slice.call(arguments), arr = this._events[eventName]; args.shift(); - for (var e in arr) { - if (arr[e].apply(this, args) === false) { - break; + if (arr) { + for (var e in arr) { + if (arr.hasOwnProperty(e)) { + try { + if (arr[e].apply(this, args) === false) { + break; + } + } catch(error) { + console.warn(error); + } + } } } }; /** - * IMPORTANT: Please call this method to load all server information before joining - * the room or doing anything else. - * This is Init function to load Skyway. + * Initialize Skyway + * - <b><i>IMPORTANT</i></b>: Please call this method to load all server + * information before joining the room or doing anything else. * @method init * @param {String|JSON} options Connection options or API Key ID * @param {String} options.apiKey API Key ID to identify with the Temasys backend server @@ -926,11 +1080,11 @@

    File: source\skyway.js

    * If there's no room provided, default room would be used. * @param {String} options.region Optional. The regional server that user chooses to use. * [Rel: Skyway.REGIONAL_SERVER] - * @param {String} options.iceTrickle Optional. The option to enable iceTrickle or not. + * @param {Boolean} options.iceTrickle Optional. The option to enable iceTrickle or not. * Default is true. - * @param {String} options.dataChannel Optional. The option to enable dataChannel or not. + * @param {Boolean} options.dataChannel Optional. The option to enable dataChannel or not. * Default is true. - * @param {String} options.credentials Optional. Credentials options + * @param {JSON} options.credentials Optional. Credentials options * @param {String} options.credentials.startDateTime The Start timing of the * meeting in Date ISO String * @param {Integer} options.credentials.duration The duration of the meeting @@ -977,6 +1131,7 @@

    File: source\skyway.js

    * @trigger readyStateChange * @for Skyway * @required + * @since 0.3.0 */ Skyway.prototype.init = function(options) { if (!options) { @@ -999,7 +1154,7 @@

    File: source\skyway.js

    roomserver = options.roomServer || roomserver; roomserver = (roomserver.lastIndexOf('/') === (roomserver.length - 1)) ? roomserver.substring(0, - str.length - 1) : roomserver; + roomserver.length - 1) : roomserver; region = options.region || region; defaultRoom = options.defaultRoom || apiKey; room = defaultRoom; @@ -1042,32 +1197,33 @@

    File: source\skyway.js

    }; /** - * Reinitialize Skyway signaling credentials + * Re-initialize Skyway signaling credentials. * @method _reinit - * @param {Function} callback Once everything is done * @param {JSON} options * @param {String} options.roomserver * @param {String} options.apiKey * @param {String} options.defaultRoom * @param {String} options.room * @param {String} options.region - * @param {String} options.iceTrickle - * @param {String} options.dataChannel - * @param {String} options.credentials + * @param {Boolean} options.iceTrickle + * @param {Boolean} options.dataChannel + * @param {JSON} options.credentials * @param {String} options.credentials.startDateTime * @param {Integer} options.credentials.duration * @param {String} options.credentials.credentials + * @param {Function} callback Once everything is initialized. * @trigger readyStateChange * @private + * @since 0.4.0 */ - Skyway.prototype._reinit = function(callback, options) { + Skyway.prototype._reinit = function(options, callback) { var self = this; var startDateTime, duration, credentials; var apiKey = options.apiKey || self._apiKey; var roomserver = options.roomServer || self._roomServer; roomserver = (roomserver.lastIndexOf('/') === (roomserver.length - 1)) ? roomserver.substring(0, - str.length - 1) : roomserver; + roomserver.length - 1) : roomserver; var region = options.region || self._serverRegion; var defaultRoom = options.defaultRoom || self._defaultRoom; var room = options.room || defaultRoom; @@ -1110,7 +1266,12 @@

    File: source\skyway.js

    if (status !== 200) { var errorMessage = 'XMLHttpRequest status not OK.\nStatus was: ' + status; self._readyState = 0; - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, errorMessage); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: status, + content: (response) ? (response.info || errorMessage) : errorMessage, + errorCode: response.error || + self.READY_STATE_CHANGE_ERROR.INVALID_XMLHTTPREQUEST_STATUS + }); console.error(errorMessage); return; } @@ -1150,7 +1311,11 @@

    File: source\skyway.js

    callback(); } catch (error) { self._readyState = 0; - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, error); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: null, + content: error, + errorCode: self.READY_STATE_CHANGE_ERROR.SCRIPT_ERROR + }); console.error('API - Error occurred rejoining room'); console.error(error); return; @@ -1159,9 +1324,13 @@

    File: source\skyway.js

    }; /** - * Set and Update the User information. Please note that the custom - * data would be overrided so please call getUser and then modify the - * information you want individually. + * Updates the User information. + * - Please note that the custom data would be overrided so please call + * {{#crossLink "Skyway/getUserData:method"}}getUserData(){{/crossLink}} + * and then modify the information you want individually. + * - {{#crossLink "Skyway/peerUpdated:event"}}peerUpdated{{/crossLink}} + * only fires after <b>setUserData()</b> is fired + * after the user joins the room. * @method setUserData * @param {JSON} userData User custom data * @example @@ -1177,64 +1346,63 @@

    File: source\skyway.js

    * userData.userData.fbUserId = 'another Id'; * SkywayDemo.setUserData(userData); * @trigger peerUpdated + * @since 0.3.0 */ Skyway.prototype.setUserData = function(userData) { var self = this; // NOTE ALEX: be smarter and copy fields and only if different - var setUserData = function () { - var initial = (!self._user.info) ? true : false; - var params = { - type: self.SIG_TYPE.UPDATE_USER, - mid: self._user.sid, - rid: self._room.id - }; - self._user.info = self._user.info || {}; - self._user.info.userData = userData || - self._user.info.userData || {}; - console.info(self._user.info); - console.info(userData); - if (self._in_room && !initial) { - params.userData = self._user.info.userData; - self._sendMessage(params); - self._trigger('peerUpdated', self._user.sid, self._user.info, true); - } - }; - if (self._user) { - setUserData(); - } else { - var checkReadyState = setInterval(function () { - if (self._readyState === self.READY_STATE_CHANGE.COMPLETED) { - clearInterval(checkReadyState); - setUserData(); + var checkInRoom = setInterval(function () { + if (self._readyState === self.READY_STATE_CHANGE.COMPLETED) { + self._user.info = self._user.info || {}; + self._user.info.userData = userData || + self._user.info.userData || {}; + if (self._in_room) { + clearInterval(checkInRoom); + self._sendMessage({ + type: self.SIG_TYPE.UPDATE_USER, + mid: self._user.sid, + rid: self._room.id, + userData: self._user.info.userData + }); + self._trigger('peerUpdated', self._user.sid, self._user.info, true); } - }, 500); - } + } + }, 50); }; /** - * Get the User Information + * Gets the user information. * @method getUserData - * @return {JSON} User information + * @return {JSON|} User information * @example * var userInfo = SkywayDemo.getUserData(); + * @since 0.4.0 */ Skyway.prototype.getUserData = function() { - return this._user.info; + return (this._user) ? + ((this._user.info) ? (this._user.info.userData || '') + : '') : ''; }; /** - * Get the Peer Information + * Gets the peer information. + * - If input peerId is user's id or empty, <b>getPeerInfo()</b> + * would return user's peer information. * @method getPeerInfo * @param {String} peerId * @return {JSON} Peer information * @example + * // Example 1: To get other peer's information * var peerInfo = SkywayDemo.getPeerInfo(peerId); + * + * // Example 2: To get own information + * var userInfo = SkywayDemo.getPeerInfo(); + * @since 0.4.0 */ Skyway.prototype.getPeerInfo = function(peerId) { - if (!peerId) { - return; - } - return this._peerInformations[peerId]; + return (peerId && peerId !== this._user.sid) ? + this._peerInformations[peerId] : + ((this._user) ? this._user.info : null); }; /* Syntactically private variables and utility functions */ @@ -1243,90 +1411,103 @@

    File: source\skyway.js

    * Event fired when a successfull connection channel has been established * with the signaling server * @event channelOpen + * @since 0.1.0 */ 'channelOpen': [], /** * Event fired when the channel has been closed. * @event channelClose + * @since 0.1.0 */ 'channelClose': [], /** - * Event fired when we received a message from the sig server.. + * Event fired when we received a message from the signaling server. * @event channelMessage * @param {JSON} message + * @since 0.1.0 */ 'channelMessage': [], /** * Event fired when there was an error with the connection channel to the sig server. * @event channelError - * @param {String} error + * @param {Object|String} error Error message or object thrown. + * @since 0.1.0 */ 'channelError': [], /** * Event fired whether the room is ready for use * @event readyStateChange * @param {String} readyState [Rel: Skyway.READY_STATE_CHANGE] - * @param {String} error Error message when there's an error + * @param {JSON} error Error object thrown. + * @param {Integer} error.status HTTP status when retrieving information. + * May be empty for other errors. + * @param {String} error.content A short description of the error + * @param {Integer} error.errorCode The error code for the type of error + * [Rel: Skyway.READY_STATE_CHANGE_ERROR] + * @since 0.4.0 */ 'readyStateChange': [], /** * Event fired when a step of the handshake has happened. Usefull for diagnostic * or progress bar. * @event handshakeProgress - * @param {String} step [Rel: Skyway.HANDSHAKE_PROGRESS] - * @param {String} peerId - * @param {JSON|Object|String} error Error message when error occurs + * @param {String} step The current handshake progress step. + * [Rel: Skyway.HANDSHAKE_PROGRESS] + * @param {String} peerId PeerId of the peer's handshake progress. + * @param {JSON|Object|String} error Error message or object thrown. + * @since 0.3.0 */ 'handshakeProgress': [], /** * Event fired during ICE gathering * @event candidateGenerationState - * @param {String} state [Rel: Skyway.CANDIDATE_GENERATION_STATE] - * @param {String} peerId + * @param {String} state The current ice candidate generation state. + * [Rel: Skyway.CANDIDATE_GENERATION_STATE] + * @param {String} peerId PeerId of the peer that had an ice candidate + * generation state change. + * @since 0.1.0 */ 'candidateGenerationState': [], /** * Event fired during Peer Connection state change * @event peerConnectionState - * @param {String} state [Rel: Skyway.PEER_CONNECTION_STATE] + * @param {String} state The current peer connection state. + * [Rel: Skyway.PEER_CONNECTION_STATE] + * @param {String} peerId PeerId of the peer that had a peer connection state + * change. + * @since 0.1.0 */ 'peerConnectionState': [], /** * Event fired during ICE connection * @iceConnectionState - * @param {String} state [Rel: Skyway.ICE_CONNECTION_STATE] - * @param {String} peerId + * @param {String} state The current ice connection state. + * [Rel: Skyway.ICE_CONNECTION_STATE] + * @param {String} peerId PeerId of the peer that had an ice connection state change. + * @since 0.1.0 */ 'iceConnectionState': [], //-- per peer, local media events /** * Event fired when allowing webcam media stream fails * @event mediaAccessError - * @param {Object|String} error + * @param {Object|String} error Error message or object thrown. + * @since 0.1.0 */ 'mediaAccessError': [], /** * Event fired when allowing webcam media stream passes * @event mediaAccessSuccess - * @param {Object} stream + * @param {Object} stream MediaStream object. + * @since 0.1.0 */ 'mediaAccessSuccess': [], - /** - * Event fired when a chat message is received from other peers - * @event chatMessageReceived - * @param {String} message - * @param {String} senderPeerId - * @param {String|JSON} userData - * @param {Boolean} isPrivate - * @param {Boolean} isSelf - */ - 'chatMessageReceived': [], /** * Event fired when a peer joins the room. Inactive audio or video means that the * audio is muted or video is muted. * @event peerJoined - * @param {String} peerId - * @param {JSON} peerInfo + * @param {String} peerId PeerId of the peer that joined the room. + * @param {JSON} peerInfo Peer Information of the peer * @param {JSON} peerInfo.settings Peer stream settings * @param {Boolean|JSON} peerInfo.settings.audio * @param {Boolean} peerInfo.settings.audio.stereo @@ -1340,14 +1521,15 @@

    File: source\skyway.js

    * @param {Boolean} peerInfo.mediaStatus.videoMuted If Peer's Video stream is muted. * @param {String|JSON} peerInfo.userData Peer custom data * @param {Boolean} isSelf Is the Peer self. + * @since 0.3.0 */ 'peerJoined': [], /** * Event fired when a peer information is updated. Inactive audio or video means that the * audio is muted or video is muted. * @event peerUpdated - * @param {String} peerId - * @param {JSON} peerInfo + * @param {String} peerId PeerId of the peer that had information updaed. + * @param {JSON} peerInfo Peer Information of the peer * @param {JSON} peerInfo.settings Peer stream settings * @param {Boolean|JSON} peerInfo.settings.audio * @param {Boolean} peerInfo.settings.audio.stereo @@ -1360,14 +1542,29 @@

    File: source\skyway.js

    * @param {Boolean} peerInfo.mediaStatus.audioMuted If Peer's Audio stream is muted. * @param {Boolean} peerInfo.mediaStatus.videoMuted If Peer's Video stream is muted. * @param {String|JSON} peerInfo.userData Peer custom data - * @param {Boolean} isSelf Is the Peer self. + * @param {Boolean} isSelf Is the peer self. + * @since 0.3.0 */ 'peerUpdated': [], /** * Event fired when a peer leaves the room * @event peerLeft - * @param {String} peerId, - * @param {Boolean} isSelf + * @param {String} peerId PeerId of the peer that left. + * @param {JSON} peerInfo Peer Information of the peer + * @param {JSON} peerInfo.settings Peer stream settings + * @param {Boolean|JSON} peerInfo.settings.audio + * @param {Boolean} peerInfo.settings.audio.stereo + * @param {Boolean|JSON} peerInfo.settings.video + * @param {JSON} peerInfo.settings.video.resolution [Rel: Skyway.VIDEO_RESOLUTION] + * @param {Integer} peerInfo.settings.video.resolution.width + * @param {Integer} peerInfo.settings.video.resolution.height + * @param {Integer} peerInfo.settings.video.frameRate + * @param {JSON} peerInfo.mediaStatus Peer stream status. + * @param {Boolean} peerInfo.mediaStatus.audioMuted If Peer's Audio stream is muted. + * @param {Boolean} peerInfo.mediaStatus.videoMuted If Peer's Video stream is muted. + * @param {String|JSON} peerInfo.userData Peer custom data + * @param {Boolean} isSelf Is the peer self. + * @since 0.3.0 */ 'peerLeft': [], /** @@ -1376,219 +1573,242 @@

    File: source\skyway.js

    * @param {JSON} users The list of users * @private * @deprecated + * @since 0.1.0 */ 'presenceChanged': [], //-- per peer, peer connection events /** - * Event fired when a remote stream has become available - * @event addPeerStream - * @param {String} peerId - * @param {Object} stream - * @param {Boolean} isSelf + * Event fired when a remote stream has become available. + * - This occurs after the user joins the room. + * - This is changed from <b>addPeerStream</b> event. Note that + * <b>addPeerStream</b> is removed from the specs. + * @event incomingStream + * @param {Object} stream MediaStream object. + * @param {String} peerId PeerId of the peer that is sending the stream. + * @param {Boolean} isSelf Is the peer self. + * @since 0.4.0 */ - 'addPeerStream': [], + 'incomingStream': [], /** - * TODO Event fired when a remote stream has become unavailable - * @event removePeerStream - * @param {String} peerId - * @private + * Event fired when a message being broadcasted is received. + * @event incomingMessage + * @param {JSON} message Message object that is received. + * @param {JSON|String} message.content Data that is broadcasted. + * @param {String} message.sendPeerId PeerId of the sender peer. + * @param {String} message.targetPeerId PeerId that is specifically + * targeted to receive the message. + * @param {Boolean} message.isPrivate Is data received a private message. + * @param {Boolean} message.isDataChannel Is data received from a data channel. + * @param {String} peerId PeerId of the sender peer. + * @param {Boolean} isSelf Check if message is sent to self + * @since 0.4.0 */ - 'removePeerStream': [], + 'incomingMessage': [], /** - * Event fired when a room is locked + * Event fired when a room lock status has changed. * @event roomLock - * @param {Boolean} success - * @param {Boolean} isLocked - * @param {String} error + * @param {Boolean} isLocked Is the room locked. + * @param {String} peerId PeerId of the peer that is locking/unlocking the room. + * @param {JSON} peerInfo Peer Information of the peer + * @param {JSON} peerInfo.settings Peer stream settings + * @param {Boolean|JSON} peerInfo.settings.audio + * @param {Boolean} peerInfo.settings.audio.stereo + * @param {Boolean|JSON} peerInfo.settings.video + * @param {JSON} peerInfo.settings.video.resolution [Rel: Skyway.VIDEO_RESOLUTION] + * @param {Integer} peerInfo.settings.video.resolution.width Video width + * @param {Integer} peerInfo.settings.video.resolution.height Video height + * @param {Integer} peerInfo.settings.video.frameRate + * @param {JSON} peerInfo.mediaStatus Peer stream status. + * @param {Boolean} peerInfo.mediaStatus.audioMuted If Peer's Audio stream is muted. + * @param {Boolean} peerInfo.mediaStatus.videoMuted If Peer's Video stream is muted. + * @param {String|JSON} peerInfo.userData Peer custom data + * @param {Boolean} isSelf Is the peer self. + * @since 0.4.0 */ 'roomLock': [], //-- data state events /** - * Event fired when a DataChannel's state has changed + * Event fired when a peer's datachannel state has changed. * @event dataChannelState - * @param {String} state [Rel: Skyway.DATA_CHANNEL_STATE] - * @param {String} peerId + * @param {String} state The current datachannel state. + * [Rel: Skyway.DATA_CHANNEL_STATE] + * @param {String} peerId PeerId of peer that has a datachannel state change. + * @since 0.1.0 */ 'dataChannelState': [], /** - * Event fired when a Peer there is a Data Transfer going on + * Event fired when a data transfer state has changed. * @event dataTransferState - * @param {String} state [Rel: Skyway.DATA_TRANSFER_STATE] - * @param {String} transferId ID of the Data Transfer - * @param {String} peerId Peer's ID - * @param {JSON} transferInfo Available data may vary at different state. + * @param {String} state The current data transfer state. + * [Rel: Skyway.DATA_TRANSFER_STATE] + * @param {String} transferId TransferId of the data + * @param {String} peerId PeerId of the peer that has a data + * transfer state change. + * @param {JSON} transferInfo Transfer information. * @param {JSON} transferInfo.percentage The percetange of data being * uploaded / downloaded * @param {JSON} transferInfo.senderPeerId * @param {JSON} transferInfo.data Blob data URL - * @param {JSON} transferInfo.name Data name - * @param {JSON} transferInfo.size Data size - * @param {JSON} transferInfo.message Error message + * @param {JSON} transferInfo.name Blob data name + * @param {JSON} transferInfo.size Blob data size + * @param {JSON} transferInfo.message Error object thrown. * @param {JSON} transferInfo.type Where the error message occurred. * [Rel: Skyway.DATA_TRANSFER_TYPE] + * @since 0.1.0 */ 'dataTransferState': [], /** * Event fired when the Signalling server responds to user regarding * the state of the room * @event systemAction - * @param {String} action [Rel: Skyway.SYSTEM_ACTION] - * @param {String} message The reason of the action + * @param {String} action The action that is required for the current peer to + * follow. [Rel: Skyway.SYSTEM_ACTION] + * @param {String} message Reason for the action + * @since 0.1.0 */ - 'systemAction': [], + 'systemAction': [] + }; + + Skyway.prototype._dataChannelEvents = { /** - * Event fired when a private message is broadcasted. - * @event privateMessage - * @param {JSON|String} data Data to be sent over. Data is based on - * what the user has set. - * @param {String} senderPeerId Sender - * @param {String} peerId Targeted Peer to receive the data - * @param {Boolean} isSelf Check if message is sent to self + * Fired when a datachannel is successfully connected. + * @event Datachannel: CONN + * @param {String} + * @trigger dataChannelState + * @private + * @since 0.4.0 */ - 'privateMessage': [], + 'CONN': [], /** - * Event fired when a public message is broadcasted. - * @event publicMessage - * @param {JSON|String} data Data to be sent over. Data is based on - * what the user has set. - * @param {String} senderPeerId Sender - * @param {Boolean} isSelf Check if message is sent to self + * Fired when a datachannel has a blob data send request. + * @event Datachannel: WRQ + * @param {String} userAgent The user's browser agent. + * @param {String} name The blob data name. + * @param {Integer} size The blob data size. + * @param {Integer} chunkSize The expected chunk size. + * @param {Integer} timeout The timeout in seconds. + * @private + * @since 0.4.0 + */ + 'WRQ': [], + /** + * Fired when a datachannel has a blob data send request acknowledgement. + * - 0: User accepts the request. + * - -1: User rejects the request. + * - Above 0: User acknowledges the blob data packet. + * @event Datachannel: ACK + * @param {Integer} ackN The acknowledge number. + * @param {Integer} userAgent The user's browser agent. + * @private + * @since 0.4.0 + */ + 'ACK': [], + /** + * Fired when a datachannel transfer has an error occurred. + * @event Datachannel: ERROR + * @param {String} message The error message. + * @param {Boolean} isSender If user's the uploader. + * @private + * @since 0.4.0 + */ + 'ERROR': [], + /** + * Fired when a datachannel chat has been received. + * @event Datachannel: CHAT + * @param {String} type If the message is a private or group message. + * - PRIVATE: This message is a private message targeted to a peer. + * - GROUP: This message is to be sent to all peers. + * @param {String} peerId PeerId of the sender. + * @param {JSON|String} message The message data or object. + * @private + * @since 0.4.0 */ - 'publicMessage': [] + 'CHAT': [] }; /** - * Send a chat message - * @method sendChatMessage - * @param {String} message - * @param {String} targetPeerId Optional. Specified when peer wants to - * send a private chat message to the targeted peer. + * Broadcast a message to all peers. + * - <b><i>WARNING</i></b>: Map arrays data would be lost when stringified + * in JSON, so refrain from using map arrays. + * @method sendMessage + * @param {String|JSON} message The message data to send. + * @param {String} targetPeerId PeerId of the peer to send a private + * message data to. * @example * // Example 1: Send to all peers - * SkywayDemo.sendChatMessage('Hi there!'); + * SkywayDemo.sendMessage('Hi there!'); * - * // Example 2: Send to specific peer - * SkywayDemo.sendChatMessage('Hi there peer!', targetPeerId) - * @trigger chatMessageReceived + * // Example 2: Send to a targeted peer + * SkywayDemo.sendMessage('Hi there peer!', targetPeerId); + * @trigger incomingMessage + * @since 0.4.0 */ - Skyway.prototype.sendChatMessage = function(message, targetPeerId) { - var message_json = { + Skyway.prototype.sendMessage = function(message, targetPeerId) { + var params = { cid: this._key, data: message, mid: this._user.sid, - sender: this._user.sid, rid: this._room.id, - type: this.SIG_TYPE.CHAT + type: this.SIG_TYPE.PUBLIC_MESSAGE }; if (targetPeerId) { - message_json.target = targetPeerId; + params.target = targetPeerId; + params.type = this.SIG_TYPE.PRIVATE_MESSAGE; } - this._sendMessage(message_json); - this._trigger('chatMessageReceived', message, this._user.sid, !!targetPeerId, true); + this._sendMessage(params); + this._trigger('incomingMessage', { + content: message, + isPrivate: (targetPeerId) ? true: false, + targetPeerId: targetPeerId || null, + isDataChannel: false, + senderPeerId: this._user.sid + }, this._user.sid, true); }; /** - * Send a chat message via DataChannel - * @method sendDataChannelChatMessage - * @param {String} message - * @param {String} targetPeerId Optional. Specified when peer wants to - * send a private chat message to the targeted peer. + * Broadcasts to all P2P datachannel messages and broadcasts to a + * peer only when targetPeerId is provided. + * - This is ideal for sending strings or json objects lesser than 40KB. + * For huge data, please check out + * {{#crossLink "Skyway/sendBlobData:method"}}sendBlobData(){{/crossLink}}. + * - <b><i>WARNING</i></b>: Map arrays data would be lost when stringified + * in JSON, so refrain from using map arrays. + * @method sendP2PMessage + * @param {String|JSON} message The message data to send. + * @param {String} targetPeerId Optional. Provide if you want to send to + * only one peer * @example * // Example 1: Send to all peers - * SkywayDemo.sendDataChannelChatMessage('Hi there!'); + * SkywayDemo.sendP2PMessage('Hi there! This is from a DataChannel!'); * * // Example 2: Send to specific peer - * SkywayDemo.sendDataChannelChatMessage('Hi there peer!', targetPeerId) - * @trigger chatMessageReceived + * SkywayDemo.sendP2PMessage('Hi there peer! This is from a DataChannel!', targetPeerId); + * @trigger incomingMessage + * @since 0.4.0 */ - Skyway.prototype.sendDataChannelChatMessage = function(message, targetPeerId) { - var message_json = { - cid: this._key, - data: message, - mid: this._user.sid, - sender: this._user.sid, - rid: this._room.id, - type: this.SIG_TYPE.CHAT - }; - if (targetPeerId) { - message_json.target = targetPeerId; - } - if (targetPeerId) { - if (this._dataChannels.hasOwnProperty(targetPeerId)) { - this._sendDataChannel(targetpeerId, ['CHAT', 'PRIVATE', this._user.sid, message]); - } - } else { - for (var peerId in this._dataChannels) { - if (this._dataChannels.hasOwnProperty(peerId)) { - this._sendDataChannel(peerId, ['CHAT', 'GROUP', this._user.sid, message]); + Skyway.prototype.sendP2PMessage = function(message, targetPeerId) { + // Handle typeof object sent over + for (var peerId in this._dataChannels) { + if (this._dataChannels.hasOwnProperty(peerId)) { + if ((targetPeerId && targetPeerId === peerId) || !targetPeerId) { + this._sendDataChannel(peerId, ['CHAT', ((targetPeerId) ? + 'PRIVATE' : 'GROUP'), this._user.sid, + ((typeof message === 'object') ? JSON.stringify(message) : + message)]); } } } - this._trigger('chatMessage', message, this._user.sid, !!targetPeerId); - }; - - /** - * Broadcasts a private message - * @method sendPrivateMessage - * @param {String|JSON} data - * @param {String} targetPeerId - * @example - * // Example 1: Send JSON - * SkywayDemo.sendPrivateMessage({ - * item1: data1, - * item2: data2 - * }, targetPeerId); - * - * // Example 2: Send a String - * SkywayDemo.sendPrivateMessage(data1 + '-' + data2, targetPeerId); - * @trigger privateMessage - * @beta - */ - Skyway.prototype.sendPrivateMessage = function(data, targetPeerId) { - var message_json = { - cid: this._key, - data: data, - mid: this._user.sid, - rid: this._room.id, - sender: this._user.sid, - target: ((targetpeerId) ? targetPeerId : this._user.sid), - type: this.SIG_TYPE.PRIVATE_MESSAGE - }; - this._sendMessage(message_json); - this._trigger('privateMessage', data, this._user.sid, targetPeerId, true); - }; - - /** - * Broadcasts a public broadcast message - * @method sendPublicMessage - * @param {String|JSON} data - * @example - * // Example 1: Send JSON - * SkywayDemo.sendPublicMessage({ - * item1: data1, - * item2: data2 - * }); - * - * // Example 2: Send a String - * SkywayDemo.sendPublicMessage(data1 + '-' + data2); - * @trigger publicMessage - * @beta - */ - Skyway.prototype.sendPublicMessage = function(data) { - var message_json = { - cid: this._key, - data: data, - mid: this._user.sid, - sender: this._user.sid, - rid: this._room.id, - type: this.SIG_TYPE.PUBLIC_MESSAGE - }; - this._sendMessage(message_json); - this._trigger('publicMessage', data, this._user.sid, true); + this._trigger('incomingMessage', { + content: message, + isPrivate: (targetPeerId) ? true : false, + targetPeerId: targetPeerId || null, // is not null if there's user + isDataChannel: true, + senderPeerId: this._user.sid + }, this._user.sid, true); }; /** - * Get the default cam and microphone + * Get the default webcam and microphone * @method getUserMedia * @param {JSON} options Optional. Media constraints. * @param {JSON|Boolean} options.audio @@ -1600,7 +1820,7 @@

    File: source\skyway.js

    * @param {Integer} options.video.frameRate Mininum frameRate of Video * @example * // Default is to get both audio and video - * // Example 1: Get the default stream. + * // Example 1: Get both audio and video by default. * SkywayDemo.getUserMedia(); * * // Example 2: Get the audio stream only @@ -1612,39 +1832,71 @@

    File: source\skyway.js

    * // Example 3: Set the stream settings for the audio and video * SkywayDemo.getUserMedia({ * 'video' : { - * resolution: SkywayDemo.VIDEO_RESOLUTION.HD, - * frameRate: 50 + * 'resolution': SkywayDemo.VIDEO_RESOLUTION.HD, + * 'frameRate': 50 * }, * 'audio' : { stereo: true } * }); * @trigger mediaAccessSuccess, mediaAccessError + * @since 0.4.0 */ Skyway.prototype.getUserMedia = function(options) { var self = this; - // So it would invoke to getMediaStream defaults - options.audio = (options.audio) ? options.audio : typeof options.audio !== 'boolean'; - options.video = (options.video) ? options.video : typeof options.video !== 'boolean'; - self._parseStreamSettings(options); - if (!options.video && !options.audio) { - console.error('API - No streams requested. Request an audio/video or both.'); - return; + var getStream = false; + options = options || { + audio: true, + video: true + }; + // prevent undefined error + self._user = self._user || {}; + self._user.info = self._user.info || {}; + self._user.info.settings = self._user.info.settings || {}; + self._user.streams = self._user.streams || []; + // called during joinRoom + if (self._user.info.settings) { + // So it would invoke to getMediaStream defaults + if (!options.video && !options.audio) { + console.warn('API - No streams requested. Request an audio/video or both.'); + } else if (self._user.info.settings.audio !== options.audio || + self._user.info.settings.video !== options.video) { + if (Object.keys(self._user.streams).length > 0) { + // NOTE: User's stream may hang.. so find a better way? + // NOTE: Also make a use case for multiple streams? + getStream = self._setStreams(options); + if (getStream) { + // NOTE: When multiple streams, streams should not be cleared. + self._user.streams = []; + } + } else { + getStream = true; + } + } + } else { // called before joinRoom + getStream = true; } - try { - window.getUserMedia({ - audio: self._streamSettings.audio, - video: self._streamSettings.video - }, function(stream) { - self._onUserMediaSuccess(stream, self); - }, function(error) { - self._onUserMediaError(error, self); - }); - console.log('API [MediaStream] - Requested ' + - ((self._streamSettings.audio) ? 'A' : '') + - ((self._streamSettings.audio && - self._streamSettings.video) ? '/' : '') + - ((self._streamSettings.video) ? 'V' : '')); - } catch (error) { - this._onUserMediaError(error, self); + self._parseStreamSettings(options); + if (getStream) { + try { + window.getUserMedia({ + audio: self._streamSettings.audio, + video: self._streamSettings.video + }, function(stream) { + self._onUserMediaSuccess(stream, self); + }, function(error) { + self._onUserMediaError(error, self); + }); + console.log('API [MediaStream] - Requested ' + + ((self._streamSettings.audio) ? 'A' : '') + + ((self._streamSettings.audio && + self._streamSettings.video) ? '/' : '') + + ((self._streamSettings.video) ? 'V' : '')); + } catch (error) { + this._onUserMediaError(error, self); + } + } else if (Object.keys(self._user.streams).length > 0) { + console.warn('API - User already has stream. Reactiving stream only.'); + } else { + console.warn('API - Not retrieving stream.'); } }; @@ -1655,6 +1907,7 @@

    File: source\skyway.js

    * @param {Skyway} self A convenience pointer to the Skyway object for callbacks * @trigger mediaAccessSuccess * @private + * @since 0.3.0 */ Skyway.prototype._onUserMediaSuccess = function(stream, self) { console.log('API - User has granted access to local media.'); @@ -1664,7 +1917,12 @@

    File: source\skyway.js

    clearInterval(checkReadyState); self._user.streams[stream.id] = stream; self._user.streams[stream.id].active = true; - self._trigger('addPeerStream', self._user.sid, stream, true); + var checkIfUserInRoom = setInterval(function () { + if (self._in_room) { + clearInterval(checkIfUserInRoom); + self._trigger('incomingStream', self._user.sid, stream, true); + } + }, 500); } }, 500); }; @@ -1676,6 +1934,7 @@

    File: source\skyway.js

    * @param {Skyway} self A convenience pointer to the Skyway object for callbacks * @trigger mediaAccessFailure * @private + * @since 0.1.0 */ Skyway.prototype._onUserMediaError = function(e, self) { console.log('API - getUserMedia failed with exception type: ' + e.name); @@ -1691,15 +1950,17 @@

    File: source\skyway.js

    /** * Handle every incoming message. If it's a bundle, extract single messages - * Eventually handle the message(s) to - * {{#crossLink "Skyway/_processSingleMessage:method"}}_processSingleMessage(){{/crossLink}} + * - Eventually handle the message(s) to + * {{#crossLink "Skyway/_processSingleMessage:method"}} + * _processSingleMessage(){{/crossLink}} * @method _processSigMessage - * @param {JSON} messageString + * @param {String} messageString * @private + * @since 0.1.0 */ Skyway.prototype._processSigMessage = function(messageString) { var message = JSON.parse(messageString); - if (message.type === 'group') { + if (message.type === this.SIG_TYPE.GROUP) { console.log('API - Bundle of ' + message.lists.length + ' messages.'); for (var i = 0; i < message.lists.length; i++) { this._processSingleMessage(message.lists[i]); @@ -1714,6 +1975,7 @@

    File: source\skyway.js

    * @method _processingSingleMessage * @param {JSON} message * @private + * @since 0.1.0 */ Skyway.prototype._processSingleMessage = function(message) { this._trigger('channelMessage', message); @@ -1724,8 +1986,7 @@

    File: source\skyway.js

    console.log('API - [' + origin + '] Incoming message: ' + message.type); if (message.mid === this._user.sid && message.type !== this.SIG_TYPE.REDIRECT && - message.type !== this.SIG_TYPE.IN_ROOM && - message.type !== this.SIG_TYPE.CHAT) { + message.type !== this.SIG_TYPE.IN_ROOM) { console.log('API - Ignoring message: ' + message.type + '.'); return; } @@ -1758,9 +2019,6 @@

    File: source\skyway.js

    case this.SIG_TYPE.BYE: this._byeHandler(message); break; - case this.SIG_TYPE.CHAT: - this._chatHandler(message); - break; case this.SIG_TYPE.REDIRECT: this._redirectHandler(message); break; @@ -1780,42 +2038,22 @@

    File: source\skyway.js

    case this.SIG_TYPE.ROOM_LOCK: this._roomLockEventHandler(message); break; - case this.SIG_TYPE.INVITE: - // this._inviteHandler(); - break; default: console.log('API - [' + message.mid + '] Unsupported message type received: ' + message.type); break; } }; - /** - * Throw an event with the received chat message - * @method _chatHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.target targetPeerId. For private message - * @param {String} message.data Chat message - * @param {String} message.sender senderPeerId - * @param {String} message.type Message type - * @trigger chatMessageReceived - * @private - */ - Skyway.prototype._chatHandler = function(message) { - this._trigger('chatMessageReceived', message.data, - message.sender, (message.target ? true : false), false); - }; - /** * Signaling server error message * @method _errorHandler * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.kind Error type - * @param {String} message.type Message type + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the error message. + * @param {String} message.kind The error kind. + * @param {String} message.type The type of message received. * @private + * @since 0.1.0 */ Skyway.prototype._errorHandler = function(message) { console.log('API - [Server] Error occurred: ' + message.kind); @@ -1825,16 +2063,16 @@

    File: source\skyway.js

    /** * Signaling server wants us to move out. * @method _redirectHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.url Deprecated. Url to redirect to - * @param {String} message.info Reason for redirect - * @param {String} message.action Action of the redirect + * @param {JSON} message The message object. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.url Deprecated. Url to redirect to. + * @param {String} message.info The reason for redirect + * @param {String} message.action The action of the redirect * [Rel: Skyway.SYSTEM_ACTION] - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger systemAction * @private + * @since 0.1.0 */ Skyway.prototype._redirectHandler = function(message) { console.log('API - [Server] You are being redirected: ' + message.info); @@ -1842,20 +2080,21 @@

    File: source\skyway.js

    }; /** - * User Information is updated + * User information is updated. * @method _updateUserEventHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.userData The Skyway._user.info.userData data. - * @param {String} message.type Message type + * @param {JSON} message The message object. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the + * updated event. + * @param {String} message.userData The peer's user data. + * @param {String} message.type The type of message received. * @trigger peerUpdated * @private + * @since 0.2.0 */ Skyway.prototype._updateUserEventHandler = function(message) { var targetMid = message.mid; console.log('API - [' + targetMid + '] received \'updateUserEvent\'.'); - console.info(message); if (this._peerInformations[targetMid]) { this._peerInformations[targetMid].userData = message.userData || {}; this._trigger('peerUpdated', targetMid, @@ -1864,32 +2103,37 @@

    File: source\skyway.js

    }; /** - * Room Lock is Fired + * Room lock status is changed. * @method _roomLockEventHandler * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the + * updated room lock status. * @param {String} message.lock If room is locked or not - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger roomLock * @private + * @since 0.2.0 */ Skyway.prototype._roomLockEventHandler = function(message) { var targetMid = message.mid; console.log('API - [' + targetMid + '] received \'roomLockEvent\'.'); - this._trigger('roomLock', true, message.lock); + this._trigger('roomLock', message.lock, targetMid, + this._peerInformations[targetMid], false); }; /** - * Peer Audio is muted/unmuted + * Peer Audio is muted/unmuted. * @method _muteAudioEventHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending + * their own updated audio stream status. * @param {String} message.muted If audio stream is muted or not - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger peerUpdated * @private + * @since 0.2.0 */ Skyway.prototype._muteAudioEventHandler = function(message) { var targetMid = message.mid; @@ -1902,15 +2146,17 @@

    File: source\skyway.js

    }; /** - * Peer Video is muted/unmuted + * Peer Video is muted/unmuted. * @method _muteVideoEventHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending + * their own updated video streams status. * @param {String} message.muted If video stream is muted or not - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger peerUpdated * @private + * @since 0.2.0 */ Skyway.prototype._muteVideoEventHandler = function(message) { var targetMid = message.mid; @@ -1925,12 +2171,13 @@

    File: source\skyway.js

    /** * A peer left, let's clean the corresponding connection, and trigger an event. * @method _byeHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.type Message type + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that has left the room. + * @param {String} message.type The type of message received. * @trigger peerLeft * @private + * @since 0.1.0 */ Skyway.prototype._byeHandler = function(message) { var targetMid = message.mid; @@ -1941,66 +2188,84 @@

    File: source\skyway.js

    /** * Throw an event with the received private message * @method _privateMessageHandler - * @param {JSON} message - * @param {String} message.sender The senderPeerId. - * @param {JSON|String} message.data The Data broadcasted - * @param {String} message.nick Deprecated. Nickname of the user - * @param {String} message.mid TargetMid - * @param {String} message.cid The credentialId - * @param {String} message.rid RoomId - * @param {String} message.type Message type + * @param {JSON} message The message object received. + * @param {JSON|String} message.data The data broadcasted + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.cid CredentialId of the room + * @param {String} message.mid PeerId of the peer that is sending a private + * broadcast message + * @param {Boolean} message.isDataChannel Is the message sent from datachannel + * @param {String} message.type The type of message received. * @trigger privateMessage * @private + * @since 0.4.0 */ Skyway.prototype._privateMessageHandler = function(message) { - this._trigger('privateMessage', message.data, message.sender, message.target, false); + this._trigger('incomingMessage', { + content: message.data, + isPrivate: true, + targetPeerId: message.target, // is not null if there's user + isDataChannel: (message.isDataChannel) ? true : false, + senderPeerId: this._user.sid + }, this._user.sid, false); }; /** * Throw an event with the received private message * @method _publicMessageHandler - * @param {JSON} message - * @param {String} message.sender The senderPeerId. - * @param {JSON|String} message.data The Data broadcasted - * @param {String} message.nick Deprecated. Nickname of the user - * @param {String} message.mid TargetMid - * @param {String} message.cid The credentialId - * @param {String} message.rid RoomId - * @param {String} message.type Message type + * @param {JSON} message The message object received. + * @param {JSON|String} message.data The data broadcasted + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.cid CredentialId of the room + * @param {String} message.mid PeerId of the peer that is sending a private + * broadcast message + * @param {Boolean} message.isDataChannel Is the message sent from datachannel + * @param {String} message.type The type of message received. * @trigger publicMessage * @private + * @since 0.4.0 */ Skyway.prototype._publicMessageHandler = function(message) { - this._trigger('publicMessage', message.data, message.sender, false); + this._trigger('incomingMessage', { + content: message.data, + isPrivate: false, + targetPeerId: null, // is not null if there's user + isDataChannel: (message.isDataChannel) ? true : false, + senderPeerId: this._user.sid + }, this._user.sid, false); }; /** - * Actually clean the peerconnection and trigger an event. Can be called by _byHandler - * and leaveRoom. + * Actually clean the peerconnection and trigger an event. + * Can be called by _byHandler and leaveRoom. * @method _removePeer - * @param {String} peerId Id of the peer to remove + * @param {String} peerId PeerId of the peer that has left. * @trigger peerLeft * @private + * @since 0.1.0 */ Skyway.prototype._removePeer = function(peerId) { - this._trigger('peerLeft', peerId, false); + this._trigger('peerLeft', peerId, this._peerInformations[peerId], false); if (this._peerConnections[peerId]) { this._peerConnections[peerId].close(); } delete this._peerConnections[peerId]; + delete this._peerInformations[peerId]; }; /** * We just joined a room! Let's send a nice message to all to let them know I'm in. * @method _inRoomHandler - * @param {JSON} message - * @param {JSON} message.pc_config The PeerConnection configuration - * @param {String} message.sid Self peerId. - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.type Message type + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.sid PeerId of self. + * @param {String} message.mid PeerId of the peer that is + * @param {JSON} message.pc_config The peerconnection configuration + * sending the joinRoom message. + * @param {String} message.type The type of message received. * @trigger peerJoined * @private + * @since 0.1.0 */ Skyway.prototype._inRoomHandler = function(message) { var self = this; @@ -2025,7 +2290,6 @@

    File: source\skyway.js

    version: window.webrtcDetectedBrowser.version, userInfo: self._user.info }; - console.info(params); console.log('API - Sending enter.'); self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ENTER, self._user.sid); self._sendMessage(params); @@ -2035,13 +2299,13 @@

    File: source\skyway.js

    * Someone just entered the room. If we don't have a connection with him/her, * send him a welcome. Handshake step 2 and 3. * @method _enterHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.agent Browser agent - * @param {String} message.version Browser version - * @param {String} message.userInfo Peer Skyway._user.info data. - * @param {JSON} message.userInfo.settings Peer stream settings + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the enter shake. + * @param {String} message.agent Peer's browser agent. + * @param {String} message.version Peer's browser version. + * @param {String} message.userInfo Peer's user information. + * @param {JSON} message.userInfo.settings Peer's stream settings * @param {Boolean|JSON} message.userInfo.settings.audio * @param {Boolean} message.userInfo.settings.audio.stereo * @param {Boolean|JSON} message.userInfo.settings.video @@ -2050,18 +2314,20 @@

    File: source\skyway.js

    * @param {Integer} message.userInfo.settings.video.resolution.height * @param {Integer} message.userInfo.settings.video.frameRate * @param {JSON} message.userInfo.mediaStatus Peer stream status. - * @param {Boolean} message.userInfo.mediaStatus.audioMuted If Peer's Audio stream is muted. - * @param {Boolean} message.userInfo.mediaStatus.videoMuted If Peer's Video stream is muted. + * @param {Boolean} message.userInfo.mediaStatus.audioMuted If peer's audio stream is muted. + * @param {Boolean} message.userInfo.mediaStatus.videoMuted If peer's video stream is muted. * @param {String|JSON} message.userInfo.userData Peer custom data * @param {String} message.type Message type - * @trigger handshakeProgress + * @trigger handshakeProgress, peerJoined * @private + * @since 0.1.0 */ Skyway.prototype._enterHandler = function(message) { var self = this; var targetMid = message.mid; // need to check entered user is new or not. - if (!self._peerConnections[targetMid]) { + if (!self._peerConnections[targetMid] && !self._peerInformations[targetMid] && + targetMid !== self._user.sid) { message.agent = (!message.agent) ? 'Chrome' : message.agent; var browserAgent = message.agent + ((message.version) ? ('|' + message.version) : ''); // should we resend the enter so we can be the offerer? @@ -2074,7 +2340,7 @@

    File: source\skyway.js

    agent: window.webrtcDetectedBrowser.browser, userInfo: self._user.info }; - console.info(params); + console.info(JSON.stringify(params)); if (!beOfferer) { console.log('API - [' + targetMid + '] Sending welcome.'); self._peerInformations[targetMid] = message.userInfo; @@ -2088,7 +2354,7 @@

    File: source\skyway.js

    // NOTE ALEX: and if we already have a connection when the peer enter, // what should we do? what are the possible use case? console.log('API - Received "enter" when Peer "' + targetMid + - '" is already added'); + '" is already added.'); return; } }; @@ -2097,9 +2363,9 @@

    File: source\skyway.js

    * We have just received a welcome. If there is no existing connection with this peer, * create one, then set the remotedescription and answer. * @method _welcomeHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the welcome shake. * @param {String} message.target targetPeerId * @param {Boolean} message.receiveOnly Peer to receive only * @param {Boolean} message.enableIceTrickle Option to enable Ice trickle or not @@ -2119,21 +2385,33 @@

    File: source\skyway.js

    * @param {String|JSON} message.userInfo.userData Peer custom data * @param {String} message.agent Browser agent * @param {String} message.type Message type - * @trigger handshakeProgress + * @trigger handshakeProgress, peerJoined * @private + * @since 0.1.0 */ Skyway.prototype._welcomeHandler = function(message) { var targetMid = message.mid; - message.agent = (!message.agent) ? 'Chrome' : message.agent; - this._trigger('handshakeProgress', this.HANDSHAKE_PROGRESS.WELCOME, targetMid); - this._peerInformations[targetMid] = message.userInfo; - this._trigger('peerJoined', targetMid, message.userInfo, false); - this._enableIceTrickle = (typeof message.enableIceTrickle === 'boolean') ? - message.enableIceTrickle : this._enableIceTrickle; - this._enableDataChannel = (typeof message.enableDataChannel === 'boolean') ? - message.enableDataChannel : this._enableDataChannel; - if (!this._peerConnections[targetMid]) { + // Prevent duplicates and receiving own peer + if (!this._peerInformations[targetMid] && !this._peerInformations[targetMid] && + targetMid !== this._user.sid) { + message.agent = (!message.agent) ? 'Chrome' : message.agent; + this._trigger('handshakeProgress', this.HANDSHAKE_PROGRESS.WELCOME, targetMid); + this._peerInformations[targetMid] = message.userInfo; + this._trigger('peerJoined', targetMid, message.userInfo, false); + this._enableIceTrickle = (typeof message.enableIceTrickle === 'boolean') ? + message.enableIceTrickle : this._enableIceTrickle; + this._enableDataChannel = (typeof message.enableDataChannel === 'boolean') ? + message.enableDataChannel : this._enableDataChannel; this._openPeer(targetMid, message.agent, true, message.receiveOnly); + } else { + console.log('API - Not creating offer because user is' + + ' connected to peer already.'); + console.error('API [' + targetMid + '] - Peer connectivity issue.' + + ' Refreshing connection'); + this.leaveRoom(); + // set timeout to 500 ? + this.joinRoom(); + return; } }; @@ -2141,14 +2419,14 @@

    File: source\skyway.js

    * We have just received an offer. If there is no existing connection with this peer, * create one, then set the remotedescription and answer. * @method _offerHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.target targetPeerId + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the offer shake. * @param {String} message.sdp Offer sessionDescription - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger handshakeProgress * @private + * @since 0.1.0 */ Skyway.prototype._offerHandler = function(message) { var self = this; @@ -2176,8 +2454,9 @@

    File: source\skyway.js

    * We have succesfully received an offer and set it locally. This function will take care * of cerating and sendng the corresponding answer. Handshake step 4. * @method _doAnswer - * @param {String} targetMid The peer we should connect to. + * @param {String} targetMid PeerId of the peer to send answer to. * @private + * @since 0.1.0 */ Skyway.prototype._doAnswer = function(targetMid) { var self = this; @@ -2203,11 +2482,12 @@

    File: source\skyway.js

    * We have a peer, this creates a peerconnection object to handle the call. * if we are the initiator, we then starts the O/A handshake. * @method _openPeer - * @param {String} targetMid The peer we should connect to. - * @param {String} peerAgentBrowser The peer's browser + * @param {String} targetMid PeerId of the peer we should connect to. + * @param {String} peerAgentBrowser Peer's browser * @param {Boolean} toOffer Wether we should start the O/A or wait. * @param {Boolean} receiveOnly Should they only receive? * @private + * @since 0.1.0 */ Skyway.prototype._openPeer = function(targetMid, peerAgentBrowser, toOffer, receiveOnly) { var self = this; @@ -2235,8 +2515,9 @@

    File: source\skyway.js

    * Sends our Local MediaStream to other Peers. * By default, it sends all it's other stream * @method _addLocalStream - * @param {String} peerId + * @param {String} peerId PeerId of the peer to send local stream to. * @private + * @since 0.2.0 */ Skyway.prototype._addLocalStream = function(peerId) { // NOTE ALEX: here we could do something smarter @@ -2261,21 +2542,23 @@

    File: source\skyway.js

    * The remote peer advertised streams, that we are forwarding to the app. This is part * of the peerConnection's addRemoteDescription() API's callback. * @method _onRemoteStreamAdded - * @param {String} targetMid + * @param {String} targetMid PeerId of the peer that has remote stream to send. * @param {Event} event This is provided directly by the peerconnection API. - * @trigger addPeerStream + * @trigger incomingStream * @private + * @since 0.1.0 */ Skyway.prototype._onRemoteStreamAdded = function(targetMid, event) { console.log('API - [' + targetMid + '] Remote Stream added.'); - this._trigger('addPeerStream', targetMid, event.stream, false); + this._trigger('incomingStream', targetMid, event.stream, false); }; /** * It then sends it to the peer. Handshake step 3 (offer) or 4 (answer) * @method _doCall - * @param {String} targetMid + * @param {String} targetMid PeerId of the peer to send offer to. * @private + * @since 0.1.0 */ Skyway.prototype._doCall = function(targetMid, peerAgentBrowser) { var self = this; @@ -2302,13 +2585,15 @@

    File: source\skyway.js

    }; /** - * Find a line in the SDP and return it + * Finds a line in the SDP and returns it. + * - To set the value to the line, add an additional parameter to the method. * @method _findSDPLine - * @param {Array} sdpLines - * @param {Array} condition + * @param {Array} sdpLines Sdp received. + * @param {Array} condition The conditions. * @param {String} value Value to set Sdplines to * @return {Array} [index, line] - Returns the sdpLines based on the condition * @private + * @since 0.2.0 */ Skyway.prototype._findSDPLine = function(sdpLines, condition, value) { for (var index in sdpLines) { @@ -2327,11 +2612,13 @@

    File: source\skyway.js

    }; /** - * Add Stereo to SDP. Requires OPUS + * Adds stereo feature to the SDP. + * - This requires OPUS to be enabled in the SDP or it will not work. * @method _addStereo - * @param {Array} sdpLines + * @param {Array} sdpLines Sdp received. * @return {Array} Updated version with Stereo feature * @private + * @since 0.2.0 */ Skyway.prototype._addStereo = function(sdpLines) { var opusLineFound = false, @@ -2357,9 +2644,10 @@

    File: source\skyway.js

    /** * Set Audio, Video and Data Bitrate in SDP * @method _setSDPBitrate - * @param {Array} sdpLines + * @param {Array} sdpLines Sdp received. * @return {Array} Updated version with custom Bandwidth settings * @private + * @since 0.2.0 */ Skyway.prototype._setSDPBitrate = function(sdpLines) { // Find if user has audioStream @@ -2388,11 +2676,12 @@

    File: source\skyway.js

    * This takes an offer or an aswer generated locally and set it in the peerconnection * it then sends it to the peer. Handshake step 3 (offer) or 4 (answer) * @method _setLocalAndSendMessage - * @param {String} targetMid + * @param {String} targetMid PeerId of the peer to send offer/answer to. * @param {JSON} sessionDescription This should be provided by the peerconnection API. * User might 'tamper' with it, but then , the setLocal may fail. * @trigger handshakeProgress * @private + * @since 0.1.0 */ Skyway.prototype._setLocalAndSendMessage = function(targetMid, sessionDescription) { var self = this; @@ -2447,10 +2736,12 @@

    File: source\skyway.js

    }; /** - * This sets the STUN server specially for Firefox for ICE Connection + * Sets the STUN server specially for Firefox for ICE Connection. * @method _setFirefoxIceServers - * @param {JSON} config + * @param {JSON} config Ice configuration servers url object. + * @return {JSON} Updated configuration * @private + * @since 0.1.0 */ Skyway.prototype._setFirefoxIceServers = function(config) { if (window.webrtcDetectedBrowser.mozWebRTC) { @@ -2482,8 +2773,9 @@

    File: source\skyway.js

    }; /** - * Waits for MediaStream. Once the stream is loaded, callback is called - * If there's not a need for stream, callback is called + * Waits for MediaStream. + * - Once the stream is loaded, callback is called + * - If there's not a need for stream, callback is called * @method _waitForMediaStream * @param {Function} callback Callback after requested constraints are loaded. * @param {JSON} options Optional. Media Constraints. @@ -2500,101 +2792,45 @@

    File: source\skyway.js

    * @param {String} options.bandwidth.video Video Bandwidth * @param {String} options.bandwidth.data Data Bandwidth * @private + * @since 0.4.0 */ Skyway.prototype._waitForMediaStream = function(callback, options) { var self = this; - var getStream = function (doReinit) { - // Loop for stream - console.log('API - requireVideo: ' + options.video); - console.log('API - requireAudio: ' + options.audio); - if (doReinit) { - self.getUserMedia(options); - } else { - self._parseStreamSettings(options); - } + options = options || {}; + self.getUserMedia(options); + + console.log('API - requireVideo: ' + options.video); + console.log('API - requireAudio: ' + options.audio); + + if (options.video || options.audio) { var checkForStream = setInterval(function() { - if (options.video || options.audio) { - for (var stream in self._user.streams) { - if (self._user.streams.hasOwnProperty(stream)) { - var audioTracks = self._user.streams[stream].getAudioTracks(); - var videoTracks = self._user.streams[stream].getVideoTracks(); - if (((options.video) ? (videoTracks.length > 0) : true) && - ((options.audio) ? (audioTracks.length > 0) : true)) { - clearInterval(checkForStream); - callback(); - break; - } + for (var stream in self._user.streams) { + if (self._user.streams.hasOwnProperty(stream)) { + var audioTracks = self._user.streams[stream].getAudioTracks(); + var videoTracks = self._user.streams[stream].getVideoTracks(); + if (((options.video) ? (videoTracks.length > 0) : true) && + ((options.audio) ? (audioTracks.length > 0) : true)) { + clearInterval(checkForStream); + callback(); + break; } } - } else { - clearInterval(checkForStream); - callback(); } }, 2000); - }; - // Scenario 1: No options - if (!options) { - callback(); - console.log('Scenario 1'); - return; - // Scenario 2: Only bandwidth or user options } else { - // Set User - self._user.info = self._user.info || {}; - self._user.info.userData = options.user || self._user.info.userData; - // Bandwidth options only - if (!options.hasOwnProperty('video') && !options.hasOwnProperty('audio')) { - self._parseStreamSettings(options); - callback(); - console.log('Scenario 2'); - return; - } else { - if (options.hasOwnProperty('user')) { - delete options.user; - } - // If undefined, at least set to boolean - options.video = options.video || false; - options.audio = options.audio || false; - // Does user has settings? - if (!self._user.info.settings) { - getStream(true); - console.log('Scenario 3'); - } else { - console.info(self._user.info.settings.audio !== options.audio); - console.info(self._user.info.settings.video !== options.video); - console.info(self._user.info.settings.audio !== options.audio || - self._user.info.settings.video !== options.video); - - if (self._user.info.settings.audio !== options.audio || - self._user.info.settings.video !== options.video) { - if (Object.keys(self._user.streams).length > 0) { - // NOTE: User's stream may hang.. so find a better way? - var reinit = self._setStreams(options); - getStream(reinit); - console.log('Scenario 4'); - } else { - self._parseStreamSettings(options); - callback(); - console.log('Scenario 5'); - } - } else { - self._parseStreamSettings(options); - callback(); - console.log('Scenario 6'); - } - } - } + callback(); } }; /** - * Close/Open existing mediaStreams + * Opens or closes existing MediaStreams. * @method _setStreams * @param {JSON} options * @param {JSON} options.audio Enable audio or not * @param {JSON} options.video Enable video or not * @return {Boolean} Whether we should re-fetch mediaStreams or not * @private + * @since 0.3.0 */ Skyway.prototype._setStreams = function(options) { var hasAudioTracks = false, hasVideoTracks = false; @@ -2630,12 +2866,13 @@

    File: source\skyway.js

    }; /** - * Create a peerconnection to communicate with the peer whose ID is 'targetMid'. + * Creates a peerconnection to communicate with the peer whose ID is 'targetMid'. * All the peerconnection callbacks are set up here. This is a quite central piece. * @method _createPeerConnection * @param {String} targetMid * @return {Object} The created peer connection object. * @private + * @since 0.1.0 */ Skyway.prototype._createPeerConnection = function(targetMid) { var pc, self = this; @@ -2717,6 +2954,7 @@

    File: source\skyway.js

    * @param {Event} event This is provided directly by the peerconnection API. * @trigger candidateGenerationState * @private + * @since 0.1.0 */ Skyway.prototype._onIceCandidate = function(targetMid, event) { if (event.candidate) { @@ -2755,7 +2993,7 @@

    File: source\skyway.js

    }; /** - * Handling reception of a candidate. handshake done, connection ongoing. + * Handles the reception of a candidate. handshake done, connection ongoing. * @method _candidateHandler * @param {JSON} message * @param {String} message.rid RoomId @@ -2766,6 +3004,7 @@

    File: source\skyway.js

    * @param {String} message.label IceCandidate label * @param {String} message.type Message type * @private + * @since 0.1.0 */ Skyway.prototype._candidateHandler = function(message) { var targetMid = message.mid; @@ -2801,7 +3040,7 @@

    File: source\skyway.js

    }; /** - * Handling reception of an answer (to a previous offer). handshake step 4. + * Handles the reception of an answer (to a previous offer). handshake step 4. * @method _answerHandler * @param {JSON} message * @param {String} message.rid RoomId @@ -2811,6 +3050,7 @@

    File: source\skyway.js

    * @param {String} message.type Message type * @trigger handshakeProgress * @private + * @since 0.1.0 */ Skyway.prototype._answerHandler = function(message) { var self = this; @@ -2830,10 +3070,14 @@

    File: source\skyway.js

    }; /** - * Send a message to the signaling server + * Sends a message to the signaling server. + * - Not to be confused with method + * {{#crossLink "Skyway/sendMessage:method"}}sendMessage(){{/crossLink}} + * that broadcasts messages. This is for sending socket messages. * @method _sendMessage * @param {JSON} message * @private + * @since 0.1.0 */ Skyway.prototype._sendMessage = function(message) { if (!this._channel_open) { @@ -2846,10 +3090,11 @@

    File: source\skyway.js

    }; /** - * Initiate a Socket signaling connection. + * Initiate a socket signaling connection. * @method _openChannel * @trigger channelMessage, channelOpen, channelError, channelClose * @private + * @since 0.1.0 */ Skyway.prototype._openChannel = function() { var self = this; @@ -2894,9 +3139,10 @@

    File: source\skyway.js

    }; /** - * Close the Socket signaling connection. + * Closes the socket signaling connection. * @method _closeChannel * @private + * @since 0.1.0 */ Skyway.prototype._closeChannel = function() { if (!this._channel_open) { @@ -2910,11 +3156,12 @@

    File: source\skyway.js

    /** * Create a DataChannel. Only SCTPDataChannel support * @method _createDataChannel - * @param {String} peerId The peerId of which the dataChannel is connected to - * @param {Function} callback The callback which it returns the DataChannel object to - * @param {Object} dc The DataChannel object passed inside + * @param {String} peerId PeerId of the peer which the datachannel is connected to + * @param {Function} callback The callback fired when datachannel is created. + * @param {Object} dc The datachannel object received. * @trigger dataChannelState * @private + * @since 0.1.0 */ Skyway.prototype._createDataChannel = function(peerId, callback, dc) { var self = this; @@ -2959,11 +3206,14 @@

    File: source\skyway.js

    }; /** - * Check DataChannel ReadyState. If ready, it sends a 'CONN' + * Checks datachannel ready state. + * - If ready, it sends a + * {{#crossLink "Skyway/CONN:event"}}CONN{{/crossLink}}. * @method _checkDataChannelStatus - * @param {Object} dc DataChannel object + * @param {Object} dc The datachannel object. * @trigger dataChannelState * @private + * @since 0.1.0 */ Skyway.prototype._checkDataChannelStatus = function(dc) { var self = this; @@ -2980,11 +3230,12 @@

    File: source\skyway.js

    }; /** - * Sending of String Data over the DataChannels + * Sends data to the datachannel. * @method _sendDataChannel - * @param {String} peerId - * @param {JSON} data + * @param {String} peerId PeerId of the peer's datachannel to send data. + * @param {JSON} data The data to send. * @private + * @since 0.1.0 */ Skyway.prototype._sendDataChannel = function(peerId, data) { var dc = this._dataChannels[peerId]; @@ -3016,23 +3267,25 @@

    File: source\skyway.js

    }; /** - * To obtain the Peer that it's connected to from the DataChannel + * Obtains the peerId of the peer connected to the datachannel. * @method _dataChannelPeer - * @param {String} channel - * @param {Skyway} self + * @param {String} channel The datachannel name. + * @param {Skyway} self Skyway object. * @private * @deprecated + * @since 0.1.0 */ Skyway.prototype._dataChannelPeer = function(channel, self) { return self._dataChannelPeers[channel]; }; /** - * To obtain the Peer that it's connected to from the DataChannel + * Closes the datachannel. * @method _closeDataChannel - * @param {String} peerId - * @param {Skyway} self + * @param {String} peerId PeerId of the peer's datachannel to close. + * @param {Skyway} self Skyway object. * @private + * @since 0.1.0 */ Skyway.prototype._closeDataChannel = function(peerId, self) { var dc = self._dataChannels[peerId]; @@ -3046,10 +3299,11 @@

    File: source\skyway.js

    }; /** - * The Handler for all DataChannel Protocol events + * Handles all datachannel protocol events. * @method _dataChannelHandler - * @param {String} data + * @param {String|Object} data The data received from datachannel. * @private + * @since 0.1.0 */ Skyway.prototype._dataChannelHandler = function(dataString, peerId, self) { // PROTOCOL ESTABLISHMENT @@ -3058,33 +3312,26 @@

    File: source\skyway.js

    var data = dataString.split('|'); var state = data[0]; console.log('API - DataChannel [' + peerId + ']: Received ' + state); - switch (state) { case 'CONN': - // CONN - DataChannel Connection has been established self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.OPEN, peerId); break; case 'WRQ': - // WRQ - Send File Request Received. For receiver to accept or not self._dataChannelWRQHandler(peerId, data, self); break; case 'ACK': - // ACK - If accepted, send. Else abort self._dataChannelACKHandler(peerId, data, self); break; case 'ERROR': - // ERROR - Failure in receiving data. Could be timeout self._dataChannelERRORHandler(peerId, data, self); break; case 'CHAT': - // CHAT - DataChannel Chat self._dataChannelCHATHandler(peerId, data, self); break; default: console.error('API - DataChannel [' + peerId + ']: Invalid command'); } } else { - // DATA - BinaryString base64 received console.log('API - DataChannel [' + peerId + ']: Received "DATA"'); self._dataChannelDATAHandler(peerId, dataString, self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING, self); @@ -3093,15 +3340,15 @@

    File: source\skyway.js

    }; /** - * DataChannel TFTP Protocol Stage: WRQ - * The sender has sent a request to send file + * The user receives a blob request. * From here, it's up to the user to accept or reject it * @method _dataChannelWRQHandler - * @param {String} peerId - * @param {Array} data - * @param {Skyway} self + * @param {String} peerId PeerId of the peer that is sending the request. + * @param {Array} data The data object received from datachannel. + * @param {Skyway} self Skyway object. * @trigger dataTransferState * @private + * @since 0.4.0 */ Skyway.prototype._dataChannelWRQHandler = function(peerId, data, self) { var transferId = this._user.sid + this.DATA_TRANSFER_TYPE.DOWNLOAD + @@ -3110,42 +3357,60 @@

    File: source\skyway.js

    var binarySize = parseInt(data[3], 10); var expectedSize = parseInt(data[4], 10); var timeout = parseInt(data[5], 10); - var sendDataTransfer = confirm('Do you want to receive "' + name + '" ?'); - - if (sendDataTransfer) { - self._downloadDataTransfers[peerId] = []; - self._downloadDataSessions[peerId] = { - transferId: transferId, - name: name, - size: binarySize, - ackN: 0, - receivedSize: 0, - chunkSize: expectedSize, - timeout: timeout - }; - self._sendDataChannel(peerId, ['ACK', 0, window.webrtcDetectedBrowser.browser]); + self._downloadDataSessions[peerId] = { + transferId: transferId, + name: name, + size: binarySize, + ackN: 0, + receivedSize: 0, + chunkSize: expectedSize, + timeout: timeout + }; + var transferInfo = { + name: name, + size: binarySize, + senderPeerId: peerId + }; + self._trigger('dataTransferState', + self.DATA_TRANSFER_STATE.UPLOAD_REQUEST, transferId, peerId, transferInfo); + }; + + /** + * User's response to accept or reject file. + * @method respondBlobRequest + * @param {String} peerId PeerId of the peer that is expected to receive + * the request response. + * @param {Boolean} accept Accept the Blob download request or not. + * @trigger dataTransferState + * @since 0.4.0 + */ + Skyway.prototype.respondBlobRequest = function (peerId, accept) { + if (accept) { + this._downloadDataTransfers[peerId] = []; + var data = this._downloadDataSessions[peerId]; + this._sendDataChannel(peerId, ['ACK', 0, window.webrtcDetectedBrowser.browser]); var transferInfo = { - name: name, - size: binarySize, + name: data.name, + size: data.size, senderPeerId: peerId }; - this._trigger('dataTransferState', - this.DATA_TRANSFER_STATE.DOWNLOAD_STARTED, transferId, peerId, transferInfo); + this._trigger('dataTransferState', this.DATA_TRANSFER_STATE.DOWNLOAD_STARTED, + data.transferId, peerId, transferInfo); } else { - self._sendDataChannel(peerId, ['ACK', -1]); + this._sendDataChannel(peerId, ['ACK', -1]); + delete this._downloadDataSessions[peerId]; } }; /** - * DataChannel TFTP Protocol Stage: ACK - * The user sends a ACK of the request [accept/reject/nhe current - * index of chunk to be sent over] + * The user receives an acknowledge of the blob request. * @method _dataChannelACKHandler - * @param {String} peerId - * @param {Array} data - * @param {Skyway} self + * @param {String} peerId PeerId of the peer that is sending the acknowledgement. + * @param {Array} data The data object received from datachannel. + * @param {Skyway} self Skyway object. * @trigger dataTransferState * @private + * @since 0.1.0 */ Skyway.prototype._dataChannelACKHandler = function(peerId, data, self) { self._clearDataChannelTimeout(peerId, true, self); @@ -3193,54 +3458,62 @@

    File: source\skyway.js

    }; /** - * DataChannel TFTP Protocol Stage: CHAT - * The user receives a DataChannel CHAT message + * The user receives a datachannel broadcast message. * @method _dataChannelCHATHandler - * @param {String} peerId - * @param {Array} data - * @param {Skyway} self - * @trigger dataTransferState + * @param {String} peerId PeerId of the peer that is sending a broadcast message. + * @param {Array} data The data object received from datachannel. + * @param {Skyway} self Skyway object. + * @trigger incomingMessage * @private + * @since 0.4.0 */ Skyway.prototype._dataChannelCHATHandler = function(peerId, data) { - var messageChatType = this._stripNonAlphanumeric(data[1]); - var messageNick = this._stripNonAlphanumeric(data[2]); + var isPrivate = (this._stripNonAlphanumeric(data[1]) === 'PRIVATE') ? + true : false; + var senderPeerId = this._stripNonAlphanumeric(data[2]); + var params = { + cid: this._key, + mid: senderPeerId, + rid: this._room.id, + isDataChannel: true + }; // Get remaining parts as the message contents. // Get the index of the first char of chat content //var start = 3 + data.slice(0, 3).join('').length; - var messageChat = ''; + params.data = ''; // Add all char from start to the end of dataStr. // This method is to allow '|' to appear in the chat message. for (var i = 3; i < data.length; i++) { - messageChat += data[i]; + params.data += data[i]; } - console.log('API - Got DataChannel Chat Message: ' + messageChat + '.'); - console.log('API - Got a ' + messageChatType + ' chat message from ' + - peerId + ' (' + messageNick + ').'); - - // Create a message using event.data, message mid. - var message = { - type: this.SIG_TYPE.CHAT, - mid: peerId, - sender: peerId, - data: '[DC]: ' + messageChat - }; - // For private message, create a target field with our id. - if (messageChatType === 'PRIVATE') { - message.target = this._user.sid; + // Handle different type of data + try { + var result = JSON.parse(params.data); + params.data = result; + console.log('API - Received data is a JSON.'); + } catch (error) { + console.log('API - Received data is not a JSON.'); + } + if (isPrivate) { + params.target = this._user.sid; + params.type = this.SIG_TYPE.PRIVATE_MESSAGE; + } else { + params.target = this._user.sid; + params.type = this.SIG_TYPE.PUBLIC_MESSAGE; } - this._processSingleMessage(message); + // Create a message using event.data, message mid. + this._processSingleMessage(params); }; /** - * DataChannel TFTP Protocol Stage: ERROR - * The user received an error, usually an exceeded timeout. + * The user receives a timeout error. * @method _dataChannelERRORHandler - * @param {String} peerId - * @param {Array} data - * @param {Skyway} self + * @param {String} peerId PeerId of the peer that is sending the error. + * @param {Array} data The data object received from datachannel. + * @param {Skyway} self Skyway object. * @trigger dataTransferState * @private + * @since 0.1.0 */ Skyway.prototype._dataChannelERRORHandler = function(peerId, data, self) { var isUploader = data[2]; @@ -3257,15 +3530,16 @@

    File: source\skyway.js

    }; /** - * DataChannel TFTP Protocol Stage: DATA - * This is when the data is sent from the sender to the receiving user + * This is when the data is sent from the sender to the receiving user. * @method _dataChannelDATAHandler - * @param {String} peerId - * @param {ArrayBuffer|Blob|String} dataString - * @param {String} dataType [Rel: Skyway.DATA_TRANSFER_DATA_TYPE] - * @param {Skyway} self + * @param {String} peerId PeerId of the peer that is sending the data. + * @param {ArrayBuffer|Blob|String} dataString The data received. + * @param {String} dataType The data type received from datachannel. + * [Rel: Skyway.DATA_TRANSFER_DATA_TYPE] + * @param {Skyway} self Skyway object. * @trigger dataTransferState * @private + * @since 0.1.0 */ Skyway.prototype._dataChannelDATAHandler = function(peerId, dataString, dataType, self) { var chunk, transferInfo = {}; @@ -3334,13 +3608,15 @@

    File: source\skyway.js

    }; /** - * Set the DataChannel timeout. If exceeded, send the 'ERROR' message + * Sets the datachannel timeout. + * - If timeout is met, it will send the 'ERROR' message * @method _setDataChannelTimeout - * @param {String} peerId - * @param {Integer} timeout - * @param {Boolean} isSender - * @param {Skyway} self + * @param {String} peerId PeerId of the datachannel to set timeout. + * @param {Integer} timeout The timeout to set in seconds. + * @param {Boolean} isSender Is peer the sender or the receiver? + * @param {Skyway} self Skyway object. * @private + * @since 0.1.0 */ Skyway.prototype._setDataChannelTimeout = function(peerId, timeout, isSender, self) { if (!self._dataTransfersTimeout[peerId]) { @@ -3369,12 +3645,13 @@

    File: source\skyway.js

    }; /** - * Clear the DataChannel timeout as a response is received + * Clears the datachannel timeout. * @method _clearDataChannelTimeout - * @param {String} peerId - * @param {Boolean} isSender - * @param {Skyway} self + * @param {String} peerId PeerId of the datachannel to clear timeout. + * @param {Boolean} isSender Is peer the sender or the receiver? + * @param {Skyway} self Skyway object. * @private + * @since 0.1.0 */ Skyway.prototype._clearDataChannelTimeout = function(peerId, isSender, self) { if (self._dataTransfersTimeout[peerId]) { @@ -3386,14 +3663,15 @@

    File: source\skyway.js

    }; /** - * Convert base64 to raw binary data held in a string. - * Doesn't handle URLEncoded DataURIs - * - see StackOverflow answer #6850276 for code that does this + * Converts base64 string to raw binary data. + * - Doesn't handle URLEncoded DataURIs + * - See StackOverflow answer #6850276 for code that does this * This is to convert the base64 binary string to a blob * @author Code from devnull69 @ stackoverflow.com * @method _base64ToBlob - * @param {String} dataURL + * @param {String} dataURL Blob base64 dataurl. * @private + * @since 0.1.0 */ Skyway.prototype._base64ToBlob = function(dataURL) { var byteString = atob(dataURL.replace(/\s\r\n/g, '')); @@ -3408,12 +3686,12 @@

    File: source\skyway.js

    }; /** - * To chunk the File (which already is a blob) into smaller blob files. - * For now please send files below or around 2KB till chunking is implemented + * Chunks blob data into chunks. * @method _chunkFile - * @param {Blob} blob - * @param {Integer} blobByteSize + * @param {Blob} blob The blob data to chunk. + * @param {Integer} blobByteSize The blob data size. * @private + * @since 0.1.0 */ Skyway.prototype._chunkFile = function(blob, blobByteSize) { var chunksArray = [], @@ -3437,11 +3715,12 @@

    File: source\skyway.js

    }; /** - * Removes non-alphanumeric characters from a string and return it. + * Removes non-alphanumeric characters from a string. * @method _stripNonAlphanumeric * @param {String} input String to check. * @return {String} Updated string from non-alphanumeric characters * @private + * @since 0.2.0 */ Skyway.prototype._stripNonAlphanumeric = function(str) { var strOut = ''; @@ -3462,13 +3741,14 @@

    File: source\skyway.js

    }; /** - * Check if a text string consist of only alphanumeric characters. - * If so, return true. - * If not, return false. + * Check if a string consist of only alphanumeric characters. + * - If alphanumeric characters are found, it will return true, + * else it returns false. * @method _alphanumeric * @param {String} input String to check. * @return {Boolean} If string contains only alphanumeric characters. * @private + * @since 0.2.0 */ Skyway.prototype._alphanumeric = function(str) { var letterNumber = /^[0-9a-zA-Z]+$/; @@ -3479,17 +3759,21 @@

    File: source\skyway.js

    }; /** - * Method to send Blob data to peers. - * Peers have the option to download or reject the file. + * Sends blob data to peer(s). + * - Note that peers have the option to download or reject receiving the blob data. + * - This method is ideal for sending files. + * - To send a private file to a peer, input the peerId after the + * data information. * @method sendBlobData - * @param {Blob} data - The Blob data to be sent over - * @param {JSON} dataInfo - The Blob data information - * @param {String} dataInfo.name The Blob data name - * @param {Integer} dataInfo.timeout The timeout to wait for packets - * @param {Integer} dataInfo.size The Blob data size. Default is 60. - * @param {String} targetPeerId The specific peerId to send to. + * @param {Blob} data The blob data to be sent over. + * @param {JSON} dataInfo The data information. + * @param {String} dataInfo.transferId TransferId of the data. + * @param {String} dataInfo.name Data name. + * @param {Integer} dataInfo.timeout Data timeout to wait for packets. + * [Default is 60]. + * @param {Integer} dataInfo.size Data size + * @param {String} targetPeerId PeerId targeted to receive data. * Leave blank to send to all peers. - * @bubbles dataTransferState * @example * // Send file to all peers connected * SkywayDemo.sendBlobData(file, { @@ -3505,6 +3789,7 @@

    File: source\skyway.js

    * 'timeout' : 87 * }, targetPeerId); * @trigger dataTransferState + * @since 0.1.0 */ Skyway.prototype.sendBlobData = function(data, dataInfo, targetPeerId) { if (!data && !dataInfo) { @@ -3541,6 +3826,7 @@

    File: source\skyway.js

    senderPeerId: this._user.sid, name: dataInfo.name, size: dataInfo.size, + timeout: dataInfo.timeout || 60, data: URL.createObjectURL(data) }; this._trigger('dataTransferState', @@ -3559,18 +3845,21 @@

    File: source\skyway.js

    }; /** - * Method to send Blob data to individual peer. - * This sends the 'WRQ' and initiate the TFTP protocol. + * Sends blob data to individual peer. + * - This sends the {{#crossLink "Skyway/WRQ:event"}}WRQ{{/crossLink}} + * and to initiate the TFTP protocol. * @method _sendBlobDataToPeer - * @param {Blob} data - The Blob data to be sent over - * @param {JSON} dataInfo - The Blob data information - * @param {String} dataInfo.transferId The transfer Id - * @param {String} dataInfo.name The Blob data name - * @param {Integer} dataInfo.timeout The timeout to wait for packets. - * Default is 60. - * @param {Integer} dataInfo.size The Blob data size - * @param {String} targetPeerId + * @param {Blob} data The blob data to be sent over. + * @param {JSON} dataInfo The data information. + * @param {String} dataInfo.transferId TransferId of the data. + * @param {String} dataInfo.name Data name. + * @param {Integer} dataInfo.timeout Data timeout to wait for packets. + * [Default is 60]. + * @param {Integer} dataInfo.size Data size + * @param {String} targetPeerId PeerId targeted to receive data. + * Leave blank to send to all peers. * @private + * @since 0.1.0 */ Skyway.prototype._sendBlobDataToPeer = function(data, dataInfo, targetPeerId) { var binarySize = (dataInfo.size * (4 / 3)).toFixed(); @@ -3594,13 +3883,17 @@

    File: source\skyway.js

    }; /** - * Handle the Lock actions + * Handles all the room lock events. * @method _handleLock - * @param {String} lockAction [Rel: SkywayDemo.LOCK_ACTION] + * @param {String} lockAction Lock action to send to server for response. + * [Rel: SkywayDemo.LOCK_ACTION] + * @param {Function} callback The callback to return the response after + * everything's loaded. * @trigger roomLock * @private + * @since 0.4.0 */ - Skyway.prototype._handleLock = function(lockAction) { + Skyway.prototype._handleLock = function(lockAction, callback) { var self = this; var url = self._serverPath + '/rest/room/lock'; var params = { @@ -3615,12 +3908,15 @@

    File: source\skyway.js

    }; self._requestServerInfo('POST', url, function(status, response) { if (status !== 200) { - self._trigger('roomLock', false, null, 'Request failed!'); + console.error('API - Failed ' + lockAction + 'ing room.\nReason was:'); + console.error('XMLHttpRequest status not OK.\nStatus was: ' + status); return; } console.info(response); if (response.status) { - self._trigger('roomLock', true, response.content.lock); + self._room_lock = response.content.lock; + self._trigger('roomLock', response.content.lock, self._user.sid, + self._user.info, true); if (lockAction !== self.LOCK_ACTION.STATUS) { self._sendMessage({ type: self.SIG_TYPE.ROOM_LOCK, @@ -3630,203 +3926,234 @@

    File: source\skyway.js

    }); } } else { - self._trigger('roomLock', false, null, response.message); + console.error('API - Failed ' + lockAction + 'ing room.\nReason was:'); + console.error(response.message); } }, params); }; /** - * Restart the {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} - * process to initiate Audio and Video + * Handles all audio and video mute events. + * - If there is no available audio or video stream, it will call + * {{#crossLink "Skyway/leaveRoom:method"}}leaveRoom(){{/crossLink}} + * and call {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} + * to join user in the room to send their audio and video stream. * @method _handleAV - * @param {String} mediaType - * @param {Boolean} isEnabled - * @param {Boolean} hasMedia + * @param {String} mediaType Media types expected to receive. + * [Rel: 'audio' or 'video'] + * @param {Boolean} enableMedia Enable it or disable it * @trigger peerUpdated * @private + * @since 0.4.0 */ - Skyway.prototype._handleAV = function(mediaType, isEnabled, hasMedia) { + Skyway.prototype._handleAV = function(mediaType, enableMedia) { if (mediaType !== 'audio' && mediaType !== 'video') { return; + } else if (!this._in_room) { + console.error('API - User is not in the room. Cannot ' + + ((enableMedia) ? 'enable' : 'disable') + ' ' + mediaType); + return; } - this._sendMessage({ - type: ((mediaType === 'audio') ? this.SIG_TYPE.MUTE_AUDIO : - this.SIG_TYPE.MUTE_VIDEO), - mid: this._user.sid, - rid: this._room.id, - muted: !isEnabled - }); - if (hasMedia === false) { + // Loop and enable tracks accordingly + var hasTracks = false, isTracksActive = false; + for (var stream in this._user.streams) { + if (this._user.streams.hasOwnProperty(stream)) { + var tracks = (mediaType === 'audio') ? + this._user.streams[stream].getAudioTracks() : + this._user.streams[stream].getVideoTracks(); + for (var track in tracks) { + if (tracks.hasOwnProperty(track)) { + tracks[track].enabled = enableMedia; + hasTracks = true; + } + } + isTracksActive = this._user.streams[stream].active; + } + } + // Broadcast to other peers + if (!(hasTracks && isTracksActive) && enableMedia) { this.leaveRoom(); + var hasProperty = (this._user) ? ((this._user.info) ? ( + (this._user.info.settings) ? true : false) : false) : false; + // set timeout? to 500? this.joinRoom({ - audio: (mediaType === 'audio') ? true : this._streamSettings.audio, - video: (mediaType === 'video') ? true : this._streamSettings.video + audio: (mediaType === 'audio') ? true : ((hasProperty) ? + this._user.info.settings.audio : false), + video: (mediaType === 'video') ? true : ((hasProperty) ? + this._user.info.settings.video : false) + }); + } else { + this._sendMessage({ + type: ((mediaType === 'audio') ? this.SIG_TYPE.MUTE_AUDIO : + this.SIG_TYPE.MUTE_VIDEO), + mid: this._user.sid, + rid: this._room.id, + muted: !enableMedia }); } - if (this._in_room) { - this._user.info.mediaStatus[mediaType + 'Muted'] = !isEnabled; - this._trigger('peerUpdated', this._user.sid, this._user.info, true); - } + this._user.info.mediaStatus[mediaType + 'Muted'] = !enableMedia; + this._trigger('peerUpdated', this._user.sid, this._user.info, true); }; /** - * Lock the Room to prevent users from coming in + * Lock the room to prevent peers from joining. * @method lockRoom - * @bubbles lockRoom * @example * SkywayDemo.lockRoom(); * @trigger lockRoom - * @beta + * @since 0.2.0 */ Skyway.prototype.lockRoom = function() { this._handleLock(this.LOCK_ACTION.LOCK); }; /** - * Unlock the Room to allow users to come in + * Unlock the room to allow peers to join. * @method unlockRoom - * @bubbles lockRoom * @example * SkywayDemo.unlockRoom(); * @trigger lockRoom - * @beta + * @since 0.2.0 */ Skyway.prototype.unlockRoom = function() { this._handleLock(this.LOCK_ACTION.UNLOCK); }; /** - * Enable Microphone. If Microphone is not enabled from the - * beginning, user would have to reinitate the - * {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} - * process and ask for Microphone again. + * Get the lock status of the room. + * - <b><i>WARNING</i></b>: If there's too many peers toggling the + * room lock feature at the same time, the returned results may not + * be completely correct since while retrieving the room lock status, + * another peer may be toggling it. + * @method isRoomLocked + * @example + * if(SkywayDemo.isRoomLocked()) { + * SkywayDemo.unlockRoom(); + * } else { + * SkywayDemo.lockRoom(); + * } + * @beta + * @since 0.4.0 + */ + Skyway.prototype.isRoomLocked = function() { + this._handleLock(this.LOCK_ACTION.STATUS, function (lockAction) { + return lockAction; + }); + }; + + /** + * Enable microphone. + * - If microphone is not enabled from the beginning, user would have to reinitate the + * {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} + * process and ask for microphone again. * @method enableAudio * @trigger peerUpdated * @example * SkywayDemo.enableAudio(); + * @since 0.4.0 */ Skyway.prototype.enableAudio = function() { - var hasAudioTracks = false, audioTracksActive = false; - for (var stream in this._user.streams) { - if (this._user.streams.hasOwnProperty(stream)) { - var tracks = this._user.streams[stream].getAudioTracks(); - for (var track in tracks) { - if (tracks.hasOwnProperty(track)) { - tracks[track].enabled = true; - hasAudioTracks = true; - } - } - audioTracksActive = this._user.streams[stream].active; - } - } - this._handleAV('audio', true, (hasAudioTracks && audioTracksActive)); + this._handleAV('audio', true); }; /** - * Disable Microphone. If Microphone is not enabled from the - * beginning, there is no effect. + * Disable microphone. + * - If microphone is not enabled from the beginning, there is no effect. * @method disableAudio * @example * SkywayDemo.disableAudio(); * @trigger peerUpdated + * @since 0.4.0 */ Skyway.prototype.disableAudio = function() { - for (var stream in this._user.streams) { - if (this._user.streams.hasOwnProperty(stream)) { - var tracks = this._user.streams[stream].getAudioTracks(); - for (var track in tracks) { - if (tracks.hasOwnProperty(track)) { - tracks[track].enabled = false; - } - } - } - } this._handleAV('audio', false); }; /** - * Enable Webcam Video. If Webcam Video is not enabled from the - * beginning, user would have to reinitate the - * {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} - * process and ask for Webcam video again. + * Enable webcam video. + * - If webcam is not enabled from the beginning, user would have to reinitate the + * {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} + * process and ask for webcam again. * @method enableVideo * @example * SkywayDemo.enableVideo(); * @trigger peerUpdated + * @since 0.4.0 */ Skyway.prototype.enableVideo = function() { - var hasVideoTracks = false; - var videoTrackActive = false; - for (var stream in this._user.streams) { - if (this._user.streams.hasOwnProperty(stream)) { - var tracks = this._user.streams[stream].getVideoTracks(); - for (var track in tracks) { - if (tracks.hasOwnProperty(track)) { - tracks[track].enabled = true; - hasVideoTracks = true; - } - } - videoTracksActive = this._user.streams[stream].active; - } - } - this._handleAV('video', true, (videoTracksActive && hasVideoTracks)); + this._handleAV('video', true); }; /** - * Disable Webcam Video. If Webcam Video is not enabled from the - * beginning, there is no effect. + * Disable webcam video. + * - If webcam is not enabled from the beginning, there is no effect. * @method disableVideo * @example * SkywayDemo.disableVideo(); * @trigger peerUpdated + * @since 0.4.0 */ Skyway.prototype.disableVideo = function() { - for (var stream in this._user.streams) { - if (this._user.streams.hasOwnProperty(stream)) { - var tracks = this._user.streams[stream].getVideoTracks(); - for (var track in tracks) { - if (tracks.hasOwnProperty(track)) { - tracks[track].enabled = false; - } - } - } - } this._handleAV('video', false); }; /** - * Parse Stream settings + * Parse stream settings * @method _parseStreamSettings - * @param {JSON} options + * @param {JSON} options Optional. Media Constraints. + * @param {JSON} options.user Optional. User custom data. + * @param {Boolean|JSON} options.audio This call requires audio + * @param {Boolean} options.audio.stereo Enabled stereo or not + * @param {Boolean|JSON} options.video This call requires video + * @param {JSON} options.video.resolution [Rel: Skyway.VIDEO_RESOLUTION] + * @param {Integer} options.video.resolution.width Video width + * @param {Integer} options.video.resolution.height Video height + * @param {Integer} options.video.frameRate Mininum frameRate of Video + * @param {String} options.bandwidth Bandwidth settings + * @param {String} options.bandwidth.audio Audio Bandwidth + * @param {String} options.bandwidth.video Video Bandwidth + * @param {String} options.bandwidth.data Data Bandwidth * @private + * @since 0.4.0 */ Skyway.prototype._parseStreamSettings = function(options) { options = options || {}; + this._user.info = this._user.info || {}; + this._user.info.settings = this._user.info.settings || {}; + this._user.info.mediaStatus = this._user.info.mediaStatus || {}; + // Set User + this._user.info.userData = options.user || this._user.info.userData; // Set Bandwidth - console.info(JSON.stringify(options)); - console.info(JSON.stringify(this._user)); this._streamSettings.bandwidth = options.bandwidth || this._streamSettings.bandwidth || {}; - // Set user stream settings - this._user.info = this._user.info || {}; - this._user.info.settings = this._user.info.settings || {}; this._user.info.settings.bandwidth = options.bandwidth || this._user.info.settings.bandwidth || {}; + // Set audio settings this._user.info.settings.audio = (typeof options.audio === 'boolean' || typeof options.audio === 'object') ? options.audio : - (this._user.info.settings.audio || false); + (this._streamSettings.audio || false); + this._user.info.mediaStatus.audioMuted = (options.audio) ? + ((typeof this._user.info.mediaStatus.audioMuted === 'boolean') ? + this._user.info.mediaStatus.audioMuted : !options.audio) : true; + console.info(this._user.info.mediaStatus.audioMuted); + // Set video settings this._user.info.settings.video = (typeof options.video === 'boolean' || typeof options.video === 'object') ? options.video : - (this._user.info.settings.video || false); + (this._streamSettings.video || false); // Set user media status options - this._user.info.mediaStatus = this._user.info.mediaStatus || {}; - this._user.info.mediaStatus.audioMuted = (options.audio) ? - ((typeof this._user.info.mediaStatus.audioMuted === 'boolean') ? - this._user.info.mediaStatus.audioMuted : false) : true; - this._user.info.mediaStatus.audioMuted = (options.video) ? + this._user.info.mediaStatus.videoMuted = (options.video) ? ((typeof this._user.info.mediaStatus.videoMuted === 'boolean') ? - this._user.info.mediaStatus.videoMuted : false) : true; - console.info(JSON.stringify(this._user)); + this._user.info.mediaStatus.videoMuted : !options.video) : true; + + console.dir(this._user.info); + + if (!options.video && !options.audio) { + return; + } + // If undefined, at least set to boolean + options.video = options.video || false; + options.audio = options.audio || false; + // Set Video if (typeof options.video === 'object') { if (typeof options.video.resolution === 'object') { @@ -3842,9 +4169,7 @@

    File: source\skyway.js

    minWidth: width, minHeight: height }, - optional: [{ - minFrameRate: frameRate - }] + optional: [{ minFrameRate: frameRate }] }; } } @@ -3863,9 +4188,11 @@

    File: source\skyway.js

    /** * User to join the room. - * You may call {{#crossLink "Skyway/getUserMedia:method"}}getUserMedia(){{/crossLink}} - * first if you want to get - * MediaStream and joining Room seperately. + * - You may call {{#crossLink "Skyway/getUserMedia:method"}} + * getUserMedia(){{/crossLink}} first if you want to get + * MediaStream and joining Room seperately. + * - If <b>joinRoom()</b> parameters is empty, it simply uses + * any previous media or user data settings. * @method joinRoom * @param {String} room Room to join * @param {JSON} options Optional. Media Constraints. @@ -3878,17 +4205,20 @@

    File: source\skyway.js

    * @param {Integer} options.video.resolution.height Video height * @param {Integer} options.video.frameRate Mininum frameRate of Video * @param {String} options.bandwidth Bandwidth settings - * @param {String} options.bandwidth.audio Audio Bandwidth - * @param {String} options.bandwidth.video Video Bandwidth - * @param {String} options.bandwidth.data Data Bandwidth + * @param {Integer} options.bandwidth.audio Audio Bandwidth + * @param {Integer} options.bandwidth.video Video Bandwidth + * @param {Integer} options.bandwidth.data Data Bandwidth * @example * // To just join the default room without any video or audio + * // Note that calling joinRoom without any parameters + * // Still sends any available existing MediaStreams allowed. + * // See Examples 2, 3, 4 and 5 etc to prevent video or audio stream * SkywayDemo.joinRoom(); * * // To just join the default room with bandwidth settings * SkywayDemo.joinRoom({ - * bandwidth: { - * data: 14440 + * 'bandwidth': { + * 'data': 14440 * } * }); * @@ -3912,7 +4242,7 @@

    File: source\skyway.js

    * SkywayDemo.joinRoom('room', { * 'audio' : true, * 'video' : { - * 'res' : { + * 'resolution' : { * 'width' : 640, * 'height' : 320 * } @@ -3921,9 +4251,9 @@

    File: source\skyway.js

    * * // Example 5: Join a room with userData and settings with audio, video and bandwidth * SkwayDemo.joinRoom({ - * 'userData': { - * item1: 'My custom data', - * item2: 'Put whatever, string or JSON or array' + * 'user': { + * 'item1': 'My custom data', + * 'item2': 'Put whatever, string or JSON or array' * }, * 'audio' : { * 'stereo' : true @@ -3939,8 +4269,10 @@

    File: source\skyway.js

    * } * }); * @trigger peerJoined + * @since 0.2.0 */ Skyway.prototype.joinRoom = function(room, mediaOptions) { + console.info(mediaOptions); var self = this; if (self._in_room) { return; @@ -3976,9 +4308,9 @@

    File: source\skyway.js

    }, 500); }; if (typeof room === 'string') { - self._reinit(doJoinRoom, { + self._reinit({ room: room - }); + }, doJoinRoom); } else { mediaOptions = room; doJoinRoom(); @@ -3986,11 +4318,12 @@

    File: source\skyway.js

    }; /** - * User to leave the room + * User to leave the room. * @method leaveRoom * @example * SkywayDemo.leaveRoom(); * @trigger peerLeft, channelClose + * @since 0.1.0 */ Skyway.prototype.leaveRoom = function() { if (!this._in_room) { @@ -4003,7 +4336,7 @@

    File: source\skyway.js

    } this._in_room = false; this._closeChannel(); - this._trigger('peerLeft', this._user.sid, true); + this._trigger('peerLeft', this._user.sid, this._user.info, true); }; }).call(this); diff --git a/doc/index.html b/doc/index.html index 8f7810fed..d2cf8b45f 100644 --- a/doc/index.html +++ b/doc/index.html @@ -22,7 +22,7 @@

    - API Docs for: 0.3.1 + API Docs for: 0.4.0
    diff --git a/package.json b/package.json index 85644f849..6473c05d7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "skywayjs", "description": "WebRTC real-time video conversation library", - "version": "0.3.1", + "version": "0.4.0", "homepage": "https://www.temasys.com.sg/", "author": { "name": "Temasys Communications Pte. Ltd.", @@ -18,8 +18,8 @@ } ], "scripts": { - "test": "test.sh;", - "prestart": "./start.sh;" + "test": "./test.sh;", + "prestart": "./start.sh &" }, "dependencies": { "socket.io-client": "1.0.6", @@ -78,5 +78,5 @@ "npm": "1.4.6", "grunt": "0.4.1a" }, - "keywords": [] -} \ No newline at end of file + "keywords": ["webrtc", "real-time", "p2p"] +} diff --git a/publish/skyway.complete.js b/publish/skyway.complete.js index c3d0beed3..efe16343c 100644 --- a/publish/skyway.complete.js +++ b/publish/skyway.complete.js @@ -1,4 +1,4 @@ -/*! skywayjs - v0.3.1 - 2014-08-14 */ +/*! skywayjs - v0.4.0 - 2014-08-25 */ !function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.io=e():"undefined"!=typeof global?global.io=e():"undefined"!=typeof self&&(self.io=e())}(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;oIMPORTANT: Please call this method to load all server + * information before joining the room or doing anything else. * @method init * @param {String|JSON} options Connection options or API Key ID * @param {String} options.apiKey API Key ID to identify with the Temasys backend server @@ -7911,11 +8065,11 @@ if (webrtcDetectedBrowser.mozWebRTC) { * If there's no room provided, default room would be used. * @param {String} options.region Optional. The regional server that user chooses to use. * [Rel: Skyway.REGIONAL_SERVER] - * @param {String} options.iceTrickle Optional. The option to enable iceTrickle or not. + * @param {Boolean} options.iceTrickle Optional. The option to enable iceTrickle or not. * Default is true. - * @param {String} options.dataChannel Optional. The option to enable dataChannel or not. + * @param {Boolean} options.dataChannel Optional. The option to enable dataChannel or not. * Default is true. - * @param {String} options.credentials Optional. Credentials options + * @param {JSON} options.credentials Optional. Credentials options * @param {String} options.credentials.startDateTime The Start timing of the * meeting in Date ISO String * @param {Integer} options.credentials.duration The duration of the meeting @@ -7962,6 +8116,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @trigger readyStateChange * @for Skyway * @required + * @since 0.3.0 */ Skyway.prototype.init = function(options) { if (!options) { @@ -7984,7 +8139,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { roomserver = options.roomServer || roomserver; roomserver = (roomserver.lastIndexOf('/') === (roomserver.length - 1)) ? roomserver.substring(0, - str.length - 1) : roomserver; + roomserver.length - 1) : roomserver; region = options.region || region; defaultRoom = options.defaultRoom || apiKey; room = defaultRoom; @@ -8027,32 +8182,33 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Reinitialize Skyway signaling credentials + * Re-initialize Skyway signaling credentials. * @method _reinit - * @param {Function} callback Once everything is done * @param {JSON} options * @param {String} options.roomserver * @param {String} options.apiKey * @param {String} options.defaultRoom * @param {String} options.room * @param {String} options.region - * @param {String} options.iceTrickle - * @param {String} options.dataChannel - * @param {String} options.credentials + * @param {Boolean} options.iceTrickle + * @param {Boolean} options.dataChannel + * @param {JSON} options.credentials * @param {String} options.credentials.startDateTime * @param {Integer} options.credentials.duration * @param {String} options.credentials.credentials + * @param {Function} callback Once everything is initialized. * @trigger readyStateChange * @private + * @since 0.4.0 */ - Skyway.prototype._reinit = function(callback, options) { + Skyway.prototype._reinit = function(options, callback) { var self = this; var startDateTime, duration, credentials; var apiKey = options.apiKey || self._apiKey; var roomserver = options.roomServer || self._roomServer; roomserver = (roomserver.lastIndexOf('/') === (roomserver.length - 1)) ? roomserver.substring(0, - str.length - 1) : roomserver; + roomserver.length - 1) : roomserver; var region = options.region || self._serverRegion; var defaultRoom = options.defaultRoom || self._defaultRoom; var room = options.room || defaultRoom; @@ -8095,7 +8251,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { if (status !== 200) { var errorMessage = 'XMLHttpRequest status not OK.\nStatus was: ' + status; self._readyState = 0; - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, errorMessage); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: status, + content: (response) ? (response.info || errorMessage) : errorMessage, + errorCode: response.error || + self.READY_STATE_CHANGE_ERROR.INVALID_XMLHTTPREQUEST_STATUS + }); console.error(errorMessage); return; } @@ -8135,7 +8296,11 @@ if (webrtcDetectedBrowser.mozWebRTC) { callback(); } catch (error) { self._readyState = 0; - self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, error); + self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, { + status: null, + content: error, + errorCode: self.READY_STATE_CHANGE_ERROR.SCRIPT_ERROR + }); console.error('API - Error occurred rejoining room'); console.error(error); return; @@ -8144,9 +8309,13 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Set and Update the User information. Please note that the custom - * data would be overrided so please call getUser and then modify the - * information you want individually. + * Updates the User information. + * - Please note that the custom data would be overrided so please call + * {{#crossLink "Skyway/getUserData:method"}}getUserData(){{/crossLink}} + * and then modify the information you want individually. + * - {{#crossLink "Skyway/peerUpdated:event"}}peerUpdated{{/crossLink}} + * only fires after setUserData() is fired + * after the user joins the room. * @method setUserData * @param {JSON} userData User custom data * @example @@ -8162,64 +8331,63 @@ if (webrtcDetectedBrowser.mozWebRTC) { * userData.userData.fbUserId = 'another Id'; * SkywayDemo.setUserData(userData); * @trigger peerUpdated + * @since 0.3.0 */ Skyway.prototype.setUserData = function(userData) { var self = this; // NOTE ALEX: be smarter and copy fields and only if different - var setUserData = function () { - var initial = (!self._user.info) ? true : false; - var params = { - type: self.SIG_TYPE.UPDATE_USER, - mid: self._user.sid, - rid: self._room.id - }; - self._user.info = self._user.info || {}; - self._user.info.userData = userData || - self._user.info.userData || {}; - console.info(self._user.info); - console.info(userData); - if (self._in_room && !initial) { - params.userData = self._user.info.userData; - self._sendMessage(params); - self._trigger('peerUpdated', self._user.sid, self._user.info, true); - } - }; - if (self._user) { - setUserData(); - } else { - var checkReadyState = setInterval(function () { - if (self._readyState === self.READY_STATE_CHANGE.COMPLETED) { - clearInterval(checkReadyState); - setUserData(); + var checkInRoom = setInterval(function () { + if (self._readyState === self.READY_STATE_CHANGE.COMPLETED) { + self._user.info = self._user.info || {}; + self._user.info.userData = userData || + self._user.info.userData || {}; + if (self._in_room) { + clearInterval(checkInRoom); + self._sendMessage({ + type: self.SIG_TYPE.UPDATE_USER, + mid: self._user.sid, + rid: self._room.id, + userData: self._user.info.userData + }); + self._trigger('peerUpdated', self._user.sid, self._user.info, true); } - }, 500); - } + } + }, 50); }; /** - * Get the User Information + * Gets the user information. * @method getUserData - * @return {JSON} User information + * @return {JSON|} User information * @example * var userInfo = SkywayDemo.getUserData(); + * @since 0.4.0 */ Skyway.prototype.getUserData = function() { - return this._user.info; + return (this._user) ? + ((this._user.info) ? (this._user.info.userData || '') + : '') : ''; }; /** - * Get the Peer Information + * Gets the peer information. + * - If input peerId is user's id or empty, getPeerInfo() + * would return user's peer information. * @method getPeerInfo * @param {String} peerId * @return {JSON} Peer information * @example + * // Example 1: To get other peer's information * var peerInfo = SkywayDemo.getPeerInfo(peerId); + * + * // Example 2: To get own information + * var userInfo = SkywayDemo.getPeerInfo(); + * @since 0.4.0 */ Skyway.prototype.getPeerInfo = function(peerId) { - if (!peerId) { - return; - } - return this._peerInformations[peerId]; + return (peerId && peerId !== this._user.sid) ? + this._peerInformations[peerId] : + ((this._user) ? this._user.info : null); }; /* Syntactically private variables and utility functions */ @@ -8228,90 +8396,103 @@ if (webrtcDetectedBrowser.mozWebRTC) { * Event fired when a successfull connection channel has been established * with the signaling server * @event channelOpen + * @since 0.1.0 */ 'channelOpen': [], /** * Event fired when the channel has been closed. * @event channelClose + * @since 0.1.0 */ 'channelClose': [], /** - * Event fired when we received a message from the sig server.. + * Event fired when we received a message from the signaling server. * @event channelMessage * @param {JSON} message + * @since 0.1.0 */ 'channelMessage': [], /** * Event fired when there was an error with the connection channel to the sig server. * @event channelError - * @param {String} error + * @param {Object|String} error Error message or object thrown. + * @since 0.1.0 */ 'channelError': [], /** * Event fired whether the room is ready for use * @event readyStateChange * @param {String} readyState [Rel: Skyway.READY_STATE_CHANGE] - * @param {String} error Error message when there's an error + * @param {JSON} error Error object thrown. + * @param {Integer} error.status HTTP status when retrieving information. + * May be empty for other errors. + * @param {String} error.content A short description of the error + * @param {Integer} error.errorCode The error code for the type of error + * [Rel: Skyway.READY_STATE_CHANGE_ERROR] + * @since 0.4.0 */ 'readyStateChange': [], /** * Event fired when a step of the handshake has happened. Usefull for diagnostic * or progress bar. * @event handshakeProgress - * @param {String} step [Rel: Skyway.HANDSHAKE_PROGRESS] - * @param {String} peerId - * @param {JSON|Object|String} error Error message when error occurs + * @param {String} step The current handshake progress step. + * [Rel: Skyway.HANDSHAKE_PROGRESS] + * @param {String} peerId PeerId of the peer's handshake progress. + * @param {JSON|Object|String} error Error message or object thrown. + * @since 0.3.0 */ 'handshakeProgress': [], /** * Event fired during ICE gathering * @event candidateGenerationState - * @param {String} state [Rel: Skyway.CANDIDATE_GENERATION_STATE] - * @param {String} peerId + * @param {String} state The current ice candidate generation state. + * [Rel: Skyway.CANDIDATE_GENERATION_STATE] + * @param {String} peerId PeerId of the peer that had an ice candidate + * generation state change. + * @since 0.1.0 */ 'candidateGenerationState': [], /** * Event fired during Peer Connection state change * @event peerConnectionState - * @param {String} state [Rel: Skyway.PEER_CONNECTION_STATE] + * @param {String} state The current peer connection state. + * [Rel: Skyway.PEER_CONNECTION_STATE] + * @param {String} peerId PeerId of the peer that had a peer connection state + * change. + * @since 0.1.0 */ 'peerConnectionState': [], /** * Event fired during ICE connection * @iceConnectionState - * @param {String} state [Rel: Skyway.ICE_CONNECTION_STATE] - * @param {String} peerId + * @param {String} state The current ice connection state. + * [Rel: Skyway.ICE_CONNECTION_STATE] + * @param {String} peerId PeerId of the peer that had an ice connection state change. + * @since 0.1.0 */ 'iceConnectionState': [], //-- per peer, local media events /** * Event fired when allowing webcam media stream fails * @event mediaAccessError - * @param {Object|String} error + * @param {Object|String} error Error message or object thrown. + * @since 0.1.0 */ 'mediaAccessError': [], /** * Event fired when allowing webcam media stream passes * @event mediaAccessSuccess - * @param {Object} stream + * @param {Object} stream MediaStream object. + * @since 0.1.0 */ 'mediaAccessSuccess': [], - /** - * Event fired when a chat message is received from other peers - * @event chatMessageReceived - * @param {String} message - * @param {String} senderPeerId - * @param {String|JSON} userData - * @param {Boolean} isPrivate - * @param {Boolean} isSelf - */ - 'chatMessageReceived': [], /** * Event fired when a peer joins the room. Inactive audio or video means that the * audio is muted or video is muted. * @event peerJoined - * @param {String} peerId - * @param {JSON} peerInfo + * @param {String} peerId PeerId of the peer that joined the room. + * @param {JSON} peerInfo Peer Information of the peer * @param {JSON} peerInfo.settings Peer stream settings * @param {Boolean|JSON} peerInfo.settings.audio * @param {Boolean} peerInfo.settings.audio.stereo @@ -8325,14 +8506,15 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {Boolean} peerInfo.mediaStatus.videoMuted If Peer's Video stream is muted. * @param {String|JSON} peerInfo.userData Peer custom data * @param {Boolean} isSelf Is the Peer self. + * @since 0.3.0 */ 'peerJoined': [], /** * Event fired when a peer information is updated. Inactive audio or video means that the * audio is muted or video is muted. * @event peerUpdated - * @param {String} peerId - * @param {JSON} peerInfo + * @param {String} peerId PeerId of the peer that had information updaed. + * @param {JSON} peerInfo Peer Information of the peer * @param {JSON} peerInfo.settings Peer stream settings * @param {Boolean|JSON} peerInfo.settings.audio * @param {Boolean} peerInfo.settings.audio.stereo @@ -8345,14 +8527,29 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {Boolean} peerInfo.mediaStatus.audioMuted If Peer's Audio stream is muted. * @param {Boolean} peerInfo.mediaStatus.videoMuted If Peer's Video stream is muted. * @param {String|JSON} peerInfo.userData Peer custom data - * @param {Boolean} isSelf Is the Peer self. + * @param {Boolean} isSelf Is the peer self. + * @since 0.3.0 */ 'peerUpdated': [], /** * Event fired when a peer leaves the room * @event peerLeft - * @param {String} peerId, - * @param {Boolean} isSelf + * @param {String} peerId PeerId of the peer that left. + * @param {JSON} peerInfo Peer Information of the peer + * @param {JSON} peerInfo.settings Peer stream settings + * @param {Boolean|JSON} peerInfo.settings.audio + * @param {Boolean} peerInfo.settings.audio.stereo + * @param {Boolean|JSON} peerInfo.settings.video + * @param {JSON} peerInfo.settings.video.resolution [Rel: Skyway.VIDEO_RESOLUTION] + * @param {Integer} peerInfo.settings.video.resolution.width + * @param {Integer} peerInfo.settings.video.resolution.height + * @param {Integer} peerInfo.settings.video.frameRate + * @param {JSON} peerInfo.mediaStatus Peer stream status. + * @param {Boolean} peerInfo.mediaStatus.audioMuted If Peer's Audio stream is muted. + * @param {Boolean} peerInfo.mediaStatus.videoMuted If Peer's Video stream is muted. + * @param {String|JSON} peerInfo.userData Peer custom data + * @param {Boolean} isSelf Is the peer self. + * @since 0.3.0 */ 'peerLeft': [], /** @@ -8361,219 +8558,242 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {JSON} users The list of users * @private * @deprecated + * @since 0.1.0 */ 'presenceChanged': [], //-- per peer, peer connection events /** - * Event fired when a remote stream has become available - * @event addPeerStream - * @param {String} peerId - * @param {Object} stream - * @param {Boolean} isSelf + * Event fired when a remote stream has become available. + * - This occurs after the user joins the room. + * - This is changed from addPeerStream event. Note that + * addPeerStream is removed from the specs. + * @event incomingStream + * @param {Object} stream MediaStream object. + * @param {String} peerId PeerId of the peer that is sending the stream. + * @param {Boolean} isSelf Is the peer self. + * @since 0.4.0 */ - 'addPeerStream': [], + 'incomingStream': [], /** - * TODO Event fired when a remote stream has become unavailable - * @event removePeerStream - * @param {String} peerId - * @private + * Event fired when a message being broadcasted is received. + * @event incomingMessage + * @param {JSON} message Message object that is received. + * @param {JSON|String} message.content Data that is broadcasted. + * @param {String} message.sendPeerId PeerId of the sender peer. + * @param {String} message.targetPeerId PeerId that is specifically + * targeted to receive the message. + * @param {Boolean} message.isPrivate Is data received a private message. + * @param {Boolean} message.isDataChannel Is data received from a data channel. + * @param {String} peerId PeerId of the sender peer. + * @param {Boolean} isSelf Check if message is sent to self + * @since 0.4.0 */ - 'removePeerStream': [], + 'incomingMessage': [], /** - * Event fired when a room is locked + * Event fired when a room lock status has changed. * @event roomLock - * @param {Boolean} success - * @param {Boolean} isLocked - * @param {String} error + * @param {Boolean} isLocked Is the room locked. + * @param {String} peerId PeerId of the peer that is locking/unlocking the room. + * @param {JSON} peerInfo Peer Information of the peer + * @param {JSON} peerInfo.settings Peer stream settings + * @param {Boolean|JSON} peerInfo.settings.audio + * @param {Boolean} peerInfo.settings.audio.stereo + * @param {Boolean|JSON} peerInfo.settings.video + * @param {JSON} peerInfo.settings.video.resolution [Rel: Skyway.VIDEO_RESOLUTION] + * @param {Integer} peerInfo.settings.video.resolution.width Video width + * @param {Integer} peerInfo.settings.video.resolution.height Video height + * @param {Integer} peerInfo.settings.video.frameRate + * @param {JSON} peerInfo.mediaStatus Peer stream status. + * @param {Boolean} peerInfo.mediaStatus.audioMuted If Peer's Audio stream is muted. + * @param {Boolean} peerInfo.mediaStatus.videoMuted If Peer's Video stream is muted. + * @param {String|JSON} peerInfo.userData Peer custom data + * @param {Boolean} isSelf Is the peer self. + * @since 0.4.0 */ 'roomLock': [], //-- data state events /** - * Event fired when a DataChannel's state has changed + * Event fired when a peer's datachannel state has changed. * @event dataChannelState - * @param {String} state [Rel: Skyway.DATA_CHANNEL_STATE] - * @param {String} peerId + * @param {String} state The current datachannel state. + * [Rel: Skyway.DATA_CHANNEL_STATE] + * @param {String} peerId PeerId of peer that has a datachannel state change. + * @since 0.1.0 */ 'dataChannelState': [], /** - * Event fired when a Peer there is a Data Transfer going on + * Event fired when a data transfer state has changed. * @event dataTransferState - * @param {String} state [Rel: Skyway.DATA_TRANSFER_STATE] - * @param {String} transferId ID of the Data Transfer - * @param {String} peerId Peer's ID - * @param {JSON} transferInfo Available data may vary at different state. + * @param {String} state The current data transfer state. + * [Rel: Skyway.DATA_TRANSFER_STATE] + * @param {String} transferId TransferId of the data + * @param {String} peerId PeerId of the peer that has a data + * transfer state change. + * @param {JSON} transferInfo Transfer information. * @param {JSON} transferInfo.percentage The percetange of data being * uploaded / downloaded * @param {JSON} transferInfo.senderPeerId * @param {JSON} transferInfo.data Blob data URL - * @param {JSON} transferInfo.name Data name - * @param {JSON} transferInfo.size Data size - * @param {JSON} transferInfo.message Error message + * @param {JSON} transferInfo.name Blob data name + * @param {JSON} transferInfo.size Blob data size + * @param {JSON} transferInfo.message Error object thrown. * @param {JSON} transferInfo.type Where the error message occurred. * [Rel: Skyway.DATA_TRANSFER_TYPE] + * @since 0.1.0 */ 'dataTransferState': [], /** * Event fired when the Signalling server responds to user regarding * the state of the room * @event systemAction - * @param {String} action [Rel: Skyway.SYSTEM_ACTION] - * @param {String} message The reason of the action + * @param {String} action The action that is required for the current peer to + * follow. [Rel: Skyway.SYSTEM_ACTION] + * @param {String} message Reason for the action + * @since 0.1.0 */ - 'systemAction': [], + 'systemAction': [] + }; + + Skyway.prototype._dataChannelEvents = { /** - * Event fired when a private message is broadcasted. - * @event privateMessage - * @param {JSON|String} data Data to be sent over. Data is based on - * what the user has set. - * @param {String} senderPeerId Sender - * @param {String} peerId Targeted Peer to receive the data - * @param {Boolean} isSelf Check if message is sent to self + * Fired when a datachannel is successfully connected. + * @event Datachannel: CONN + * @param {String} + * @trigger dataChannelState + * @private + * @since 0.4.0 */ - 'privateMessage': [], + 'CONN': [], /** - * Event fired when a public message is broadcasted. - * @event publicMessage - * @param {JSON|String} data Data to be sent over. Data is based on - * what the user has set. - * @param {String} senderPeerId Sender - * @param {Boolean} isSelf Check if message is sent to self + * Fired when a datachannel has a blob data send request. + * @event Datachannel: WRQ + * @param {String} userAgent The user's browser agent. + * @param {String} name The blob data name. + * @param {Integer} size The blob data size. + * @param {Integer} chunkSize The expected chunk size. + * @param {Integer} timeout The timeout in seconds. + * @private + * @since 0.4.0 + */ + 'WRQ': [], + /** + * Fired when a datachannel has a blob data send request acknowledgement. + * - 0: User accepts the request. + * - -1: User rejects the request. + * - Above 0: User acknowledges the blob data packet. + * @event Datachannel: ACK + * @param {Integer} ackN The acknowledge number. + * @param {Integer} userAgent The user's browser agent. + * @private + * @since 0.4.0 + */ + 'ACK': [], + /** + * Fired when a datachannel transfer has an error occurred. + * @event Datachannel: ERROR + * @param {String} message The error message. + * @param {Boolean} isSender If user's the uploader. + * @private + * @since 0.4.0 + */ + 'ERROR': [], + /** + * Fired when a datachannel chat has been received. + * @event Datachannel: CHAT + * @param {String} type If the message is a private or group message. + * - PRIVATE: This message is a private message targeted to a peer. + * - GROUP: This message is to be sent to all peers. + * @param {String} peerId PeerId of the sender. + * @param {JSON|String} message The message data or object. + * @private + * @since 0.4.0 */ - 'publicMessage': [] + 'CHAT': [] }; /** - * Send a chat message - * @method sendChatMessage - * @param {String} message - * @param {String} targetPeerId Optional. Specified when peer wants to - * send a private chat message to the targeted peer. + * Broadcast a message to all peers. + * - WARNING: Map arrays data would be lost when stringified + * in JSON, so refrain from using map arrays. + * @method sendMessage + * @param {String|JSON} message The message data to send. + * @param {String} targetPeerId PeerId of the peer to send a private + * message data to. * @example * // Example 1: Send to all peers - * SkywayDemo.sendChatMessage('Hi there!'); + * SkywayDemo.sendMessage('Hi there!'); * - * // Example 2: Send to specific peer - * SkywayDemo.sendChatMessage('Hi there peer!', targetPeerId) - * @trigger chatMessageReceived + * // Example 2: Send to a targeted peer + * SkywayDemo.sendMessage('Hi there peer!', targetPeerId); + * @trigger incomingMessage + * @since 0.4.0 */ - Skyway.prototype.sendChatMessage = function(message, targetPeerId) { - var message_json = { + Skyway.prototype.sendMessage = function(message, targetPeerId) { + var params = { cid: this._key, data: message, mid: this._user.sid, - sender: this._user.sid, rid: this._room.id, - type: this.SIG_TYPE.CHAT + type: this.SIG_TYPE.PUBLIC_MESSAGE }; if (targetPeerId) { - message_json.target = targetPeerId; - } - this._sendMessage(message_json); - this._trigger('chatMessageReceived', message, this._user.sid, !!targetPeerId, true); + params.target = targetPeerId; + params.type = this.SIG_TYPE.PRIVATE_MESSAGE; + } + this._sendMessage(params); + this._trigger('incomingMessage', { + content: message, + isPrivate: (targetPeerId) ? true: false, + targetPeerId: targetPeerId || null, + isDataChannel: false, + senderPeerId: this._user.sid + }, this._user.sid, true); }; /** - * Send a chat message via DataChannel - * @method sendDataChannelChatMessage - * @param {String} message - * @param {String} targetPeerId Optional. Specified when peer wants to - * send a private chat message to the targeted peer. + * Broadcasts to all P2P datachannel messages and broadcasts to a + * peer only when targetPeerId is provided. + * - This is ideal for sending strings or json objects lesser than 40KB. + * For huge data, please check out + * {{#crossLink "Skyway/sendBlobData:method"}}sendBlobData(){{/crossLink}}. + * - WARNING: Map arrays data would be lost when stringified + * in JSON, so refrain from using map arrays. + * @method sendP2PMessage + * @param {String|JSON} message The message data to send. + * @param {String} targetPeerId Optional. Provide if you want to send to + * only one peer * @example * // Example 1: Send to all peers - * SkywayDemo.sendDataChannelChatMessage('Hi there!'); + * SkywayDemo.sendP2PMessage('Hi there! This is from a DataChannel!'); * * // Example 2: Send to specific peer - * SkywayDemo.sendDataChannelChatMessage('Hi there peer!', targetPeerId) - * @trigger chatMessageReceived + * SkywayDemo.sendP2PMessage('Hi there peer! This is from a DataChannel!', targetPeerId); + * @trigger incomingMessage + * @since 0.4.0 */ - Skyway.prototype.sendDataChannelChatMessage = function(message, targetPeerId) { - var message_json = { - cid: this._key, - data: message, - mid: this._user.sid, - sender: this._user.sid, - rid: this._room.id, - type: this.SIG_TYPE.CHAT - }; - if (targetPeerId) { - message_json.target = targetPeerId; - } - if (targetPeerId) { - if (this._dataChannels.hasOwnProperty(targetPeerId)) { - this._sendDataChannel(targetpeerId, ['CHAT', 'PRIVATE', this._user.sid, message]); - } - } else { - for (var peerId in this._dataChannels) { - if (this._dataChannels.hasOwnProperty(peerId)) { - this._sendDataChannel(peerId, ['CHAT', 'GROUP', this._user.sid, message]); + Skyway.prototype.sendP2PMessage = function(message, targetPeerId) { + // Handle typeof object sent over + for (var peerId in this._dataChannels) { + if (this._dataChannels.hasOwnProperty(peerId)) { + if ((targetPeerId && targetPeerId === peerId) || !targetPeerId) { + this._sendDataChannel(peerId, ['CHAT', ((targetPeerId) ? + 'PRIVATE' : 'GROUP'), this._user.sid, + ((typeof message === 'object') ? JSON.stringify(message) : + message)]); } } } - this._trigger('chatMessage', message, this._user.sid, !!targetPeerId); + this._trigger('incomingMessage', { + content: message, + isPrivate: (targetPeerId) ? true : false, + targetPeerId: targetPeerId || null, // is not null if there's user + isDataChannel: true, + senderPeerId: this._user.sid + }, this._user.sid, true); }; /** - * Broadcasts a private message - * @method sendPrivateMessage - * @param {String|JSON} data - * @param {String} targetPeerId - * @example - * // Example 1: Send JSON - * SkywayDemo.sendPrivateMessage({ - * item1: data1, - * item2: data2 - * }, targetPeerId); - * - * // Example 2: Send a String - * SkywayDemo.sendPrivateMessage(data1 + '-' + data2, targetPeerId); - * @trigger privateMessage - * @beta - */ - Skyway.prototype.sendPrivateMessage = function(data, targetPeerId) { - var message_json = { - cid: this._key, - data: data, - mid: this._user.sid, - rid: this._room.id, - sender: this._user.sid, - target: ((targetpeerId) ? targetPeerId : this._user.sid), - type: this.SIG_TYPE.PRIVATE_MESSAGE - }; - this._sendMessage(message_json); - this._trigger('privateMessage', data, this._user.sid, targetPeerId, true); - }; - - /** - * Broadcasts a public broadcast message - * @method sendPublicMessage - * @param {String|JSON} data - * @example - * // Example 1: Send JSON - * SkywayDemo.sendPublicMessage({ - * item1: data1, - * item2: data2 - * }); - * - * // Example 2: Send a String - * SkywayDemo.sendPublicMessage(data1 + '-' + data2); - * @trigger publicMessage - * @beta - */ - Skyway.prototype.sendPublicMessage = function(data) { - var message_json = { - cid: this._key, - data: data, - mid: this._user.sid, - sender: this._user.sid, - rid: this._room.id, - type: this.SIG_TYPE.PUBLIC_MESSAGE - }; - this._sendMessage(message_json); - this._trigger('publicMessage', data, this._user.sid, true); - }; - - /** - * Get the default cam and microphone + * Get the default webcam and microphone * @method getUserMedia * @param {JSON} options Optional. Media constraints. * @param {JSON|Boolean} options.audio @@ -8585,7 +8805,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {Integer} options.video.frameRate Mininum frameRate of Video * @example * // Default is to get both audio and video - * // Example 1: Get the default stream. + * // Example 1: Get both audio and video by default. * SkywayDemo.getUserMedia(); * * // Example 2: Get the audio stream only @@ -8597,39 +8817,71 @@ if (webrtcDetectedBrowser.mozWebRTC) { * // Example 3: Set the stream settings for the audio and video * SkywayDemo.getUserMedia({ * 'video' : { - * resolution: SkywayDemo.VIDEO_RESOLUTION.HD, - * frameRate: 50 + * 'resolution': SkywayDemo.VIDEO_RESOLUTION.HD, + * 'frameRate': 50 * }, * 'audio' : { stereo: true } * }); * @trigger mediaAccessSuccess, mediaAccessError + * @since 0.4.0 */ Skyway.prototype.getUserMedia = function(options) { var self = this; - // So it would invoke to getMediaStream defaults - options.audio = (options.audio) ? options.audio : typeof options.audio !== 'boolean'; - options.video = (options.video) ? options.video : typeof options.video !== 'boolean'; - self._parseStreamSettings(options); - if (!options.video && !options.audio) { - console.error('API - No streams requested. Request an audio/video or both.'); - return; + var getStream = false; + options = options || { + audio: true, + video: true + }; + // prevent undefined error + self._user = self._user || {}; + self._user.info = self._user.info || {}; + self._user.info.settings = self._user.info.settings || {}; + self._user.streams = self._user.streams || []; + // called during joinRoom + if (self._user.info.settings) { + // So it would invoke to getMediaStream defaults + if (!options.video && !options.audio) { + console.warn('API - No streams requested. Request an audio/video or both.'); + } else if (self._user.info.settings.audio !== options.audio || + self._user.info.settings.video !== options.video) { + if (Object.keys(self._user.streams).length > 0) { + // NOTE: User's stream may hang.. so find a better way? + // NOTE: Also make a use case for multiple streams? + getStream = self._setStreams(options); + if (getStream) { + // NOTE: When multiple streams, streams should not be cleared. + self._user.streams = []; + } + } else { + getStream = true; + } + } + } else { // called before joinRoom + getStream = true; } - try { - window.getUserMedia({ - audio: self._streamSettings.audio, - video: self._streamSettings.video - }, function(stream) { - self._onUserMediaSuccess(stream, self); - }, function(error) { - self._onUserMediaError(error, self); - }); - console.log('API [MediaStream] - Requested ' + - ((self._streamSettings.audio) ? 'A' : '') + - ((self._streamSettings.audio && - self._streamSettings.video) ? '/' : '') + - ((self._streamSettings.video) ? 'V' : '')); - } catch (error) { - this._onUserMediaError(error, self); + self._parseStreamSettings(options); + if (getStream) { + try { + window.getUserMedia({ + audio: self._streamSettings.audio, + video: self._streamSettings.video + }, function(stream) { + self._onUserMediaSuccess(stream, self); + }, function(error) { + self._onUserMediaError(error, self); + }); + console.log('API [MediaStream] - Requested ' + + ((self._streamSettings.audio) ? 'A' : '') + + ((self._streamSettings.audio && + self._streamSettings.video) ? '/' : '') + + ((self._streamSettings.video) ? 'V' : '')); + } catch (error) { + this._onUserMediaError(error, self); + } + } else if (Object.keys(self._user.streams).length > 0) { + console.warn('API - User already has stream. Reactiving stream only.'); + } else { + console.warn('API - Not retrieving stream.'); } }; @@ -8640,6 +8892,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {Skyway} self A convenience pointer to the Skyway object for callbacks * @trigger mediaAccessSuccess * @private + * @since 0.3.0 */ Skyway.prototype._onUserMediaSuccess = function(stream, self) { console.log('API - User has granted access to local media.'); @@ -8649,7 +8902,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { clearInterval(checkReadyState); self._user.streams[stream.id] = stream; self._user.streams[stream.id].active = true; - self._trigger('addPeerStream', self._user.sid, stream, true); + var checkIfUserInRoom = setInterval(function () { + if (self._in_room) { + clearInterval(checkIfUserInRoom); + self._trigger('incomingStream', self._user.sid, stream, true); + } + }, 500); } }, 500); }; @@ -8661,6 +8919,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {Skyway} self A convenience pointer to the Skyway object for callbacks * @trigger mediaAccessFailure * @private + * @since 0.1.0 */ Skyway.prototype._onUserMediaError = function(e, self) { console.log('API - getUserMedia failed with exception type: ' + e.name); @@ -8676,15 +8935,17 @@ if (webrtcDetectedBrowser.mozWebRTC) { /** * Handle every incoming message. If it's a bundle, extract single messages - * Eventually handle the message(s) to - * {{#crossLink "Skyway/_processSingleMessage:method"}}_processSingleMessage(){{/crossLink}} + * - Eventually handle the message(s) to + * {{#crossLink "Skyway/_processSingleMessage:method"}} + * _processSingleMessage(){{/crossLink}} * @method _processSigMessage - * @param {JSON} messageString + * @param {String} messageString * @private + * @since 0.1.0 */ Skyway.prototype._processSigMessage = function(messageString) { var message = JSON.parse(messageString); - if (message.type === 'group') { + if (message.type === this.SIG_TYPE.GROUP) { console.log('API - Bundle of ' + message.lists.length + ' messages.'); for (var i = 0; i < message.lists.length; i++) { this._processSingleMessage(message.lists[i]); @@ -8699,6 +8960,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @method _processingSingleMessage * @param {JSON} message * @private + * @since 0.1.0 */ Skyway.prototype._processSingleMessage = function(message) { this._trigger('channelMessage', message); @@ -8709,8 +8971,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { console.log('API - [' + origin + '] Incoming message: ' + message.type); if (message.mid === this._user.sid && message.type !== this.SIG_TYPE.REDIRECT && - message.type !== this.SIG_TYPE.IN_ROOM && - message.type !== this.SIG_TYPE.CHAT) { + message.type !== this.SIG_TYPE.IN_ROOM) { console.log('API - Ignoring message: ' + message.type + '.'); return; } @@ -8743,9 +9004,6 @@ if (webrtcDetectedBrowser.mozWebRTC) { case this.SIG_TYPE.BYE: this._byeHandler(message); break; - case this.SIG_TYPE.CHAT: - this._chatHandler(message); - break; case this.SIG_TYPE.REDIRECT: this._redirectHandler(message); break; @@ -8765,42 +9023,22 @@ if (webrtcDetectedBrowser.mozWebRTC) { case this.SIG_TYPE.ROOM_LOCK: this._roomLockEventHandler(message); break; - case this.SIG_TYPE.INVITE: - // this._inviteHandler(); - break; default: console.log('API - [' + message.mid + '] Unsupported message type received: ' + message.type); break; } }; - /** - * Throw an event with the received chat message - * @method _chatHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.target targetPeerId. For private message - * @param {String} message.data Chat message - * @param {String} message.sender senderPeerId - * @param {String} message.type Message type - * @trigger chatMessageReceived - * @private - */ - Skyway.prototype._chatHandler = function(message) { - this._trigger('chatMessageReceived', message.data, - message.sender, (message.target ? true : false), false); - }; - /** * Signaling server error message * @method _errorHandler * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.kind Error type - * @param {String} message.type Message type + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the error message. + * @param {String} message.kind The error kind. + * @param {String} message.type The type of message received. * @private + * @since 0.1.0 */ Skyway.prototype._errorHandler = function(message) { console.log('API - [Server] Error occurred: ' + message.kind); @@ -8810,16 +9048,16 @@ if (webrtcDetectedBrowser.mozWebRTC) { /** * Signaling server wants us to move out. * @method _redirectHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.url Deprecated. Url to redirect to - * @param {String} message.info Reason for redirect - * @param {String} message.action Action of the redirect + * @param {JSON} message The message object. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.url Deprecated. Url to redirect to. + * @param {String} message.info The reason for redirect + * @param {String} message.action The action of the redirect * [Rel: Skyway.SYSTEM_ACTION] - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger systemAction * @private + * @since 0.1.0 */ Skyway.prototype._redirectHandler = function(message) { console.log('API - [Server] You are being redirected: ' + message.info); @@ -8827,20 +9065,21 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * User Information is updated + * User information is updated. * @method _updateUserEventHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.userData The Skyway._user.info.userData data. - * @param {String} message.type Message type + * @param {JSON} message The message object. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the + * updated event. + * @param {String} message.userData The peer's user data. + * @param {String} message.type The type of message received. * @trigger peerUpdated * @private + * @since 0.2.0 */ Skyway.prototype._updateUserEventHandler = function(message) { var targetMid = message.mid; console.log('API - [' + targetMid + '] received \'updateUserEvent\'.'); - console.info(message); if (this._peerInformations[targetMid]) { this._peerInformations[targetMid].userData = message.userData || {}; this._trigger('peerUpdated', targetMid, @@ -8849,32 +9088,37 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Room Lock is Fired + * Room lock status is changed. * @method _roomLockEventHandler * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the + * updated room lock status. * @param {String} message.lock If room is locked or not - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger roomLock * @private + * @since 0.2.0 */ Skyway.prototype._roomLockEventHandler = function(message) { var targetMid = message.mid; console.log('API - [' + targetMid + '] received \'roomLockEvent\'.'); - this._trigger('roomLock', true, message.lock); + this._trigger('roomLock', message.lock, targetMid, + this._peerInformations[targetMid], false); }; /** - * Peer Audio is muted/unmuted + * Peer Audio is muted/unmuted. * @method _muteAudioEventHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending + * their own updated audio stream status. * @param {String} message.muted If audio stream is muted or not - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger peerUpdated * @private + * @since 0.2.0 */ Skyway.prototype._muteAudioEventHandler = function(message) { var targetMid = message.mid; @@ -8887,15 +9131,17 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Peer Video is muted/unmuted + * Peer Video is muted/unmuted. * @method _muteVideoEventHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending + * their own updated video streams status. * @param {String} message.muted If video stream is muted or not - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger peerUpdated * @private + * @since 0.2.0 */ Skyway.prototype._muteVideoEventHandler = function(message) { var targetMid = message.mid; @@ -8910,12 +9156,13 @@ if (webrtcDetectedBrowser.mozWebRTC) { /** * A peer left, let's clean the corresponding connection, and trigger an event. * @method _byeHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.type Message type + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that has left the room. + * @param {String} message.type The type of message received. * @trigger peerLeft * @private + * @since 0.1.0 */ Skyway.prototype._byeHandler = function(message) { var targetMid = message.mid; @@ -8926,66 +9173,84 @@ if (webrtcDetectedBrowser.mozWebRTC) { /** * Throw an event with the received private message * @method _privateMessageHandler - * @param {JSON} message - * @param {String} message.sender The senderPeerId. - * @param {JSON|String} message.data The Data broadcasted - * @param {String} message.nick Deprecated. Nickname of the user - * @param {String} message.mid TargetMid - * @param {String} message.cid The credentialId - * @param {String} message.rid RoomId - * @param {String} message.type Message type + * @param {JSON} message The message object received. + * @param {JSON|String} message.data The data broadcasted + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.cid CredentialId of the room + * @param {String} message.mid PeerId of the peer that is sending a private + * broadcast message + * @param {Boolean} message.isDataChannel Is the message sent from datachannel + * @param {String} message.type The type of message received. * @trigger privateMessage * @private + * @since 0.4.0 */ Skyway.prototype._privateMessageHandler = function(message) { - this._trigger('privateMessage', message.data, message.sender, message.target, false); + this._trigger('incomingMessage', { + content: message.data, + isPrivate: true, + targetPeerId: message.target, // is not null if there's user + isDataChannel: (message.isDataChannel) ? true : false, + senderPeerId: this._user.sid + }, this._user.sid, false); }; /** * Throw an event with the received private message * @method _publicMessageHandler - * @param {JSON} message - * @param {String} message.sender The senderPeerId. - * @param {JSON|String} message.data The Data broadcasted - * @param {String} message.nick Deprecated. Nickname of the user - * @param {String} message.mid TargetMid - * @param {String} message.cid The credentialId - * @param {String} message.rid RoomId - * @param {String} message.type Message type + * @param {JSON} message The message object received. + * @param {JSON|String} message.data The data broadcasted + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.cid CredentialId of the room + * @param {String} message.mid PeerId of the peer that is sending a private + * broadcast message + * @param {Boolean} message.isDataChannel Is the message sent from datachannel + * @param {String} message.type The type of message received. * @trigger publicMessage * @private + * @since 0.4.0 */ Skyway.prototype._publicMessageHandler = function(message) { - this._trigger('publicMessage', message.data, message.sender, false); + this._trigger('incomingMessage', { + content: message.data, + isPrivate: false, + targetPeerId: null, // is not null if there's user + isDataChannel: (message.isDataChannel) ? true : false, + senderPeerId: this._user.sid + }, this._user.sid, false); }; /** - * Actually clean the peerconnection and trigger an event. Can be called by _byHandler - * and leaveRoom. + * Actually clean the peerconnection and trigger an event. + * Can be called by _byHandler and leaveRoom. * @method _removePeer - * @param {String} peerId Id of the peer to remove + * @param {String} peerId PeerId of the peer that has left. * @trigger peerLeft * @private + * @since 0.1.0 */ Skyway.prototype._removePeer = function(peerId) { - this._trigger('peerLeft', peerId, false); + this._trigger('peerLeft', peerId, this._peerInformations[peerId], false); if (this._peerConnections[peerId]) { this._peerConnections[peerId].close(); } delete this._peerConnections[peerId]; + delete this._peerInformations[peerId]; }; /** * We just joined a room! Let's send a nice message to all to let them know I'm in. * @method _inRoomHandler - * @param {JSON} message - * @param {JSON} message.pc_config The PeerConnection configuration - * @param {String} message.sid Self peerId. - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.type Message type + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.sid PeerId of self. + * @param {String} message.mid PeerId of the peer that is + * @param {JSON} message.pc_config The peerconnection configuration + * sending the joinRoom message. + * @param {String} message.type The type of message received. * @trigger peerJoined * @private + * @since 0.1.0 */ Skyway.prototype._inRoomHandler = function(message) { var self = this; @@ -9010,7 +9275,6 @@ if (webrtcDetectedBrowser.mozWebRTC) { version: window.webrtcDetectedBrowser.version, userInfo: self._user.info }; - console.info(params); console.log('API - Sending enter.'); self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ENTER, self._user.sid); self._sendMessage(params); @@ -9020,13 +9284,13 @@ if (webrtcDetectedBrowser.mozWebRTC) { * Someone just entered the room. If we don't have a connection with him/her, * send him a welcome. Handshake step 2 and 3. * @method _enterHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.agent Browser agent - * @param {String} message.version Browser version - * @param {String} message.userInfo Peer Skyway._user.info data. - * @param {JSON} message.userInfo.settings Peer stream settings + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the enter shake. + * @param {String} message.agent Peer's browser agent. + * @param {String} message.version Peer's browser version. + * @param {String} message.userInfo Peer's user information. + * @param {JSON} message.userInfo.settings Peer's stream settings * @param {Boolean|JSON} message.userInfo.settings.audio * @param {Boolean} message.userInfo.settings.audio.stereo * @param {Boolean|JSON} message.userInfo.settings.video @@ -9035,18 +9299,20 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {Integer} message.userInfo.settings.video.resolution.height * @param {Integer} message.userInfo.settings.video.frameRate * @param {JSON} message.userInfo.mediaStatus Peer stream status. - * @param {Boolean} message.userInfo.mediaStatus.audioMuted If Peer's Audio stream is muted. - * @param {Boolean} message.userInfo.mediaStatus.videoMuted If Peer's Video stream is muted. + * @param {Boolean} message.userInfo.mediaStatus.audioMuted If peer's audio stream is muted. + * @param {Boolean} message.userInfo.mediaStatus.videoMuted If peer's video stream is muted. * @param {String|JSON} message.userInfo.userData Peer custom data * @param {String} message.type Message type - * @trigger handshakeProgress + * @trigger handshakeProgress, peerJoined * @private + * @since 0.1.0 */ Skyway.prototype._enterHandler = function(message) { var self = this; var targetMid = message.mid; // need to check entered user is new or not. - if (!self._peerConnections[targetMid]) { + if (!self._peerConnections[targetMid] && !self._peerInformations[targetMid] && + targetMid !== self._user.sid) { message.agent = (!message.agent) ? 'Chrome' : message.agent; var browserAgent = message.agent + ((message.version) ? ('|' + message.version) : ''); // should we resend the enter so we can be the offerer? @@ -9059,7 +9325,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { agent: window.webrtcDetectedBrowser.browser, userInfo: self._user.info }; - console.info(params); + console.info(JSON.stringify(params)); if (!beOfferer) { console.log('API - [' + targetMid + '] Sending welcome.'); self._peerInformations[targetMid] = message.userInfo; @@ -9073,7 +9339,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { // NOTE ALEX: and if we already have a connection when the peer enter, // what should we do? what are the possible use case? console.log('API - Received "enter" when Peer "' + targetMid + - '" is already added'); + '" is already added.'); return; } }; @@ -9082,9 +9348,9 @@ if (webrtcDetectedBrowser.mozWebRTC) { * We have just received a welcome. If there is no existing connection with this peer, * create one, then set the remotedescription and answer. * @method _welcomeHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the welcome shake. * @param {String} message.target targetPeerId * @param {Boolean} message.receiveOnly Peer to receive only * @param {Boolean} message.enableIceTrickle Option to enable Ice trickle or not @@ -9104,21 +9370,33 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {String|JSON} message.userInfo.userData Peer custom data * @param {String} message.agent Browser agent * @param {String} message.type Message type - * @trigger handshakeProgress + * @trigger handshakeProgress, peerJoined * @private + * @since 0.1.0 */ Skyway.prototype._welcomeHandler = function(message) { var targetMid = message.mid; - message.agent = (!message.agent) ? 'Chrome' : message.agent; - this._trigger('handshakeProgress', this.HANDSHAKE_PROGRESS.WELCOME, targetMid); - this._peerInformations[targetMid] = message.userInfo; - this._trigger('peerJoined', targetMid, message.userInfo, false); - this._enableIceTrickle = (typeof message.enableIceTrickle === 'boolean') ? - message.enableIceTrickle : this._enableIceTrickle; - this._enableDataChannel = (typeof message.enableDataChannel === 'boolean') ? - message.enableDataChannel : this._enableDataChannel; - if (!this._peerConnections[targetMid]) { + // Prevent duplicates and receiving own peer + if (!this._peerInformations[targetMid] && !this._peerInformations[targetMid] && + targetMid !== this._user.sid) { + message.agent = (!message.agent) ? 'Chrome' : message.agent; + this._trigger('handshakeProgress', this.HANDSHAKE_PROGRESS.WELCOME, targetMid); + this._peerInformations[targetMid] = message.userInfo; + this._trigger('peerJoined', targetMid, message.userInfo, false); + this._enableIceTrickle = (typeof message.enableIceTrickle === 'boolean') ? + message.enableIceTrickle : this._enableIceTrickle; + this._enableDataChannel = (typeof message.enableDataChannel === 'boolean') ? + message.enableDataChannel : this._enableDataChannel; this._openPeer(targetMid, message.agent, true, message.receiveOnly); + } else { + console.log('API - Not creating offer because user is' + + ' connected to peer already.'); + console.error('API [' + targetMid + '] - Peer connectivity issue.' + + ' Refreshing connection'); + this.leaveRoom(); + // set timeout to 500 ? + this.joinRoom(); + return; } }; @@ -9126,14 +9404,14 @@ if (webrtcDetectedBrowser.mozWebRTC) { * We have just received an offer. If there is no existing connection with this peer, * create one, then set the remotedescription and answer. * @method _offerHandler - * @param {JSON} message - * @param {String} message.rid RoomId - * @param {String} message.mid TargetMid. - * @param {String} message.target targetPeerId + * @param {JSON} message The message object received. + * @param {String} message.rid RoomId of the connected room. + * @param {String} message.mid PeerId of the peer that is sending the offer shake. * @param {String} message.sdp Offer sessionDescription - * @param {String} message.type Message type + * @param {String} message.type The type of message received. * @trigger handshakeProgress * @private + * @since 0.1.0 */ Skyway.prototype._offerHandler = function(message) { var self = this; @@ -9161,8 +9439,9 @@ if (webrtcDetectedBrowser.mozWebRTC) { * We have succesfully received an offer and set it locally. This function will take care * of cerating and sendng the corresponding answer. Handshake step 4. * @method _doAnswer - * @param {String} targetMid The peer we should connect to. + * @param {String} targetMid PeerId of the peer to send answer to. * @private + * @since 0.1.0 */ Skyway.prototype._doAnswer = function(targetMid) { var self = this; @@ -9188,11 +9467,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { * We have a peer, this creates a peerconnection object to handle the call. * if we are the initiator, we then starts the O/A handshake. * @method _openPeer - * @param {String} targetMid The peer we should connect to. - * @param {String} peerAgentBrowser The peer's browser + * @param {String} targetMid PeerId of the peer we should connect to. + * @param {String} peerAgentBrowser Peer's browser * @param {Boolean} toOffer Wether we should start the O/A or wait. * @param {Boolean} receiveOnly Should they only receive? * @private + * @since 0.1.0 */ Skyway.prototype._openPeer = function(targetMid, peerAgentBrowser, toOffer, receiveOnly) { var self = this; @@ -9220,8 +9500,9 @@ if (webrtcDetectedBrowser.mozWebRTC) { * Sends our Local MediaStream to other Peers. * By default, it sends all it's other stream * @method _addLocalStream - * @param {String} peerId + * @param {String} peerId PeerId of the peer to send local stream to. * @private + * @since 0.2.0 */ Skyway.prototype._addLocalStream = function(peerId) { // NOTE ALEX: here we could do something smarter @@ -9246,21 +9527,23 @@ if (webrtcDetectedBrowser.mozWebRTC) { * The remote peer advertised streams, that we are forwarding to the app. This is part * of the peerConnection's addRemoteDescription() API's callback. * @method _onRemoteStreamAdded - * @param {String} targetMid + * @param {String} targetMid PeerId of the peer that has remote stream to send. * @param {Event} event This is provided directly by the peerconnection API. - * @trigger addPeerStream + * @trigger incomingStream * @private + * @since 0.1.0 */ Skyway.prototype._onRemoteStreamAdded = function(targetMid, event) { console.log('API - [' + targetMid + '] Remote Stream added.'); - this._trigger('addPeerStream', targetMid, event.stream, false); + this._trigger('incomingStream', targetMid, event.stream, false); }; /** * It then sends it to the peer. Handshake step 3 (offer) or 4 (answer) * @method _doCall - * @param {String} targetMid + * @param {String} targetMid PeerId of the peer to send offer to. * @private + * @since 0.1.0 */ Skyway.prototype._doCall = function(targetMid, peerAgentBrowser) { var self = this; @@ -9287,13 +9570,15 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Find a line in the SDP and return it + * Finds a line in the SDP and returns it. + * - To set the value to the line, add an additional parameter to the method. * @method _findSDPLine - * @param {Array} sdpLines - * @param {Array} condition + * @param {Array} sdpLines Sdp received. + * @param {Array} condition The conditions. * @param {String} value Value to set Sdplines to * @return {Array} [index, line] - Returns the sdpLines based on the condition * @private + * @since 0.2.0 */ Skyway.prototype._findSDPLine = function(sdpLines, condition, value) { for (var index in sdpLines) { @@ -9312,11 +9597,13 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Add Stereo to SDP. Requires OPUS + * Adds stereo feature to the SDP. + * - This requires OPUS to be enabled in the SDP or it will not work. * @method _addStereo - * @param {Array} sdpLines + * @param {Array} sdpLines Sdp received. * @return {Array} Updated version with Stereo feature * @private + * @since 0.2.0 */ Skyway.prototype._addStereo = function(sdpLines) { var opusLineFound = false, @@ -9342,9 +9629,10 @@ if (webrtcDetectedBrowser.mozWebRTC) { /** * Set Audio, Video and Data Bitrate in SDP * @method _setSDPBitrate - * @param {Array} sdpLines + * @param {Array} sdpLines Sdp received. * @return {Array} Updated version with custom Bandwidth settings * @private + * @since 0.2.0 */ Skyway.prototype._setSDPBitrate = function(sdpLines) { // Find if user has audioStream @@ -9373,11 +9661,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { * This takes an offer or an aswer generated locally and set it in the peerconnection * it then sends it to the peer. Handshake step 3 (offer) or 4 (answer) * @method _setLocalAndSendMessage - * @param {String} targetMid + * @param {String} targetMid PeerId of the peer to send offer/answer to. * @param {JSON} sessionDescription This should be provided by the peerconnection API. * User might 'tamper' with it, but then , the setLocal may fail. * @trigger handshakeProgress * @private + * @since 0.1.0 */ Skyway.prototype._setLocalAndSendMessage = function(targetMid, sessionDescription) { var self = this; @@ -9432,10 +9721,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * This sets the STUN server specially for Firefox for ICE Connection + * Sets the STUN server specially for Firefox for ICE Connection. * @method _setFirefoxIceServers - * @param {JSON} config + * @param {JSON} config Ice configuration servers url object. + * @return {JSON} Updated configuration * @private + * @since 0.1.0 */ Skyway.prototype._setFirefoxIceServers = function(config) { if (window.webrtcDetectedBrowser.mozWebRTC) { @@ -9467,8 +9758,9 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Waits for MediaStream. Once the stream is loaded, callback is called - * If there's not a need for stream, callback is called + * Waits for MediaStream. + * - Once the stream is loaded, callback is called + * - If there's not a need for stream, callback is called * @method _waitForMediaStream * @param {Function} callback Callback after requested constraints are loaded. * @param {JSON} options Optional. Media Constraints. @@ -9485,101 +9777,45 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {String} options.bandwidth.video Video Bandwidth * @param {String} options.bandwidth.data Data Bandwidth * @private + * @since 0.4.0 */ Skyway.prototype._waitForMediaStream = function(callback, options) { var self = this; - var getStream = function (doReinit) { - // Loop for stream - console.log('API - requireVideo: ' + options.video); - console.log('API - requireAudio: ' + options.audio); - if (doReinit) { - self.getUserMedia(options); - } else { - self._parseStreamSettings(options); - } + options = options || {}; + self.getUserMedia(options); + + console.log('API - requireVideo: ' + options.video); + console.log('API - requireAudio: ' + options.audio); + + if (options.video || options.audio) { var checkForStream = setInterval(function() { - if (options.video || options.audio) { - for (var stream in self._user.streams) { - if (self._user.streams.hasOwnProperty(stream)) { - var audioTracks = self._user.streams[stream].getAudioTracks(); - var videoTracks = self._user.streams[stream].getVideoTracks(); - if (((options.video) ? (videoTracks.length > 0) : true) && - ((options.audio) ? (audioTracks.length > 0) : true)) { - clearInterval(checkForStream); - callback(); - break; - } + for (var stream in self._user.streams) { + if (self._user.streams.hasOwnProperty(stream)) { + var audioTracks = self._user.streams[stream].getAudioTracks(); + var videoTracks = self._user.streams[stream].getVideoTracks(); + if (((options.video) ? (videoTracks.length > 0) : true) && + ((options.audio) ? (audioTracks.length > 0) : true)) { + clearInterval(checkForStream); + callback(); + break; } } - } else { - clearInterval(checkForStream); - callback(); } }, 2000); - }; - // Scenario 1: No options - if (!options) { - callback(); - console.log('Scenario 1'); - return; - // Scenario 2: Only bandwidth or user options } else { - // Set User - self._user.info = self._user.info || {}; - self._user.info.userData = options.user || self._user.info.userData; - // Bandwidth options only - if (!options.hasOwnProperty('video') && !options.hasOwnProperty('audio')) { - self._parseStreamSettings(options); - callback(); - console.log('Scenario 2'); - return; - } else { - if (options.hasOwnProperty('user')) { - delete options.user; - } - // If undefined, at least set to boolean - options.video = options.video || false; - options.audio = options.audio || false; - // Does user has settings? - if (!self._user.info.settings) { - getStream(true); - console.log('Scenario 3'); - } else { - console.info(self._user.info.settings.audio !== options.audio); - console.info(self._user.info.settings.video !== options.video); - console.info(self._user.info.settings.audio !== options.audio || - self._user.info.settings.video !== options.video); - - if (self._user.info.settings.audio !== options.audio || - self._user.info.settings.video !== options.video) { - if (Object.keys(self._user.streams).length > 0) { - // NOTE: User's stream may hang.. so find a better way? - var reinit = self._setStreams(options); - getStream(reinit); - console.log('Scenario 4'); - } else { - self._parseStreamSettings(options); - callback(); - console.log('Scenario 5'); - } - } else { - self._parseStreamSettings(options); - callback(); - console.log('Scenario 6'); - } - } - } + callback(); } }; /** - * Close/Open existing mediaStreams + * Opens or closes existing MediaStreams. * @method _setStreams * @param {JSON} options * @param {JSON} options.audio Enable audio or not * @param {JSON} options.video Enable video or not * @return {Boolean} Whether we should re-fetch mediaStreams or not * @private + * @since 0.3.0 */ Skyway.prototype._setStreams = function(options) { var hasAudioTracks = false, hasVideoTracks = false; @@ -9615,12 +9851,13 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Create a peerconnection to communicate with the peer whose ID is 'targetMid'. + * Creates a peerconnection to communicate with the peer whose ID is 'targetMid'. * All the peerconnection callbacks are set up here. This is a quite central piece. * @method _createPeerConnection * @param {String} targetMid * @return {Object} The created peer connection object. * @private + * @since 0.1.0 */ Skyway.prototype._createPeerConnection = function(targetMid) { var pc, self = this; @@ -9702,6 +9939,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {Event} event This is provided directly by the peerconnection API. * @trigger candidateGenerationState * @private + * @since 0.1.0 */ Skyway.prototype._onIceCandidate = function(targetMid, event) { if (event.candidate) { @@ -9740,7 +9978,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Handling reception of a candidate. handshake done, connection ongoing. + * Handles the reception of a candidate. handshake done, connection ongoing. * @method _candidateHandler * @param {JSON} message * @param {String} message.rid RoomId @@ -9751,6 +9989,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {String} message.label IceCandidate label * @param {String} message.type Message type * @private + * @since 0.1.0 */ Skyway.prototype._candidateHandler = function(message) { var targetMid = message.mid; @@ -9786,7 +10025,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Handling reception of an answer (to a previous offer). handshake step 4. + * Handles the reception of an answer (to a previous offer). handshake step 4. * @method _answerHandler * @param {JSON} message * @param {String} message.rid RoomId @@ -9796,6 +10035,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {String} message.type Message type * @trigger handshakeProgress * @private + * @since 0.1.0 */ Skyway.prototype._answerHandler = function(message) { var self = this; @@ -9815,10 +10055,14 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Send a message to the signaling server + * Sends a message to the signaling server. + * - Not to be confused with method + * {{#crossLink "Skyway/sendMessage:method"}}sendMessage(){{/crossLink}} + * that broadcasts messages. This is for sending socket messages. * @method _sendMessage * @param {JSON} message * @private + * @since 0.1.0 */ Skyway.prototype._sendMessage = function(message) { if (!this._channel_open) { @@ -9831,10 +10075,11 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Initiate a Socket signaling connection. + * Initiate a socket signaling connection. * @method _openChannel * @trigger channelMessage, channelOpen, channelError, channelClose * @private + * @since 0.1.0 */ Skyway.prototype._openChannel = function() { var self = this; @@ -9879,9 +10124,10 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Close the Socket signaling connection. + * Closes the socket signaling connection. * @method _closeChannel * @private + * @since 0.1.0 */ Skyway.prototype._closeChannel = function() { if (!this._channel_open) { @@ -9895,11 +10141,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { /** * Create a DataChannel. Only SCTPDataChannel support * @method _createDataChannel - * @param {String} peerId The peerId of which the dataChannel is connected to - * @param {Function} callback The callback which it returns the DataChannel object to - * @param {Object} dc The DataChannel object passed inside + * @param {String} peerId PeerId of the peer which the datachannel is connected to + * @param {Function} callback The callback fired when datachannel is created. + * @param {Object} dc The datachannel object received. * @trigger dataChannelState * @private + * @since 0.1.0 */ Skyway.prototype._createDataChannel = function(peerId, callback, dc) { var self = this; @@ -9944,11 +10191,14 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Check DataChannel ReadyState. If ready, it sends a 'CONN' + * Checks datachannel ready state. + * - If ready, it sends a + * {{#crossLink "Skyway/CONN:event"}}CONN{{/crossLink}}. * @method _checkDataChannelStatus - * @param {Object} dc DataChannel object + * @param {Object} dc The datachannel object. * @trigger dataChannelState * @private + * @since 0.1.0 */ Skyway.prototype._checkDataChannelStatus = function(dc) { var self = this; @@ -9965,11 +10215,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Sending of String Data over the DataChannels + * Sends data to the datachannel. * @method _sendDataChannel - * @param {String} peerId - * @param {JSON} data + * @param {String} peerId PeerId of the peer's datachannel to send data. + * @param {JSON} data The data to send. * @private + * @since 0.1.0 */ Skyway.prototype._sendDataChannel = function(peerId, data) { var dc = this._dataChannels[peerId]; @@ -10001,23 +10252,25 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * To obtain the Peer that it's connected to from the DataChannel + * Obtains the peerId of the peer connected to the datachannel. * @method _dataChannelPeer - * @param {String} channel - * @param {Skyway} self + * @param {String} channel The datachannel name. + * @param {Skyway} self Skyway object. * @private * @deprecated + * @since 0.1.0 */ Skyway.prototype._dataChannelPeer = function(channel, self) { return self._dataChannelPeers[channel]; }; /** - * To obtain the Peer that it's connected to from the DataChannel + * Closes the datachannel. * @method _closeDataChannel - * @param {String} peerId - * @param {Skyway} self + * @param {String} peerId PeerId of the peer's datachannel to close. + * @param {Skyway} self Skyway object. * @private + * @since 0.1.0 */ Skyway.prototype._closeDataChannel = function(peerId, self) { var dc = self._dataChannels[peerId]; @@ -10031,10 +10284,11 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * The Handler for all DataChannel Protocol events + * Handles all datachannel protocol events. * @method _dataChannelHandler - * @param {String} data + * @param {String|Object} data The data received from datachannel. * @private + * @since 0.1.0 */ Skyway.prototype._dataChannelHandler = function(dataString, peerId, self) { // PROTOCOL ESTABLISHMENT @@ -10043,33 +10297,26 @@ if (webrtcDetectedBrowser.mozWebRTC) { var data = dataString.split('|'); var state = data[0]; console.log('API - DataChannel [' + peerId + ']: Received ' + state); - switch (state) { case 'CONN': - // CONN - DataChannel Connection has been established self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.OPEN, peerId); break; case 'WRQ': - // WRQ - Send File Request Received. For receiver to accept or not self._dataChannelWRQHandler(peerId, data, self); break; case 'ACK': - // ACK - If accepted, send. Else abort self._dataChannelACKHandler(peerId, data, self); break; case 'ERROR': - // ERROR - Failure in receiving data. Could be timeout self._dataChannelERRORHandler(peerId, data, self); break; case 'CHAT': - // CHAT - DataChannel Chat self._dataChannelCHATHandler(peerId, data, self); break; default: console.error('API - DataChannel [' + peerId + ']: Invalid command'); } } else { - // DATA - BinaryString base64 received console.log('API - DataChannel [' + peerId + ']: Received "DATA"'); self._dataChannelDATAHandler(peerId, dataString, self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING, self); @@ -10078,15 +10325,15 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * DataChannel TFTP Protocol Stage: WRQ - * The sender has sent a request to send file + * The user receives a blob request. * From here, it's up to the user to accept or reject it * @method _dataChannelWRQHandler - * @param {String} peerId - * @param {Array} data - * @param {Skyway} self + * @param {String} peerId PeerId of the peer that is sending the request. + * @param {Array} data The data object received from datachannel. + * @param {Skyway} self Skyway object. * @trigger dataTransferState * @private + * @since 0.4.0 */ Skyway.prototype._dataChannelWRQHandler = function(peerId, data, self) { var transferId = this._user.sid + this.DATA_TRANSFER_TYPE.DOWNLOAD + @@ -10095,42 +10342,60 @@ if (webrtcDetectedBrowser.mozWebRTC) { var binarySize = parseInt(data[3], 10); var expectedSize = parseInt(data[4], 10); var timeout = parseInt(data[5], 10); - var sendDataTransfer = confirm('Do you want to receive "' + name + '" ?'); - - if (sendDataTransfer) { - self._downloadDataTransfers[peerId] = []; - self._downloadDataSessions[peerId] = { - transferId: transferId, - name: name, - size: binarySize, - ackN: 0, - receivedSize: 0, - chunkSize: expectedSize, - timeout: timeout - }; - self._sendDataChannel(peerId, ['ACK', 0, window.webrtcDetectedBrowser.browser]); + self._downloadDataSessions[peerId] = { + transferId: transferId, + name: name, + size: binarySize, + ackN: 0, + receivedSize: 0, + chunkSize: expectedSize, + timeout: timeout + }; + var transferInfo = { + name: name, + size: binarySize, + senderPeerId: peerId + }; + self._trigger('dataTransferState', + self.DATA_TRANSFER_STATE.UPLOAD_REQUEST, transferId, peerId, transferInfo); + }; + + /** + * User's response to accept or reject file. + * @method respondBlobRequest + * @param {String} peerId PeerId of the peer that is expected to receive + * the request response. + * @param {Boolean} accept Accept the Blob download request or not. + * @trigger dataTransferState + * @since 0.4.0 + */ + Skyway.prototype.respondBlobRequest = function (peerId, accept) { + if (accept) { + this._downloadDataTransfers[peerId] = []; + var data = this._downloadDataSessions[peerId]; + this._sendDataChannel(peerId, ['ACK', 0, window.webrtcDetectedBrowser.browser]); var transferInfo = { - name: name, - size: binarySize, + name: data.name, + size: data.size, senderPeerId: peerId }; - this._trigger('dataTransferState', - this.DATA_TRANSFER_STATE.DOWNLOAD_STARTED, transferId, peerId, transferInfo); + this._trigger('dataTransferState', this.DATA_TRANSFER_STATE.DOWNLOAD_STARTED, + data.transferId, peerId, transferInfo); } else { - self._sendDataChannel(peerId, ['ACK', -1]); + this._sendDataChannel(peerId, ['ACK', -1]); + delete this._downloadDataSessions[peerId]; } }; /** - * DataChannel TFTP Protocol Stage: ACK - * The user sends a ACK of the request [accept/reject/nhe current - * index of chunk to be sent over] + * The user receives an acknowledge of the blob request. * @method _dataChannelACKHandler - * @param {String} peerId - * @param {Array} data - * @param {Skyway} self + * @param {String} peerId PeerId of the peer that is sending the acknowledgement. + * @param {Array} data The data object received from datachannel. + * @param {Skyway} self Skyway object. * @trigger dataTransferState * @private + * @since 0.1.0 */ Skyway.prototype._dataChannelACKHandler = function(peerId, data, self) { self._clearDataChannelTimeout(peerId, true, self); @@ -10178,54 +10443,62 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * DataChannel TFTP Protocol Stage: CHAT - * The user receives a DataChannel CHAT message + * The user receives a datachannel broadcast message. * @method _dataChannelCHATHandler - * @param {String} peerId - * @param {Array} data - * @param {Skyway} self - * @trigger dataTransferState + * @param {String} peerId PeerId of the peer that is sending a broadcast message. + * @param {Array} data The data object received from datachannel. + * @param {Skyway} self Skyway object. + * @trigger incomingMessage * @private + * @since 0.4.0 */ Skyway.prototype._dataChannelCHATHandler = function(peerId, data) { - var messageChatType = this._stripNonAlphanumeric(data[1]); - var messageNick = this._stripNonAlphanumeric(data[2]); + var isPrivate = (this._stripNonAlphanumeric(data[1]) === 'PRIVATE') ? + true : false; + var senderPeerId = this._stripNonAlphanumeric(data[2]); + var params = { + cid: this._key, + mid: senderPeerId, + rid: this._room.id, + isDataChannel: true + }; // Get remaining parts as the message contents. // Get the index of the first char of chat content //var start = 3 + data.slice(0, 3).join('').length; - var messageChat = ''; + params.data = ''; // Add all char from start to the end of dataStr. // This method is to allow '|' to appear in the chat message. for (var i = 3; i < data.length; i++) { - messageChat += data[i]; + params.data += data[i]; } - console.log('API - Got DataChannel Chat Message: ' + messageChat + '.'); - console.log('API - Got a ' + messageChatType + ' chat message from ' + - peerId + ' (' + messageNick + ').'); - - // Create a message using event.data, message mid. - var message = { - type: this.SIG_TYPE.CHAT, - mid: peerId, - sender: peerId, - data: '[DC]: ' + messageChat - }; - // For private message, create a target field with our id. - if (messageChatType === 'PRIVATE') { - message.target = this._user.sid; + // Handle different type of data + try { + var result = JSON.parse(params.data); + params.data = result; + console.log('API - Received data is a JSON.'); + } catch (error) { + console.log('API - Received data is not a JSON.'); } - this._processSingleMessage(message); + if (isPrivate) { + params.target = this._user.sid; + params.type = this.SIG_TYPE.PRIVATE_MESSAGE; + } else { + params.target = this._user.sid; + params.type = this.SIG_TYPE.PUBLIC_MESSAGE; + } + // Create a message using event.data, message mid. + this._processSingleMessage(params); }; /** - * DataChannel TFTP Protocol Stage: ERROR - * The user received an error, usually an exceeded timeout. + * The user receives a timeout error. * @method _dataChannelERRORHandler - * @param {String} peerId - * @param {Array} data - * @param {Skyway} self + * @param {String} peerId PeerId of the peer that is sending the error. + * @param {Array} data The data object received from datachannel. + * @param {Skyway} self Skyway object. * @trigger dataTransferState * @private + * @since 0.1.0 */ Skyway.prototype._dataChannelERRORHandler = function(peerId, data, self) { var isUploader = data[2]; @@ -10242,15 +10515,16 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * DataChannel TFTP Protocol Stage: DATA - * This is when the data is sent from the sender to the receiving user + * This is when the data is sent from the sender to the receiving user. * @method _dataChannelDATAHandler - * @param {String} peerId - * @param {ArrayBuffer|Blob|String} dataString - * @param {String} dataType [Rel: Skyway.DATA_TRANSFER_DATA_TYPE] - * @param {Skyway} self + * @param {String} peerId PeerId of the peer that is sending the data. + * @param {ArrayBuffer|Blob|String} dataString The data received. + * @param {String} dataType The data type received from datachannel. + * [Rel: Skyway.DATA_TRANSFER_DATA_TYPE] + * @param {Skyway} self Skyway object. * @trigger dataTransferState * @private + * @since 0.1.0 */ Skyway.prototype._dataChannelDATAHandler = function(peerId, dataString, dataType, self) { var chunk, transferInfo = {}; @@ -10319,13 +10593,15 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Set the DataChannel timeout. If exceeded, send the 'ERROR' message + * Sets the datachannel timeout. + * - If timeout is met, it will send the 'ERROR' message * @method _setDataChannelTimeout - * @param {String} peerId - * @param {Integer} timeout - * @param {Boolean} isSender - * @param {Skyway} self + * @param {String} peerId PeerId of the datachannel to set timeout. + * @param {Integer} timeout The timeout to set in seconds. + * @param {Boolean} isSender Is peer the sender or the receiver? + * @param {Skyway} self Skyway object. * @private + * @since 0.1.0 */ Skyway.prototype._setDataChannelTimeout = function(peerId, timeout, isSender, self) { if (!self._dataTransfersTimeout[peerId]) { @@ -10354,12 +10630,13 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Clear the DataChannel timeout as a response is received + * Clears the datachannel timeout. * @method _clearDataChannelTimeout - * @param {String} peerId - * @param {Boolean} isSender - * @param {Skyway} self + * @param {String} peerId PeerId of the datachannel to clear timeout. + * @param {Boolean} isSender Is peer the sender or the receiver? + * @param {Skyway} self Skyway object. * @private + * @since 0.1.0 */ Skyway.prototype._clearDataChannelTimeout = function(peerId, isSender, self) { if (self._dataTransfersTimeout[peerId]) { @@ -10371,14 +10648,15 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Convert base64 to raw binary data held in a string. - * Doesn't handle URLEncoded DataURIs - * - see StackOverflow answer #6850276 for code that does this + * Converts base64 string to raw binary data. + * - Doesn't handle URLEncoded DataURIs + * - See StackOverflow answer #6850276 for code that does this * This is to convert the base64 binary string to a blob * @author Code from devnull69 @ stackoverflow.com * @method _base64ToBlob - * @param {String} dataURL + * @param {String} dataURL Blob base64 dataurl. * @private + * @since 0.1.0 */ Skyway.prototype._base64ToBlob = function(dataURL) { var byteString = atob(dataURL.replace(/\s\r\n/g, '')); @@ -10393,12 +10671,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * To chunk the File (which already is a blob) into smaller blob files. - * For now please send files below or around 2KB till chunking is implemented + * Chunks blob data into chunks. * @method _chunkFile - * @param {Blob} blob - * @param {Integer} blobByteSize + * @param {Blob} blob The blob data to chunk. + * @param {Integer} blobByteSize The blob data size. * @private + * @since 0.1.0 */ Skyway.prototype._chunkFile = function(blob, blobByteSize) { var chunksArray = [], @@ -10422,11 +10700,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Removes non-alphanumeric characters from a string and return it. + * Removes non-alphanumeric characters from a string. * @method _stripNonAlphanumeric * @param {String} input String to check. * @return {String} Updated string from non-alphanumeric characters * @private + * @since 0.2.0 */ Skyway.prototype._stripNonAlphanumeric = function(str) { var strOut = ''; @@ -10447,13 +10726,14 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Check if a text string consist of only alphanumeric characters. - * If so, return true. - * If not, return false. + * Check if a string consist of only alphanumeric characters. + * - If alphanumeric characters are found, it will return true, + * else it returns false. * @method _alphanumeric * @param {String} input String to check. * @return {Boolean} If string contains only alphanumeric characters. * @private + * @since 0.2.0 */ Skyway.prototype._alphanumeric = function(str) { var letterNumber = /^[0-9a-zA-Z]+$/; @@ -10464,17 +10744,21 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Method to send Blob data to peers. - * Peers have the option to download or reject the file. + * Sends blob data to peer(s). + * - Note that peers have the option to download or reject receiving the blob data. + * - This method is ideal for sending files. + * - To send a private file to a peer, input the peerId after the + * data information. * @method sendBlobData - * @param {Blob} data - The Blob data to be sent over - * @param {JSON} dataInfo - The Blob data information - * @param {String} dataInfo.name The Blob data name - * @param {Integer} dataInfo.timeout The timeout to wait for packets - * @param {Integer} dataInfo.size The Blob data size. Default is 60. - * @param {String} targetPeerId The specific peerId to send to. + * @param {Blob} data The blob data to be sent over. + * @param {JSON} dataInfo The data information. + * @param {String} dataInfo.transferId TransferId of the data. + * @param {String} dataInfo.name Data name. + * @param {Integer} dataInfo.timeout Data timeout to wait for packets. + * [Default is 60]. + * @param {Integer} dataInfo.size Data size + * @param {String} targetPeerId PeerId targeted to receive data. * Leave blank to send to all peers. - * @bubbles dataTransferState * @example * // Send file to all peers connected * SkywayDemo.sendBlobData(file, { @@ -10490,6 +10774,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * 'timeout' : 87 * }, targetPeerId); * @trigger dataTransferState + * @since 0.1.0 */ Skyway.prototype.sendBlobData = function(data, dataInfo, targetPeerId) { if (!data && !dataInfo) { @@ -10526,6 +10811,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { senderPeerId: this._user.sid, name: dataInfo.name, size: dataInfo.size, + timeout: dataInfo.timeout || 60, data: URL.createObjectURL(data) }; this._trigger('dataTransferState', @@ -10544,18 +10830,21 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Method to send Blob data to individual peer. - * This sends the 'WRQ' and initiate the TFTP protocol. + * Sends blob data to individual peer. + * - This sends the {{#crossLink "Skyway/WRQ:event"}}WRQ{{/crossLink}} + * and to initiate the TFTP protocol. * @method _sendBlobDataToPeer - * @param {Blob} data - The Blob data to be sent over - * @param {JSON} dataInfo - The Blob data information - * @param {String} dataInfo.transferId The transfer Id - * @param {String} dataInfo.name The Blob data name - * @param {Integer} dataInfo.timeout The timeout to wait for packets. - * Default is 60. - * @param {Integer} dataInfo.size The Blob data size - * @param {String} targetPeerId + * @param {Blob} data The blob data to be sent over. + * @param {JSON} dataInfo The data information. + * @param {String} dataInfo.transferId TransferId of the data. + * @param {String} dataInfo.name Data name. + * @param {Integer} dataInfo.timeout Data timeout to wait for packets. + * [Default is 60]. + * @param {Integer} dataInfo.size Data size + * @param {String} targetPeerId PeerId targeted to receive data. + * Leave blank to send to all peers. * @private + * @since 0.1.0 */ Skyway.prototype._sendBlobDataToPeer = function(data, dataInfo, targetPeerId) { var binarySize = (dataInfo.size * (4 / 3)).toFixed(); @@ -10579,13 +10868,17 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * Handle the Lock actions + * Handles all the room lock events. * @method _handleLock - * @param {String} lockAction [Rel: SkywayDemo.LOCK_ACTION] + * @param {String} lockAction Lock action to send to server for response. + * [Rel: SkywayDemo.LOCK_ACTION] + * @param {Function} callback The callback to return the response after + * everything's loaded. * @trigger roomLock * @private + * @since 0.4.0 */ - Skyway.prototype._handleLock = function(lockAction) { + Skyway.prototype._handleLock = function(lockAction, callback) { var self = this; var url = self._serverPath + '/rest/room/lock'; var params = { @@ -10600,12 +10893,15 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; self._requestServerInfo('POST', url, function(status, response) { if (status !== 200) { - self._trigger('roomLock', false, null, 'Request failed!'); + console.error('API - Failed ' + lockAction + 'ing room.\nReason was:'); + console.error('XMLHttpRequest status not OK.\nStatus was: ' + status); return; } console.info(response); if (response.status) { - self._trigger('roomLock', true, response.content.lock); + self._room_lock = response.content.lock; + self._trigger('roomLock', response.content.lock, self._user.sid, + self._user.info, true); if (lockAction !== self.LOCK_ACTION.STATUS) { self._sendMessage({ type: self.SIG_TYPE.ROOM_LOCK, @@ -10615,203 +10911,234 @@ if (webrtcDetectedBrowser.mozWebRTC) { }); } } else { - self._trigger('roomLock', false, null, response.message); + console.error('API - Failed ' + lockAction + 'ing room.\nReason was:'); + console.error(response.message); } }, params); }; /** - * Restart the {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} - * process to initiate Audio and Video + * Handles all audio and video mute events. + * - If there is no available audio or video stream, it will call + * {{#crossLink "Skyway/leaveRoom:method"}}leaveRoom(){{/crossLink}} + * and call {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} + * to join user in the room to send their audio and video stream. * @method _handleAV - * @param {String} mediaType - * @param {Boolean} isEnabled - * @param {Boolean} hasMedia + * @param {String} mediaType Media types expected to receive. + * [Rel: 'audio' or 'video'] + * @param {Boolean} enableMedia Enable it or disable it * @trigger peerUpdated * @private + * @since 0.4.0 */ - Skyway.prototype._handleAV = function(mediaType, isEnabled, hasMedia) { + Skyway.prototype._handleAV = function(mediaType, enableMedia) { if (mediaType !== 'audio' && mediaType !== 'video') { return; + } else if (!this._in_room) { + console.error('API - User is not in the room. Cannot ' + + ((enableMedia) ? 'enable' : 'disable') + ' ' + mediaType); + return; } - this._sendMessage({ - type: ((mediaType === 'audio') ? this.SIG_TYPE.MUTE_AUDIO : - this.SIG_TYPE.MUTE_VIDEO), - mid: this._user.sid, - rid: this._room.id, - muted: !isEnabled - }); - if (hasMedia === false) { + // Loop and enable tracks accordingly + var hasTracks = false, isTracksActive = false; + for (var stream in this._user.streams) { + if (this._user.streams.hasOwnProperty(stream)) { + var tracks = (mediaType === 'audio') ? + this._user.streams[stream].getAudioTracks() : + this._user.streams[stream].getVideoTracks(); + for (var track in tracks) { + if (tracks.hasOwnProperty(track)) { + tracks[track].enabled = enableMedia; + hasTracks = true; + } + } + isTracksActive = this._user.streams[stream].active; + } + } + // Broadcast to other peers + if (!(hasTracks && isTracksActive) && enableMedia) { this.leaveRoom(); + var hasProperty = (this._user) ? ((this._user.info) ? ( + (this._user.info.settings) ? true : false) : false) : false; + // set timeout? to 500? this.joinRoom({ - audio: (mediaType === 'audio') ? true : this._streamSettings.audio, - video: (mediaType === 'video') ? true : this._streamSettings.video + audio: (mediaType === 'audio') ? true : ((hasProperty) ? + this._user.info.settings.audio : false), + video: (mediaType === 'video') ? true : ((hasProperty) ? + this._user.info.settings.video : false) + }); + } else { + this._sendMessage({ + type: ((mediaType === 'audio') ? this.SIG_TYPE.MUTE_AUDIO : + this.SIG_TYPE.MUTE_VIDEO), + mid: this._user.sid, + rid: this._room.id, + muted: !enableMedia }); } - if (this._in_room) { - this._user.info.mediaStatus[mediaType + 'Muted'] = !isEnabled; - this._trigger('peerUpdated', this._user.sid, this._user.info, true); - } + this._user.info.mediaStatus[mediaType + 'Muted'] = !enableMedia; + this._trigger('peerUpdated', this._user.sid, this._user.info, true); }; /** - * Lock the Room to prevent users from coming in + * Lock the room to prevent peers from joining. * @method lockRoom - * @bubbles lockRoom * @example * SkywayDemo.lockRoom(); * @trigger lockRoom - * @beta + * @since 0.2.0 */ Skyway.prototype.lockRoom = function() { this._handleLock(this.LOCK_ACTION.LOCK); }; /** - * Unlock the Room to allow users to come in + * Unlock the room to allow peers to join. * @method unlockRoom - * @bubbles lockRoom * @example * SkywayDemo.unlockRoom(); * @trigger lockRoom - * @beta + * @since 0.2.0 */ Skyway.prototype.unlockRoom = function() { this._handleLock(this.LOCK_ACTION.UNLOCK); }; /** - * Enable Microphone. If Microphone is not enabled from the - * beginning, user would have to reinitate the - * {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} - * process and ask for Microphone again. + * Get the lock status of the room. + * - WARNING: If there's too many peers toggling the + * room lock feature at the same time, the returned results may not + * be completely correct since while retrieving the room lock status, + * another peer may be toggling it. + * @method isRoomLocked + * @example + * if(SkywayDemo.isRoomLocked()) { + * SkywayDemo.unlockRoom(); + * } else { + * SkywayDemo.lockRoom(); + * } + * @beta + * @since 0.4.0 + */ + Skyway.prototype.isRoomLocked = function() { + this._handleLock(this.LOCK_ACTION.STATUS, function (lockAction) { + return lockAction; + }); + }; + + /** + * Enable microphone. + * - If microphone is not enabled from the beginning, user would have to reinitate the + * {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} + * process and ask for microphone again. * @method enableAudio * @trigger peerUpdated * @example * SkywayDemo.enableAudio(); + * @since 0.4.0 */ Skyway.prototype.enableAudio = function() { - var hasAudioTracks = false, audioTracksActive = false; - for (var stream in this._user.streams) { - if (this._user.streams.hasOwnProperty(stream)) { - var tracks = this._user.streams[stream].getAudioTracks(); - for (var track in tracks) { - if (tracks.hasOwnProperty(track)) { - tracks[track].enabled = true; - hasAudioTracks = true; - } - } - audioTracksActive = this._user.streams[stream].active; - } - } - this._handleAV('audio', true, (hasAudioTracks && audioTracksActive)); + this._handleAV('audio', true); }; /** - * Disable Microphone. If Microphone is not enabled from the - * beginning, there is no effect. + * Disable microphone. + * - If microphone is not enabled from the beginning, there is no effect. * @method disableAudio * @example * SkywayDemo.disableAudio(); * @trigger peerUpdated + * @since 0.4.0 */ Skyway.prototype.disableAudio = function() { - for (var stream in this._user.streams) { - if (this._user.streams.hasOwnProperty(stream)) { - var tracks = this._user.streams[stream].getAudioTracks(); - for (var track in tracks) { - if (tracks.hasOwnProperty(track)) { - tracks[track].enabled = false; - } - } - } - } this._handleAV('audio', false); }; /** - * Enable Webcam Video. If Webcam Video is not enabled from the - * beginning, user would have to reinitate the - * {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} - * process and ask for Webcam video again. + * Enable webcam video. + * - If webcam is not enabled from the beginning, user would have to reinitate the + * {{#crossLink "Skyway/joinRoom:method"}}joinRoom(){{/crossLink}} + * process and ask for webcam again. * @method enableVideo * @example * SkywayDemo.enableVideo(); * @trigger peerUpdated + * @since 0.4.0 */ Skyway.prototype.enableVideo = function() { - var hasVideoTracks = false; - var videoTrackActive = false; - for (var stream in this._user.streams) { - if (this._user.streams.hasOwnProperty(stream)) { - var tracks = this._user.streams[stream].getVideoTracks(); - for (var track in tracks) { - if (tracks.hasOwnProperty(track)) { - tracks[track].enabled = true; - hasVideoTracks = true; - } - } - videoTracksActive = this._user.streams[stream].active; - } - } - this._handleAV('video', true, (videoTracksActive && hasVideoTracks)); + this._handleAV('video', true); }; /** - * Disable Webcam Video. If Webcam Video is not enabled from the - * beginning, there is no effect. + * Disable webcam video. + * - If webcam is not enabled from the beginning, there is no effect. * @method disableVideo * @example * SkywayDemo.disableVideo(); * @trigger peerUpdated + * @since 0.4.0 */ Skyway.prototype.disableVideo = function() { - for (var stream in this._user.streams) { - if (this._user.streams.hasOwnProperty(stream)) { - var tracks = this._user.streams[stream].getVideoTracks(); - for (var track in tracks) { - if (tracks.hasOwnProperty(track)) { - tracks[track].enabled = false; - } - } - } - } this._handleAV('video', false); }; /** - * Parse Stream settings + * Parse stream settings * @method _parseStreamSettings - * @param {JSON} options + * @param {JSON} options Optional. Media Constraints. + * @param {JSON} options.user Optional. User custom data. + * @param {Boolean|JSON} options.audio This call requires audio + * @param {Boolean} options.audio.stereo Enabled stereo or not + * @param {Boolean|JSON} options.video This call requires video + * @param {JSON} options.video.resolution [Rel: Skyway.VIDEO_RESOLUTION] + * @param {Integer} options.video.resolution.width Video width + * @param {Integer} options.video.resolution.height Video height + * @param {Integer} options.video.frameRate Mininum frameRate of Video + * @param {String} options.bandwidth Bandwidth settings + * @param {String} options.bandwidth.audio Audio Bandwidth + * @param {String} options.bandwidth.video Video Bandwidth + * @param {String} options.bandwidth.data Data Bandwidth * @private + * @since 0.4.0 */ Skyway.prototype._parseStreamSettings = function(options) { options = options || {}; + this._user.info = this._user.info || {}; + this._user.info.settings = this._user.info.settings || {}; + this._user.info.mediaStatus = this._user.info.mediaStatus || {}; + // Set User + this._user.info.userData = options.user || this._user.info.userData; // Set Bandwidth - console.info(JSON.stringify(options)); - console.info(JSON.stringify(this._user)); this._streamSettings.bandwidth = options.bandwidth || this._streamSettings.bandwidth || {}; - // Set user stream settings - this._user.info = this._user.info || {}; - this._user.info.settings = this._user.info.settings || {}; this._user.info.settings.bandwidth = options.bandwidth || this._user.info.settings.bandwidth || {}; + // Set audio settings this._user.info.settings.audio = (typeof options.audio === 'boolean' || typeof options.audio === 'object') ? options.audio : - (this._user.info.settings.audio || false); + (this._streamSettings.audio || false); + this._user.info.mediaStatus.audioMuted = (options.audio) ? + ((typeof this._user.info.mediaStatus.audioMuted === 'boolean') ? + this._user.info.mediaStatus.audioMuted : !options.audio) : true; + console.info(this._user.info.mediaStatus.audioMuted); + // Set video settings this._user.info.settings.video = (typeof options.video === 'boolean' || typeof options.video === 'object') ? options.video : - (this._user.info.settings.video || false); + (this._streamSettings.video || false); // Set user media status options - this._user.info.mediaStatus = this._user.info.mediaStatus || {}; - this._user.info.mediaStatus.audioMuted = (options.audio) ? - ((typeof this._user.info.mediaStatus.audioMuted === 'boolean') ? - this._user.info.mediaStatus.audioMuted : false) : true; - this._user.info.mediaStatus.audioMuted = (options.video) ? + this._user.info.mediaStatus.videoMuted = (options.video) ? ((typeof this._user.info.mediaStatus.videoMuted === 'boolean') ? - this._user.info.mediaStatus.videoMuted : false) : true; - console.info(JSON.stringify(this._user)); + this._user.info.mediaStatus.videoMuted : !options.video) : true; + + console.dir(this._user.info); + + if (!options.video && !options.audio) { + return; + } + // If undefined, at least set to boolean + options.video = options.video || false; + options.audio = options.audio || false; + // Set Video if (typeof options.video === 'object') { if (typeof options.video.resolution === 'object') { @@ -10827,9 +11154,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { minWidth: width, minHeight: height }, - optional: [{ - minFrameRate: frameRate - }] + optional: [{ minFrameRate: frameRate }] }; } } @@ -10848,9 +11173,11 @@ if (webrtcDetectedBrowser.mozWebRTC) { /** * User to join the room. - * You may call {{#crossLink "Skyway/getUserMedia:method"}}getUserMedia(){{/crossLink}} - * first if you want to get - * MediaStream and joining Room seperately. + * - You may call {{#crossLink "Skyway/getUserMedia:method"}} + * getUserMedia(){{/crossLink}} first if you want to get + * MediaStream and joining Room seperately. + * - If joinRoom() parameters is empty, it simply uses + * any previous media or user data settings. * @method joinRoom * @param {String} room Room to join * @param {JSON} options Optional. Media Constraints. @@ -10863,17 +11190,20 @@ if (webrtcDetectedBrowser.mozWebRTC) { * @param {Integer} options.video.resolution.height Video height * @param {Integer} options.video.frameRate Mininum frameRate of Video * @param {String} options.bandwidth Bandwidth settings - * @param {String} options.bandwidth.audio Audio Bandwidth - * @param {String} options.bandwidth.video Video Bandwidth - * @param {String} options.bandwidth.data Data Bandwidth + * @param {Integer} options.bandwidth.audio Audio Bandwidth + * @param {Integer} options.bandwidth.video Video Bandwidth + * @param {Integer} options.bandwidth.data Data Bandwidth * @example * // To just join the default room without any video or audio + * // Note that calling joinRoom without any parameters + * // Still sends any available existing MediaStreams allowed. + * // See Examples 2, 3, 4 and 5 etc to prevent video or audio stream * SkywayDemo.joinRoom(); * * // To just join the default room with bandwidth settings * SkywayDemo.joinRoom({ - * bandwidth: { - * data: 14440 + * 'bandwidth': { + * 'data': 14440 * } * }); * @@ -10897,7 +11227,7 @@ if (webrtcDetectedBrowser.mozWebRTC) { * SkywayDemo.joinRoom('room', { * 'audio' : true, * 'video' : { - * 'res' : { + * 'resolution' : { * 'width' : 640, * 'height' : 320 * } @@ -10906,9 +11236,9 @@ if (webrtcDetectedBrowser.mozWebRTC) { * * // Example 5: Join a room with userData and settings with audio, video and bandwidth * SkwayDemo.joinRoom({ - * 'userData': { - * item1: 'My custom data', - * item2: 'Put whatever, string or JSON or array' + * 'user': { + * 'item1': 'My custom data', + * 'item2': 'Put whatever, string or JSON or array' * }, * 'audio' : { * 'stereo' : true @@ -10924,8 +11254,10 @@ if (webrtcDetectedBrowser.mozWebRTC) { * } * }); * @trigger peerJoined + * @since 0.2.0 */ Skyway.prototype.joinRoom = function(room, mediaOptions) { + console.info(mediaOptions); var self = this; if (self._in_room) { return; @@ -10961,9 +11293,9 @@ if (webrtcDetectedBrowser.mozWebRTC) { }, 500); }; if (typeof room === 'string') { - self._reinit(doJoinRoom, { + self._reinit({ room: room - }); + }, doJoinRoom); } else { mediaOptions = room; doJoinRoom(); @@ -10971,11 +11303,12 @@ if (webrtcDetectedBrowser.mozWebRTC) { }; /** - * User to leave the room + * User to leave the room. * @method leaveRoom * @example * SkywayDemo.leaveRoom(); * @trigger peerLeft, channelClose + * @since 0.1.0 */ Skyway.prototype.leaveRoom = function() { if (!this._in_room) { @@ -10988,6 +11321,6 @@ if (webrtcDetectedBrowser.mozWebRTC) { } this._in_room = false; this._closeChannel(); - this._trigger('peerLeft', this._user.sid, true); + this._trigger('peerLeft', this._user.sid, this._user.info, true); }; }).call(this); \ No newline at end of file diff --git a/publish/skyway.complete.min.js b/publish/skyway.complete.min.js index 649ec0dda..e6e9c737e 100644 --- a/publish/skyway.complete.min.js +++ b/publish/skyway.complete.min.js @@ -1,6 +1,6 @@ -/*! skywayjs - v0.3.1 - 2014-08-14 */ +/*! skywayjs - v0.4.0 - 2014-08-25 */ if(!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.io=e():"undefined"!=typeof global?global.io=e():"undefined"!=typeof self&&(self.io=e())}(function(){var define;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o0&&!this.encoding){var pack=this.packetBuffer.shift();this.packet(pack)}},Manager.prototype.cleanup=function(){for(var sub;sub=this.subs.shift();)sub.destroy();this.packetBuffer=[],this.encoding=!1,this.decoder.destroy()},Manager.prototype.close=Manager.prototype.disconnect=function(){this.skipReconnect=!0,this.engine.close()},Manager.prototype.onclose=function(reason){debug("close"),this.cleanup(),this.readyState="closed",this.emit("close",reason),this._reconnection&&!this.skipReconnect&&this.reconnect()},Manager.prototype.reconnect=function(){if(this.reconnecting)return this;var self=this;if(this.attempts++,this.attempts>this._reconnectionAttempts)debug("reconnect failed"),this.emitAll("reconnect_failed"),this.reconnecting=!1;else{var delay=this.attempts*this.reconnectionDelay();delay=Math.min(delay,this.reconnectionDelayMax()),debug("will wait %dms before reconnect attempt",delay),this.reconnecting=!0;var timer=setTimeout(function(){debug("attempting reconnect"),self.emitAll("reconnect_attempt",self.attempts),self.emitAll("reconnecting",self.attempts),self.open(function(err){err?(debug("reconnect attempt error"),self.reconnecting=!1,self.reconnect(),self.emitAll("reconnect_error",err.data)):(debug("reconnect success"),self.onreconnect())})},delay);this.subs.push({destroy:function(){clearTimeout(timer)}})}},Manager.prototype.onreconnect=function(){var attempt=this.attempts;this.attempts=0,this.reconnecting=!1,this.emitAll("reconnect",attempt)}},{"./on":4,"./socket":5,"./url":6,"component-bind":7,"component-emitter":8,debug:9,"engine.io-client":11,"object-component":37,"socket.io-parser":40}],4:[function(require,module){function on(obj,ev,fn){return obj.on(ev,fn),{destroy:function(){obj.removeListener(ev,fn)}}}module.exports=on},{}],5:[function(require,module,exports){function Socket(io,nsp){this.io=io,this.nsp=nsp,this.json=this,this.ids=0,this.acks={},this.open(),this.receiveBuffer=[],this.sendBuffer=[],this.connected=!1,this.disconnected=!0,this.subEvents()}{var parser=require("socket.io-parser"),Emitter=require("component-emitter"),toArray=require("to-array"),on=require("./on"),bind=require("component-bind"),debug=require("debug")("socket.io-client:socket"),hasBin=require("has-binary-data");require("indexof")}module.exports=exports=Socket;var events={connect:1,connect_error:1,connect_timeout:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1},emit=Emitter.prototype.emit;Emitter(Socket.prototype),Socket.prototype.subEvents=function(){var io=this.io;this.subs=[on(io,"open",bind(this,"onopen")),on(io,"packet",bind(this,"onpacket")),on(io,"close",bind(this,"onclose"))]},Socket.prototype.open=Socket.prototype.connect=function(){return this.connected?this:(this.io.open(),"open"==this.io.readyState&&this.onopen(),this)},Socket.prototype.send=function(){var args=toArray(arguments);return args.unshift("message"),this.emit.apply(this,args),this},Socket.prototype.emit=function(ev){if(events.hasOwnProperty(ev))return emit.apply(this,arguments),this;var args=toArray(arguments),parserType=parser.EVENT;hasBin(args)&&(parserType=parser.BINARY_EVENT);var packet={type:parserType,data:args};return"function"==typeof args[args.length-1]&&(debug("emitting packet with ack id %d",this.ids),this.acks[this.ids]=args.pop(),packet.id=this.ids++),this.connected?this.packet(packet):this.sendBuffer.push(packet),this},Socket.prototype.packet=function(packet){packet.nsp=this.nsp,this.io.packet(packet)},Socket.prototype.onopen=function(){debug("transport is open - connecting"),"/"!=this.nsp&&this.packet({type:parser.CONNECT})},Socket.prototype.onclose=function(reason){debug("close (%s)",reason),this.connected=!1,this.disconnected=!0,this.emit("disconnect",reason)},Socket.prototype.onpacket=function(packet){if(packet.nsp==this.nsp)switch(packet.type){case parser.CONNECT:this.onconnect();break;case parser.EVENT:this.onevent(packet);break;case parser.BINARY_EVENT:this.onevent(packet);break;case parser.ACK:this.onack(packet);break;case parser.BINARY_ACK:this.onack(packet);break;case parser.DISCONNECT:this.ondisconnect();break;case parser.ERROR:this.emit("error",packet.data)}},Socket.prototype.onevent=function(packet){var args=packet.data||[];debug("emitting event %j",args),null!=packet.id&&(debug("attaching ack callback to event"),args.push(this.ack(packet.id))),this.connected?emit.apply(this,args):this.receiveBuffer.push(args)},Socket.prototype.ack=function(id){var self=this,sent=!1;return function(){if(!sent){sent=!0;var args=toArray(arguments);debug("sending ack %j",args);var type=hasBin(args)?parser.BINARY_ACK:parser.ACK;self.packet({type:type,id:id,data:args})}}},Socket.prototype.onack=function(packet){debug("calling ack %s with %j",packet.id,packet.data);var fn=this.acks[packet.id];fn.apply(this,packet.data),delete this.acks[packet.id]},Socket.prototype.onconnect=function(){this.connected=!0,this.disconnected=!1,this.emit("connect"),this.emitBuffered()},Socket.prototype.emitBuffered=function(){var i;for(i=0;ii;++i)callbacks[i].apply(this,args)}return this},Emitter.prototype.listeners=function(event){return this._callbacks=this._callbacks||{},this._callbacks[event]||[]},Emitter.prototype.hasListeners=function(event){return!!this.listeners(event).length}},{}],9:[function(require,module){function debug(name){return debug.enabled(name)?function(fmt){fmt=coerce(fmt);var curr=new Date,ms=curr-(debug[name]||curr);debug[name]=curr,fmt=name+" "+fmt+" +"+debug.humanize(ms),window.console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}:function(){}}function coerce(val){return val instanceof Error?val.stack||val.message:val}module.exports=debug,debug.names=[],debug.skips=[],debug.enable=function(name){try{localStorage.debug=name}catch(e){}for(var split=(name||"").split(/[\s,]+/),len=split.length,i=0;len>i;i++)name=split[i].replace("*",".*?"),"-"===name[0]?debug.skips.push(new RegExp("^"+name.substr(1)+"$")):debug.names.push(new RegExp("^"+name+"$"))},debug.disable=function(){debug.enable("")},debug.humanize=function(ms){var sec=1e3,min=6e4,hour=60*min;return ms>=hour?(ms/hour).toFixed(1)+"h":ms>=min?(ms/min).toFixed(1)+"m":ms>=sec?(ms/sec|0)+"s":ms+"ms"},debug.enabled=function(name){for(var i=0,len=debug.skips.length;len>i;i++)if(debug.skips[i].test(name))return!1;for(var i=0,len=debug.names.length;len>i;i++)if(debug.names[i].test(name))return!0;return!1};try{window.localStorage&&debug.enable(localStorage.debug)}catch(e){}},{}],10:[function(require,module){function Emitter(obj){return obj?mixin(obj):void 0}function mixin(obj){for(var key in Emitter.prototype)obj[key]=Emitter.prototype[key];return obj}var index=require("indexof");module.exports=Emitter,Emitter.prototype.on=function(event,fn){return this._callbacks=this._callbacks||{},(this._callbacks[event]=this._callbacks[event]||[]).push(fn),this},Emitter.prototype.once=function(event,fn){function on(){self.off(event,on),fn.apply(this,arguments)}var self=this;return this._callbacks=this._callbacks||{},fn._off=on,this.on(event,on),this},Emitter.prototype.off=Emitter.prototype.removeListener=Emitter.prototype.removeAllListeners=function(event,fn){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var callbacks=this._callbacks[event];if(!callbacks)return this;if(1==arguments.length)return delete this._callbacks[event],this;var i=index(callbacks,fn._off||fn);return~i&&callbacks.splice(i,1),this},Emitter.prototype.emit=function(event){this._callbacks=this._callbacks||{};var args=[].slice.call(arguments,1),callbacks=this._callbacks[event];if(callbacks){callbacks=callbacks.slice(0);for(var i=0,len=callbacks.length;len>i;++i)callbacks[i].apply(this,args)}return this},Emitter.prototype.listeners=function(event){return this._callbacks=this._callbacks||{},this._callbacks[event]||[]},Emitter.prototype.hasListeners=function(event){return!!this.listeners(event).length}},{indexof:36}],11:[function(require,module){module.exports=require("./lib/")},{"./lib/":12}],12:[function(require,module){module.exports=require("./socket"),module.exports.parser=require("engine.io-parser")},{"./socket":13,"engine.io-parser":22}],13:[function(require,module){function Socket(uri,opts){if(!(this instanceof Socket))return new Socket(uri,opts);if(opts=opts||{},uri&&"object"==typeof uri&&(opts=uri,uri=null),uri&&(uri=parseuri(uri),opts.host=uri.host,opts.secure="https"==uri.protocol||"wss"==uri.protocol,opts.port=uri.port,uri.query&&(opts.query=uri.query)),this.secure=null!=opts.secure?opts.secure:global.location&&"https:"==location.protocol,opts.host){var pieces=opts.host.split(":");opts.hostname=pieces.shift(),pieces.length&&(opts.port=pieces.pop())}this.agent=opts.agent||!1,this.hostname=opts.hostname||(global.location?location.hostname:"localhost"),this.port=opts.port||(global.location&&location.port?location.port:this.secure?443:80),this.query=opts.query||{},"string"==typeof this.query&&(this.query=parseqs.decode(this.query)),this.upgrade=!1!==opts.upgrade,this.path=(opts.path||"/engine.io").replace(/\/$/,"")+"/",this.forceJSONP=!!opts.forceJSONP,this.forceBase64=!!opts.forceBase64,this.timestampParam=opts.timestampParam||"t",this.timestampRequests=opts.timestampRequests,this.transports=opts.transports||["polling","websocket"],this.readyState="",this.writeBuffer=[],this.callbackBuffer=[],this.policyPort=opts.policyPort||843,this.rememberUpgrade=opts.rememberUpgrade||!1,this.open(),this.binaryType=null,this.onlyBinaryUpgrades=opts.onlyBinaryUpgrades}function clone(obj){var o={};for(var i in obj)obj.hasOwnProperty(i)&&(o[i]=obj[i]);return o}var global="undefined"!=typeof self?self:"undefined"!=typeof window?window:{},transports=require("./transports"),Emitter=require("component-emitter"),debug=require("debug")("engine.io-client:socket"),index=require("indexof"),parser=require("engine.io-parser"),parseuri=require("parseuri"),parsejson=require("parsejson"),parseqs=require("parseqs");module.exports=Socket,Socket.priorWebsocketSuccess=!1,Emitter(Socket.prototype),Socket.protocol=parser.protocol,Socket.Socket=Socket,Socket.Transport=require("./transport"),Socket.transports=require("./transports"),Socket.parser=require("engine.io-parser"),Socket.prototype.createTransport=function(name){debug('creating transport "%s"',name);var query=clone(this.query);query.EIO=parser.protocol,query.transport=name,this.id&&(query.sid=this.id);var transport=new transports[name]({agent:this.agent,hostname:this.hostname,port:this.port,secure:this.secure,path:this.path,query:query,forceJSONP:this.forceJSONP,forceBase64:this.forceBase64,timestampRequests:this.timestampRequests,timestampParam:this.timestampParam,policyPort:this.policyPort,socket:this});return transport},Socket.prototype.open=function(){var transport;transport=this.rememberUpgrade&&Socket.priorWebsocketSuccess&&-1!=this.transports.indexOf("websocket")?"websocket":this.transports[0],this.readyState="opening";var transport=this.createTransport(transport);transport.open(),this.setTransport(transport)},Socket.prototype.setTransport=function(transport){debug("setting transport %s",transport.name);var self=this;this.transport&&(debug("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=transport,transport.on("drain",function(){self.onDrain()}).on("packet",function(packet){self.onPacket(packet)}).on("error",function(e){self.onError(e)}).on("close",function(){self.onClose("transport close")})},Socket.prototype.probe=function(name){function onTransportOpen(){if(self.onlyBinaryUpgrades){var upgradeLosesBinary=!this.supportsBinary&&self.transport.supportsBinary;failed=failed||upgradeLosesBinary}failed||(debug('probe transport "%s" opened',name),transport.send([{type:"ping",data:"probe"}]),transport.once("packet",function(msg){if(!failed)if("pong"==msg.type&&"probe"==msg.data)debug('probe transport "%s" pong',name),self.upgrading=!0,self.emit("upgrading",transport),Socket.priorWebsocketSuccess="websocket"==transport.name,debug('pausing current transport "%s"',self.transport.name),self.transport.pause(function(){failed||"closed"!=self.readyState&&"closing"!=self.readyState&&(debug("changing transport and sending upgrade packet"),cleanup(),self.setTransport(transport),transport.send([{type:"upgrade"}]),self.emit("upgrade",transport),transport=null,self.upgrading=!1,self.flush())});else{debug('probe transport "%s" failed',name);var err=new Error("probe error");err.transport=transport.name,self.emit("upgradeError",err)}}))}function freezeTransport(){failed||(failed=!0,cleanup(),transport.close(),transport=null)}function onerror(err){var error=new Error("probe error: "+err);error.transport=transport.name,freezeTransport(),debug('probe transport "%s" failed because of error: %s',name,err),self.emit("upgradeError",error)}function onTransportClose(){onerror("transport closed")}function onclose(){onerror("socket closed")}function onupgrade(to){transport&&to.name!=transport.name&&(debug('"%s" works - aborting "%s"',to.name,transport.name),freezeTransport())}function cleanup(){transport.removeListener("open",onTransportOpen),transport.removeListener("error",onerror),transport.removeListener("close",onTransportClose),self.removeListener("close",onclose),self.removeListener("upgrading",onupgrade)}debug('probing transport "%s"',name);var transport=this.createTransport(name,{probe:1}),failed=!1,self=this;Socket.priorWebsocketSuccess=!1,transport.once("open",onTransportOpen),transport.once("error",onerror),transport.once("close",onTransportClose),this.once("close",onclose),this.once("upgrading",onupgrade),transport.open()},Socket.prototype.onOpen=function(){if(debug("socket open"),this.readyState="open",Socket.priorWebsocketSuccess="websocket"==this.transport.name,this.emit("open"),this.flush(),"open"==this.readyState&&this.upgrade&&this.transport.pause){debug("starting upgrade probes");for(var i=0,l=this.upgrades.length;l>i;i++)this.probe(this.upgrades[i])}},Socket.prototype.onPacket=function(packet){if("opening"==this.readyState||"open"==this.readyState)switch(debug('socket receive: type "%s", data "%s"',packet.type,packet.data),this.emit("packet",packet),this.emit("heartbeat"),packet.type){case"open":this.onHandshake(parsejson(packet.data));break;case"pong":this.setPing();break;case"error":var err=new Error("server error");err.code=packet.data,this.emit("error",err);break;case"message":this.emit("data",packet.data),this.emit("message",packet.data)}else debug('packet received with socket readyState "%s"',this.readyState)},Socket.prototype.onHandshake=function(data){this.emit("handshake",data),this.id=data.sid,this.transport.query.sid=data.sid,this.upgrades=this.filterUpgrades(data.upgrades),this.pingInterval=data.pingInterval,this.pingTimeout=data.pingTimeout,this.onOpen(),"closed"!=this.readyState&&(this.setPing(),this.removeListener("heartbeat",this.onHeartbeat),this.on("heartbeat",this.onHeartbeat))},Socket.prototype.onHeartbeat=function(timeout){clearTimeout(this.pingTimeoutTimer);var self=this;self.pingTimeoutTimer=setTimeout(function(){"closed"!=self.readyState&&self.onClose("ping timeout")},timeout||self.pingInterval+self.pingTimeout)},Socket.prototype.setPing=function(){var self=this;clearTimeout(self.pingIntervalTimer),self.pingIntervalTimer=setTimeout(function(){debug("writing ping packet - expecting pong within %sms",self.pingTimeout),self.ping(),self.onHeartbeat(self.pingTimeout)},self.pingInterval)},Socket.prototype.ping=function(){this.sendPacket("ping")},Socket.prototype.onDrain=function(){for(var i=0;ii;i++)~index(this.transports,upgrades[i])&&filteredUpgrades.push(upgrades[i]);return filteredUpgrades}},{"./transport":14,"./transports":15,"component-emitter":8,debug:9,"engine.io-parser":22,indexof:36,parsejson:29,parseqs:30,parseuri:38}],14:[function(require,module){function Transport(opts){this.path=opts.path,this.hostname=opts.hostname,this.port=opts.port,this.secure=opts.secure,this.query=opts.query,this.timestampParam=opts.timestampParam,this.timestampRequests=opts.timestampRequests,this.readyState="",this.agent=opts.agent||!1,this.socket=opts.socket}var parser=require("engine.io-parser"),Emitter=require("component-emitter");module.exports=Transport,Emitter(Transport.prototype),Transport.timestamps=0,Transport.prototype.onError=function(msg,desc){var err=new Error(msg);return err.type="TransportError",err.description=desc,this.emit("error",err),this},Transport.prototype.open=function(){return("closed"==this.readyState||""==this.readyState)&&(this.readyState="opening",this.doOpen()),this},Transport.prototype.close=function(){return("opening"==this.readyState||"open"==this.readyState)&&(this.doClose(),this.onClose()),this},Transport.prototype.send=function(packets){if("open"!=this.readyState)throw new Error("Transport not open");this.write(packets)},Transport.prototype.onOpen=function(){this.readyState="open",this.writable=!0,this.emit("open")},Transport.prototype.onData=function(data){try{var packet=parser.decodePacket(data,this.socket.binaryType);this.onPacket(packet)}catch(e){e.data=data,this.onError("parser decode error",e)}},Transport.prototype.onPacket=function(packet){this.emit("packet",packet)},Transport.prototype.onClose=function(){this.readyState="closed",this.emit("close")}},{"component-emitter":8,"engine.io-parser":22}],15:[function(require,module,exports){function polling(opts){var xhr,xd=!1;if(global.location){var isSSL="https:"==location.protocol,port=location.port;port||(port=isSSL?443:80),xd=opts.hostname!=location.hostname||port!=opts.port}return opts.xdomain=xd,xhr=new XMLHttpRequest(opts),"open"in xhr&&!opts.forceJSONP?new XHR(opts):new JSONP(opts)}var global="undefined"!=typeof self?self:"undefined"!=typeof window?window:{},XMLHttpRequest=require("xmlhttprequest"),XHR=require("./polling-xhr"),JSONP=require("./polling-jsonp"),websocket=require("./websocket");exports.polling=polling,exports.websocket=websocket},{"./polling-jsonp":16,"./polling-xhr":17,"./websocket":19,xmlhttprequest:20}],16:[function(require,module){function empty(){}function JSONPPolling(opts){Polling.call(this,opts),this.query=this.query||{},callbacks||(global.___eio||(global.___eio=[]),callbacks=global.___eio),this.index=callbacks.length;var self=this;callbacks.push(function(msg){self.onData(msg)}),this.query.j=this.index,global.document&&global.addEventListener&&global.addEventListener("beforeunload",function(){self.script&&(self.script.onerror=empty)})}var global="undefined"!=typeof self?self:"undefined"!=typeof window?window:{},Polling=require("./polling"),inherit=require("component-inherit");module.exports=JSONPPolling;var callbacks,rNewline=/\n/g,rEscapedNewline=/\\n/g;inherit(JSONPPolling,Polling),JSONPPolling.prototype.supportsBinary=!1,JSONPPolling.prototype.doClose=function(){this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),this.form&&(this.form.parentNode.removeChild(this.form),this.form=null),Polling.prototype.doClose.call(this)},JSONPPolling.prototype.doPoll=function(){var self=this,script=document.createElement("script");this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),script.async=!0,script.src=this.uri(),script.onerror=function(e){self.onError("jsonp poll error",e)};var insertAt=document.getElementsByTagName("script")[0];insertAt.parentNode.insertBefore(script,insertAt),this.script=script;var isUAgecko="undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent);isUAgecko&&setTimeout(function(){var iframe=document.createElement("iframe");document.body.appendChild(iframe),document.body.removeChild(iframe)},100)},JSONPPolling.prototype.doWrite=function(data,fn){function complete(){initIframe(),fn()}function initIframe(){if(self.iframe)try{self.form.removeChild(self.iframe)}catch(e){self.onError("jsonp polling iframe removal error",e)}try{var html='