Skip to content

Commit

Permalink
Merge pull request #282 from skyway/staging
Browse files Browse the repository at this point in the history
Release v4.1.0
  • Loading branch information
y-i committed Dec 7, 2020
2 parents a2d5211 + e6ee5d6 commit b397df2
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 12 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,17 @@

## release note

## [v4.1.0](https://github.com/skyway/skyway-js-sdk/releases/tag/v4.1.0) - 2020-12-07

### Added

- Added APIs to get RTCPeerConnections used in SFU room and Mesh room. ([#279](https://github.com/skyway/skyway-js-sdk/pull/279))

### Fixed

- Fixed a problem that `npm install` fails on node v15.1.0 or later. ([#278](https://github.com/skyway/skyway-js-sdk/pull/278))
- Fixed a bug that it occurs RTCError on closing DataConnection. ([#277](https://github.com/skyway/skyway-js-sdk/pull/277))

## [v4.0.0](https://github.com/skyway/skyway-js-sdk/releases/tag/v4.0.0) - 2020-11-09

### Breaking Changes
Expand Down
6 changes: 3 additions & 3 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "skyway-js",
"version": "4.0.0",
"version": "4.1.0",
"description": "The official JavaScript SDK for SkyWay",
"main": "dist/skyway.js",
"module": "src/peer.js",
Expand Down Expand Up @@ -50,14 +50,14 @@
"webpack-cli": "^3.3.6"
},
"dependencies": {
"@jitsi/sdp-interop": "^0.1.13",
"@types/node": "^12.6.8",
"detect-browser": "^4.6.0",
"enum": "git+https://github.com/eastandwest/enum.git#react-native",
"enum": "^3.0.4",
"events": "^3.0.0",
"js-binarypack": "0.0.9",
"object-sizeof": "^1.4.0",
"query-string": "^6.8.2",
"@jitsi/sdp-interop": "^0.1.13",
"sdp-transform": "^2.11.0",
"socket.io-client": "^2.2.0",
"socket.io-parser": "~3.3.0"
Expand Down
26 changes: 24 additions & 2 deletions src/peer/dataConnection.js
Expand Up @@ -280,9 +280,31 @@ class DataConnection extends Connection {
* @deprecated Default value of forceClose may be changed to true from a future version.
*/
close(forceClose) {
super.close(forceClose);
const cleanup = forceClose => {
super.close(forceClose);
this._isOnOpenCalled = false;
};

this._isOnOpenCalled = false;
if (!this._dc) {
cleanup(forceClose);
return;
}

// Close RTCPeerConnection after RTCDataChannel is closed.
this._dc.onclose = () => {
logger.log('DataChannel closed for:', this.id);
cleanup(forceClose);
};

if (this._dc.readyState === 'closing') {
// Do nothing here because the onclose event fires after RTCDataChannel is closed.
return;
} else if (this._dc.readyState === 'closed') {
// Close RTCPeerConnection if the RTCDataChannel was already closed.
cleanup(forceClose);
} else {
this._dc.close();
}
}

/**
Expand Down
14 changes: 14 additions & 0 deletions src/peer/meshRoom.js
Expand Up @@ -295,6 +295,20 @@ class MeshRoom extends Room {
}
}

/**
* Get all of each peer's RTCPeerConnection.
*/
getPeerConnections() {
const peerConnections = {};
for (const [peerId, [connection]] of Object.entries(this.connections)) {
const pc = connection.getPeerConnection();
if (pc) {
peerConnections[peerId] = pc;
}
}
return peerConnections;
}

/**
* Append a connection to peer's array of connections, stored in room.connections.
* @param {string} peerId - User's peerID.
Expand Down
10 changes: 10 additions & 0 deletions src/peer/sfuRoom.js
Expand Up @@ -300,6 +300,16 @@ class SFURoom extends Room {
}
}

/**
* Get a RTCPeerConnection.
*/
getPeerConnection() {
if (!this._connectionStarted) {
return null;
}
return this._negotiator._pc;
}

/**
* Events the SFURoom class can emit.
* @type {Enum}
Expand Down
65 changes: 58 additions & 7 deletions tests/peer/dataConnection.js
Expand Up @@ -150,6 +150,7 @@ describe('DataConnection', () => {
dc._negotiator.emit(Negotiator.EVENTS.dcCreated.key, {});

const spy = sinon.spy(dc, 'close');
dc._dc.readyState = 'closed';
dc._dc.onclose();
assert(spy.calledOnce);

Expand Down Expand Up @@ -265,10 +266,12 @@ describe('DataConnection', () => {
dc._negotiator.emit(Negotiator.EVENTS.offerCreated.key, offer);
});

it("should cleanup the connection on negotiator 'iceConnectionDisconnected' event", () => {
it("should cleanup the connection on negotiator 'iceConnectionFailed' event", () => {
dc.open = true;
const spy = sinon.spy(dc, 'close');

dc._negotiator.emit(Negotiator.EVENTS.dcCreated.key, {});
dc._dc.readyState = 'closed';
dc._negotiator.emit(Negotiator.EVENTS.iceConnectionFailed.key);

assert(spy.calledOnce);
Expand Down Expand Up @@ -681,21 +684,69 @@ describe('DataConnection', () => {
});
});

describe('Cleanup', () => {
it('should close the socket and call the negotiator to cleanup on close()', () => {
describe('close', () => {
it('should close the socket and call the negotiator to cleanup on close() when _dc is none', () => {
const dc = new DataConnection('remoteId', {});

// Force to be open
dc.open = true;

const spy = sinon.spy(dc, 'close');
dc.close();
assert.equal(dc.open, false);
assert(cleanupSpy.called);
});

it('should dc.onclose be overridden and do nothing when the readyState of _dc is closing', () => {
const dc = new DataConnection('remoteId', {});
dc._negotiator.emit(Negotiator.EVENTS.dcCreated.key, {
close: sinon.stub(),
});
dc._dc.onopen();
dc._dc.readyState = 'closing';
const dummyOnClose = { hoge: 'hoo' };
dc._dc.onclose = dummyOnClose;

dc.close();
assert(dc);
assert(spy.calledOnce);

assert.notEqual(dc._dc.onclose, dummyOnClose);
assert.equal(dc.open, true);
assert.equal(dc._isOnOpenCalled, true);
assert(dc._dc.close.notCalled);
});

it('should super.close be called and _isOnOpencalled should be false when the readyState of _dc is closed', () => {
const dc = new DataConnection('remoteId', {});
dc._negotiator.emit(Negotiator.EVENTS.dcCreated.key, {});
dc._dc.onopen();
dc._dc.readyState = 'closed';

dc.close();

assert.equal(dc.open, false);
assert.equal(dc._isOnOpenCalled, false);
});

assert(cleanupSpy.called);
it('should _dc.onclose has been overwritten and _dc.close() has been called, then super.close has been called and isonopencalled has been set to false when the readyState of _dc is open or connecting', () => {
for (const readyState of ['open', 'connecting']) {
const dc = new DataConnection('remoteId', {});
dc._negotiator.emit(Negotiator.EVENTS.dcCreated.key, {
close: sinon.stub(),
});
dc._dc.onopen();
dc._dc.readyState = readyState;
const dummyOnClose = { hoge: 'hoo' };
dc._dc.onclose = dummyOnClose;

dc.close();

assert.notEqual(dc._dc.onclose, dummyOnClose);
assert(dc._dc.close.calledOnce);

dc._dc.onclose();

assert.equal(dc.open, false);
assert.equal(dc._isOnOpenCalled, false);
}
});
});
});
28 changes: 28 additions & 0 deletions tests/peer/meshRoom.js
Expand Up @@ -21,6 +21,7 @@ describe('MeshRoom', () => {
let closeSpy;
let answerSpy;
let replaceStreamSpy;
let getPeerConnectionStub;

beforeEach(() => {
mcStub = sinon.stub();
Expand All @@ -29,6 +30,7 @@ describe('MeshRoom', () => {
closeSpy = sinon.spy();
answerSpy = sinon.spy();
replaceStreamSpy = sinon.spy();
getPeerConnectionStub = sinon.stub();

mcStub.returns({
type: 'media',
Expand All @@ -37,6 +39,7 @@ describe('MeshRoom', () => {
close: closeSpy,
answer: answerSpy,
replaceStream: replaceStreamSpy,
getPeerConnection: getPeerConnectionStub,
});
// hoist statics
mcStub.EVENTS = MediaConnection.EVENTS;
Expand Down Expand Up @@ -64,6 +67,7 @@ describe('MeshRoom', () => {
closeSpy.resetHistory();
answerSpy.resetHistory();
replaceStreamSpy.resetHistory();
getPeerConnectionStub.resetHistory();
});

describe('Constructor', () => {
Expand Down Expand Up @@ -642,6 +646,30 @@ describe('MeshRoom', () => {
});
});

describe('getPeerConnections', () => {
it('should return all of each RTCPeerConnection', () => {
const peers = ['peerId1', 'peerId2'];
meshRoom.makeMediaConnections(peers);
getPeerConnectionStub.onCall(0).returns('peerId1_pc');
getPeerConnectionStub.onCall(1).returns('peerId2_pc');

const pcs = meshRoom.getPeerConnections();

assert.deepStrictEqual(pcs, {
peerId1: 'peerId1_pc',
peerId2: 'peerId2_pc',
});
});

it('should return an empty object if meshRoom.connections are empty', () => {
meshRoom.connections = {};

const pcs = meshRoom.getPeerConnections();

assert.deepStrictEqual(pcs, {});
});
});

describe('_addConnection', () => {
it('should add the connection to meshRoom.connections', () => {
const connection1 = {};
Expand Down
19 changes: 19 additions & 0 deletions tests/peer/sfuRoom.js
Expand Up @@ -796,6 +796,25 @@ describe('SFURoom', () => {
});
});

describe('getPeerConnection', () => {
it('should return null if _connectionStarted is not true', () => {
sfuRoom._connectionStarted = false;

const pc = sfuRoom.getPeerConnection();

assert.equal(pc, null);
});

it('should return RTCPeerConnection object if _connectionStarted is true', () => {
sfuRoom._negotiator._pc = {};
sfuRoom._connectionStarted = true;

const pc = sfuRoom.getPeerConnection();

assert.deepEqual(pc, {});
});
});

/** Inherited from Room */
describe('handleData', () => {
it('should emit a data event', done => {
Expand Down

0 comments on commit b397df2

Please sign in to comment.