UNPKG

networked-aframe

Version:

A web framework for building multi-user virtual reality experiences.

149 lines (118 loc) 3.81 kB
/* global NAF */ const NoOpAdapter = require('./NoOpAdapter'); class WsEasyRtcInterface extends NoOpAdapter { constructor(easyrtc) { super(); this.easyrtc = easyrtc || window.easyrtc; this.app = 'default'; this.room = 'default'; this.destination = {targetRoom: this.room}; this.connectedClients = []; this.serverTimeRequests = 0; this.timeOffsets = []; this.avgTimeOffset = 0; } setServerUrl(url) { this.serverUrl = url; this.easyrtc.setSocketUrl(url); } setApp(appName) { this.app = appName; } setRoom(roomName) { this.room = roomName; this.destination.targetRoom = this.room; this.easyrtc.joinRoom(roomName, null); } setWebRtcOptions(options) { // No webrtc support } setServerConnectListeners(successListener, failureListener) { this.connectSuccess = successListener; this.connectFailure = failureListener; } setRoomOccupantListener(occupantListener){ this.easyrtc.setRoomOccupantListener(function(roomName, occupants, primary) { occupantListener(occupants); }); } setDataChannelListeners(openListener, closedListener, messageListener) { this.openListener = openListener; this.closedListener = closedListener; this.easyrtc.setPeerListener(messageListener); } updateTimeOffset() { const clientSentTime = Date.now() + this.avgTimeOffset; return fetch(document.location.href, { method: "HEAD", cache: "no-cache" }) .then(res => { var precision = 1000; var serverReceivedTime = new Date(res.headers.get("Date")).getTime() + (precision / 2); var clientReceivedTime = Date.now(); var serverTime = serverReceivedTime + ((clientReceivedTime - clientSentTime) / 2); var timeOffset = serverTime - clientReceivedTime; this.serverTimeRequests++; if (this.serverTimeRequests <= 10) { this.timeOffsets.push(timeOffset); } else { this.timeOffsets[this.serverTimeRequests % 10] = timeOffset; } this.avgTimeOffset = this.timeOffsets.reduce((acc, offset) => acc += offset, 0) / this.timeOffsets.length; if (this.serverTimeRequests > 10) { setTimeout(() => this.updateTimeOffset(), 5 * 60 * 1000); // Sync clock every 5 minutes. } else { this.updateTimeOffset(); } }); } connect() { Promise.all([ this.updateTimeOffset(), new Promise((resolve, reject) => { this.easyrtc.connect(this.app, resolve, reject); }) ]).then(([_, clientId]) => { this.connectSuccess(clientId); }).catch(this.connectFailure); } shouldStartConnectionTo(clientId) { return true; } startStreamConnection(clientId) { this.connectedClients.push(clientId); this.openListener(clientId); } closeStreamConnection(clientId) { var index = this.connectedClients.indexOf(clientId); if (index > -1) { this.connectedClients.splice(index, 1); } this.closedListener(clientId); } sendData(clientId, dataType, data) { this.easyrtc.sendDataWS(clientId, dataType, data); } sendDataGuaranteed(clientId, dataType, data) { this.sendData(clientId, dataType, data); } broadcastData(dataType, data) { this.easyrtc.sendDataWS(this.destination, dataType, data); } broadcastDataGuaranteed(dataType, data) { this.broadcastData(dataType, data); } getConnectStatus(clientId) { var connected = this.connectedClients.indexOf(clientId) != -1; if (connected) { return NAF.adapters.IS_CONNECTED; } else { return NAF.adapters.NOT_CONNECTED; } } getServerTime() { return Date.now() + this.avgTimeOffset; } disconnect() { this.easyrtc.disconnect(); } } module.exports = WsEasyRtcInterface;