Skip to content
This repository has been archived by the owner on Nov 25, 2022. It is now read-only.

Add error/completion handlers for sessions, publishers, subscribers #10

Merged
merged 5 commits into from
Mar 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion example/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class App extends Component {
super(props);

this.state = {
error: null,
connected: false
};

Expand All @@ -28,14 +29,20 @@ class App extends Component {
OT.registerScreenSharingExtension('chrome', config.CHROME_EXTENSION_ID, 2);
}

onError = (err) => {
this.setState({ error: `Failed to connect: ${err.message}` });
}

render() {
return (
<OTSession
apiKey={this.props.apiKey}
sessionId={this.props.sessionId}
token={this.props.token}
eventHandlers={this.sessionEvents}
onError={this.onError}
>
{this.state.error ? <div>{this.state.error}</div> : null}
<ConnectionStatus connected={this.state.connected} />
<Publisher />
<OTStreams>
Expand All @@ -46,4 +53,4 @@ class App extends Component {
}
}

export default preloadScript(App);
export default preloadScript(App);
7 changes: 7 additions & 0 deletions example/components/Publisher.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default class Publisher extends Component {
super(props);

this.state = {
error: null,
audio: true,
video: true,
videoSource: 'camera'
Expand All @@ -27,16 +28,22 @@ export default class Publisher extends Component {
this.setState({ videoSource });
}

onError = (err) => {
this.setState({ error: `Failed to publish: ${err.message}` });
}

render() {
return (
<div>
{this.state.error ? <div>{this.state.error}</div> : null}
<OTPublisher
session={this.props.session}
properties={{
publishAudio: this.state.audio,
publishVideo: this.state.video,
videoSource: this.state.videoSource === 'screen' ? 'screen' : undefined
}}
onError={this.onError}
/>
<RadioButtons
buttons={[
Expand Down
7 changes: 7 additions & 0 deletions example/components/Subscriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default class Subscriber extends Component {
super(props);

this.state = {
error: null,
audio: true,
video: true
};
Expand All @@ -21,16 +22,22 @@ export default class Subscriber extends Component {
this.setState({ video });
}

onError = (err) => {
this.setState({ error: `Failed to subscribe: ${err.message}` });
}

render() {
return (
<div>
{this.state.error ? <div>{this.state.error}</div> : null}
<OTSubscriber
session={this.props.session}
stream={this.props.stream}
properties={{
subscribeToAudio: this.state.audio,
subscribeToVideo: this.state.video
}}
onError={this.onError}
/>
<CheckBox
label="Subscribe to Audio"
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
"author": "Aiham Hammami <aiham@aiham.net>",
"license": "MIT",
"dependencies": {
"lodash": "^4.13.1",
"react": "^15.1.0",
"react-display-name": "^0.2.0",
"scriptjs": "^2.5.8"
"scriptjs": "^2.5.8",
"uuid": "^3.0.1"
},
"devDependencies": {
"babel-cli": "^6.18.0",
Expand All @@ -53,7 +55,6 @@
"karma-firefox-launcher": "^1.0.0",
"karma-jasmine": "^1.1.0",
"karma-spec-reporter": "^0.0.26",
"lodash": "^4.13.1",
"opentok-test-scripts": "^3.2.1",
"react-addons-test-utils": "^15.4.1",
"react-dom": "^15.1.0",
Expand Down
48 changes: 46 additions & 2 deletions src/OTPublisher.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, { Component, PropTypes } from 'react';
import once from 'lodash/once';
import uuid from 'uuid';

export default class OTPublisher extends Component {
constructor(props) {
Expand Down Expand Up @@ -58,6 +60,8 @@ export default class OTPublisher extends Component {
}

destroyPublisher(session = this.props.session) {
delete this.publisherId;

if (this.state.publisher) {
this.state.publisher.off('streamCreated', this.streamCreatedHandler);

Expand All @@ -78,9 +82,18 @@ export default class OTPublisher extends Component {
}

publishToSession(publisher) {
const { publisherId } = this;

this.props.session.publish(publisher, (err) => {
if (publisherId !== this.publisherId) {
// Either this publisher has been recreated or the
// component unmounted so don't invoke any callbacks
return;
}
if (err) {
console.error('Failed to publish to OpenTok session:', err);
this.errorHandler(err);
} else if (typeof this.props.onPublish === 'function') {
this.props.onPublish();
}
});
}
Expand All @@ -101,7 +114,32 @@ export default class OTPublisher extends Component {
this.node.appendChild(container);
}

const publisher = OT.initPublisher(container, properties);
this.publisherId = uuid();
const { publisherId } = this;

this.errorHandler = once((err) => {
if (publisherId !== this.publisherId) {
// Either this publisher has been recreated or the
// component unmounted so don't invoke any callbacks
return;
}
if (typeof this.props.onError === 'function') {
this.props.onError(err);
}
});

const publisher = OT.initPublisher(container, properties, (err) => {
if (publisherId !== this.publisherId) {
// Either this publisher has been recreated or the
// component unmounted so don't invoke any callbacks
return;
}
if (err) {
this.errorHandler(err);
} else if (typeof this.props.onInit === 'function') {
this.props.onInit();
}
});
publisher.on('streamCreated', this.streamCreatedHandler);

if (
Expand Down Expand Up @@ -145,10 +183,16 @@ OTPublisher.propTypes = {
}),
properties: PropTypes.object, // eslint-disable-line react/forbid-prop-types
eventHandlers: PropTypes.objectOf(PropTypes.func),
onInit: PropTypes.func,
onPublish: PropTypes.func,
onError: PropTypes.func,
};

OTPublisher.defaultProps = {
session: null,
properties: {},
eventHandlers: null,
onInit: null,
onPublish: null,
onError: null,
};
6 changes: 6 additions & 0 deletions src/OTSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export default class OTSession extends Component {
sessionId: this.props.sessionId,
token: this.props.token,
onStreamsUpdated: (streams) => { this.setState({ streams }); },
onConnect: this.props.onConnect,
onError: this.props.onError,
});

if (
Expand Down Expand Up @@ -65,8 +67,12 @@ OTSession.propTypes = {
sessionId: PropTypes.string.isRequired,
token: PropTypes.string.isRequired,
eventHandlers: PropTypes.objectOf(PropTypes.func),
onConnect: PropTypes.func,
onError: PropTypes.func,
};

OTSession.defaultProps = {
eventHandlers: null,
onConnect: null,
onError: null,
};
21 changes: 19 additions & 2 deletions src/OTSubscriber.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from 'react';
import uuid from 'uuid';

export default class OTSubscriber extends Component {
constructor(props) {
Expand Down Expand Up @@ -59,13 +60,23 @@ export default class OTSubscriber extends Component {
container.setAttribute('class', 'OTSubscriberContainer');
this.node.appendChild(container);

this.subscriberId = uuid();
const { subscriberId } = this;

const subscriber = this.props.session.subscribe(
this.props.stream,
container,
this.props.properties,
(err) => {
if (err) {
console.error('Failed to publish to OpenTok session:', err);
if (subscriberId !== this.subscriberId) {
// Either this subscriber has been recreated or the
// component unmounted so don't invoke any callbacks
return;
}
if (err && typeof this.props.onError === 'function') {
this.props.onError(err);
} else if (!err && typeof this.props.onSubscribe === 'function') {
this.props.onSubscribe();
}
},
);
Expand All @@ -81,6 +92,8 @@ export default class OTSubscriber extends Component {
}

destroySubscriber(session = this.props.session) {
delete this.subscriberId;

if (this.state.subscriber) {
if (
this.props.eventHandlers &&
Expand Down Expand Up @@ -112,11 +125,15 @@ OTSubscriber.propTypes = {
}),
properties: PropTypes.object, // eslint-disable-line react/forbid-prop-types
eventHandlers: PropTypes.objectOf(PropTypes.func),
onSubscribe: PropTypes.func,
onError: PropTypes.func,
};

OTSubscriber.defaultProps = {
stream: null,
session: null,
properties: {},
eventHandlers: null,
onSubscribe: null,
onError: null,
};
15 changes: 14 additions & 1 deletion src/createSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export default function createSession({
sessionId,
token,
onStreamsUpdated,
onConnect,
onError,
} = {}) {
if (!apiKey) {
throw new Error('Missing apiKey');
Expand Down Expand Up @@ -41,7 +43,18 @@ export default function createSession({

let session = OT.initSession(apiKey, sessionId);
session.on(eventHandlers);
session.connect(token);
session.connect(token, (err) => {
if (!session) {
// Either this session has been disconnected or OTSession
// has been unmounted so don't invoke any callbacks
return;
}
if (err && typeof onError === 'function') {
onError(err);
} else if (!err && typeof onConnect === 'function') {
onConnect();
}
});

return {
session,
Expand Down
2 changes: 2 additions & 0 deletions test/OTPublisher.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe('OTPublisher', () => {
expect(OT.initPublisher).toHaveBeenCalledWith(
jasmine.any(HTMLDivElement),
jasmine.any(Object),
jasmine.any(Function),
);
});

Expand Down Expand Up @@ -127,6 +128,7 @@ describe('OTPublisher', () => {
expect(OT.initPublisher).toHaveBeenCalledWith(
jasmine.any(HTMLDivElement),
jasmine.any(Object),
jasmine.any(Function),
);
});

Expand Down
2 changes: 1 addition & 1 deletion test/createSession.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ describe('createSession', () => {
});

it('should call session.connect', () => {
expect(session.connect).toHaveBeenCalledWith(options.token);
expect(session.connect).toHaveBeenCalledWith(options.token, jasmine.any(Function));
});

it('should return session helper', () => {
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4054,7 +4054,7 @@ uuid@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"

uuid@^3.0.0:
uuid@^3.0.0, uuid@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"

Expand Down