blob: 68c05af81e6a9550cafbe72c1fd3228ea83a3a30 [file] [edit]
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
/* eslint no-unused-expressions: 0 */
'use strict';
import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element@0.6.2?module';
class MessagingSample extends LitElement {
constructor() {
super();
this.connected = false;
this.localMessages = '';
this.remoteMessages = '';
}
disconnect() {
this._localConnection.close();
this._remoteConnection.close();
}
async connect() {
console.log('connect!');
try {
const dataChannelParams = {ordered: true};
window.localConnection = this._localConnection = new RTCPeerConnection();
this._localConnection.addEventListener('icecandidate', async e => {
console.log('local connection ICE candidate: ', e.candidate);
await this._remoteConnection.addIceCandidate(e.candidate);
});
window.remoteConnection = this._remoteConnection = new RTCPeerConnection();
this._remoteConnection.addEventListener('icecandidate', async e => {
console.log('remote connection ICE candidate: ', e.candidate);
await this._localConnection.addIceCandidate(e.candidate);
});
window.localChannel = this._localChannel = this._localConnection
.createDataChannel('messaging-channel', dataChannelParams);
this._localChannel.binaryType = 'arraybuffer';
this._localChannel.addEventListener('open', () => {
console.log('Local channel open!');
this.connected = true;
});
this._localChannel.addEventListener('close', () => {
console.log('Local channel closed!');
this.connected = false;
});
this._localChannel.addEventListener('message', this._onLocalMessageReceived.bind(this));
this._remoteConnection.addEventListener('datachannel', this._onRemoteDataChannel.bind(this));
const initLocalOffer = async () => {
const localOffer = await this._localConnection.createOffer();
console.log(`Got local offer ${JSON.stringify(localOffer)}`);
const localDesc = this._localConnection.setLocalDescription(localOffer);
const remoteDesc = this._remoteConnection.setRemoteDescription(localOffer);
return Promise.all([localDesc, remoteDesc]);
};
const initRemoteAnswer = async () => {
const remoteAnswer = await this._remoteConnection.createAnswer();
console.log(`Got remote answer ${JSON.stringify(remoteAnswer)}`);
const localDesc = this._remoteConnection.setLocalDescription(remoteAnswer);
const remoteDesc = this._localConnection.setRemoteDescription(remoteAnswer);
return Promise.all([localDesc, remoteDesc]);
};
await initLocalOffer();
await initRemoteAnswer();
} catch (e) {
console.log(e);
}
}
_onLocalMessageReceived(event) {
console.log(`Remote message received by local: ${event.data}`);
this.localMessages += event.data + '\n';
}
_onRemoteDataChannel(event) {
console.log(`onRemoteDataChannel: ${JSON.stringify(event)}`);
window.remoteChannel = this._remoteChannel = event.channel;
this._remoteChannel.binaryType = 'arraybuffer';
this._remoteChannel.addEventListener('message', this._onRemoteMessageReceived.bind(this));
this._remoteChannel.addEventListener('close', () => {
console.log('Remote channel closed!');
this.connected = false;
});
}
_onRemoteMessageReceived(event) {
console.log(`Local message received by remote: ${event.data}`);
this.remoteMessages += event.data + '\n';
}
static get properties() {
return {
connected: {type: Boolean},
localMessages: {type: String},
remoteMessages: {type: String}
};
}
render() {
return html`<section>
<style>
@import "../../../css/main.css";
@import "main.css";
</style>
<div>
<button ?disabled="${this.connected}" @click="${this.connect.bind(this)}">Connect</button>
<button ?disabled="${!this.connected}" @click="${this.disconnect.bind(this)}">Disconnect</button>
</div>
<div class="messageBox">
<label for="localOutgoing">Local outgoing message:</label>
<textarea class="message" id="localOutgoing"
placeholder="Local outgoing message goes here."></textarea>
<button ?disabled="${!this.connected}" @click="${e => this._sendMessage('#localOutgoing', this._localChannel)}
id="sendLocal">Send message from local</button>
</div>
<div class="messageBox">
<label for="localIncoming">Local incoming messages:</label>
<textarea class="message" id="localIncoming" disabled
placeholder="Local incoming messages arrive here.">${this.localMessages}</textarea>
</div>
<div class="messageBox">
<label for="remoteOutgoing">Remote outgoing message:</label>
<textarea class="message" id="remoteOutgoing"
placeholder="Remote outgoing message goes here."></textarea>
<button ?disabled="${!this.connected}" @click="${e => this._sendMessage('#remoteOutgoing', this._remoteChannel)}"
id="sendRemote">Send message from remote</button>
</div>
<div class="messageBox">
<label for="remoteIncoming">Remote incoming messages:</label>
<textarea class="message" id="remoteIncoming" disabled
placeholder="Remote incoming messages arrive here.">${this.remoteMessages}</textarea>
</div>
</section>`;
}
_sendMessage(selector, channel) {
const textarea = this.shadowRoot.querySelector(selector);
const value = textarea.value;
if (value === '') {
console.log('Not sending empty message!');
return;
}
console.log('Sending remote message: ', value);
channel.send(value);
textarea.value = '';
}
}
customElements.define('messaging-sample', MessagingSample);