Merge branch 'develop' of https://github.com/havfo/multiparty-meeting into develop

auto_join_3.3
Stefan Otto 2020-05-19 14:13:24 +02:00
commit a44e799c79
28 changed files with 173 additions and 45 deletions

2
app/.env 100644
View File

@ -0,0 +1,2 @@
REACT_APP_VERSION=$npm_package_version
REACT_APP_NAME=$npm_package_name

View File

@ -37,7 +37,8 @@ var config =
'opera' 'opera'
], ],
// Socket.io request timeout // Socket.io request timeout
requestTimeout : 10000, requestTimeout : 20000,
requestRetries : 3,
transportOptions : transportOptions :
{ {
tcp : true tcp : true

View File

@ -1,6 +1,7 @@
import Logger from './Logger'; import Logger from './Logger';
import hark from 'hark'; import hark from 'hark';
import { getSignalingUrl } from './urlFactory'; import { getSignalingUrl } from './urlFactory';
import { SocketTimeoutError } from './utils';
import * as requestActions from './actions/requestActions'; import * as requestActions from './actions/requestActions';
import * as meActions from './actions/meActions'; import * as meActions from './actions/meActions';
import * as roomActions from './actions/roomActions'; import * as roomActions from './actions/roomActions';
@ -574,7 +575,7 @@ export default class RoomClient
if (called) if (called)
return; return;
called = true; called = true;
callback(new Error('Request timeout.')); callback(new SocketTimeoutError('Request timed out'));
}, },
ROOM_OPTIONS.requestTimeout ROOM_OPTIONS.requestTimeout
); );
@ -590,13 +591,13 @@ export default class RoomClient
}; };
} }
sendRequest(method, data) _sendRequest(method, data)
{ {
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
{ {
if (!this._signalingSocket) if (!this._signalingSocket)
{ {
reject('No socket connection.'); reject('No socket connection');
} }
else else
{ {
@ -606,19 +607,42 @@ export default class RoomClient
this.timeoutCallback((err, response) => this.timeoutCallback((err, response) =>
{ {
if (err) if (err)
{
reject(err); reject(err);
}
else else
{
resolve(response); resolve(response);
}
}) })
); );
} }
}); });
} }
async sendRequest(method, data)
{
logger.debug('sendRequest() [method:"%s", data:"%o"]', method, data);
const {
requestRetries = 3
} = window.config;
for (let tries = 0; tries < requestRetries; tries++)
{
try
{
return await this._sendRequest(method, data);
}
catch (error)
{
if (
error instanceof SocketTimeoutError &&
tries < requestRetries
)
logger.warn('sendRequest() | timeout, retrying [attempt:"%s"]', tries);
else
throw error;
}
}
}
async changeDisplayName(displayName) async changeDisplayName(displayName)
{ {
logger.debug('changeDisplayName() [displayName:"%s"]', displayName); logger.debug('changeDisplayName() [displayName:"%s"]', displayName);

View File

@ -42,8 +42,9 @@ const styles = (theme) =>
}, },
link : link :
{ {
display : 'block', display : 'block',
textAlign : 'center' textAlign : 'center',
marginBottom : theme.spacing(1)
} }
}); });
@ -68,15 +69,16 @@ const About = ({
/> />
</DialogTitle> </DialogTitle>
<DialogContent dividers='true'> <DialogContent dividers='true'>
<DialogContentText> <DialogContentText paragraph>
Contributions to this work were made on behalf of the GÉANT Contributions to this work were made on behalf of the GÉANT
project, a project that has received funding from the project, a project that has received funding from the
European Unions Horizon 2020 research and innovation European Unions Horizon 2020 research and innovation
programme under Grant Agreement No. 731122 (GN4-2). programme under Grant Agreement No. 731122 (GN4-2).
On behalf of GÉANT project, GÉANT Association is the sole On behalf of GÉANT project, GÉANT Association is the sole
owner of the copyright in all material which was developed owner of the copyright in all material which was developed
by a member of the GÉANT project.<br /> by a member of the GÉANT project.
<br /> </DialogContentText>
<DialogContentText paragraph>
GÉANT Vereniging (Association) is registered with the GÉANT Vereniging (Association) is registered with the
Chamber of Commerce in Amsterdam with registration number Chamber of Commerce in Amsterdam with registration number
40535155 and operates in the UK as a branch of GÉANT 40535155 and operates in the UK as a branch of GÉANT
@ -87,6 +89,13 @@ const About = ({
<Link href='https://edumeet.org' target='_blank' rel='noreferrer' color='secondary' variant='h6' className={classes.link}> <Link href='https://edumeet.org' target='_blank' rel='noreferrer' color='secondary' variant='h6' className={classes.link}>
https://edumeet.org https://edumeet.org
</Link> </Link>
<DialogContentText align='center' variant='h7'>
<FormattedMessage
id='label.version'
defaultMessage='Version'
/>
:{` ${process.env.REACT_APP_VERSION}`}
</DialogContentText>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
{ window.config.logo && <img alt='Logo' className={classes.logo} src={window.config.logo} /> } { window.config.logo && <img alt='Logo' className={classes.logo} src={window.config.logo} /> }

View File

@ -479,35 +479,36 @@ const TopBar = (props) =>
> >
<MoreIcon /> <MoreIcon />
</IconButton> </IconButton>
</div> { lobbyPeers.length > 0 &&
{ lobbyPeers.length > 0 && <Tooltip
<Tooltip title={intl.formatMessage({
title={intl.formatMessage({ id : 'tooltip.lobby',
id : 'tooltip.lobby', defaultMessage : 'Show lobby'
defaultMessage : 'Show lobby' })}
})} >
> <span className={classes.disabledButton}>
<span className={classes.disabledButton}> <IconButton
<IconButton aria-label={intl.formatMessage({
aria-label={intl.formatMessage({ id : 'tooltip.lobby',
id : 'tooltip.lobby', defaultMessage : 'Show lobby'
defaultMessage : 'Show lobby' })}
})} className={classes.actionButton}
className={classes.actionButton} color='inherit'
color='inherit' disabled={!canPromote}
disabled={!canPromote} onClick={() => setLockDialogOpen(!room.lockDialogOpen)}
onClick={() => setLockDialogOpen(!room.lockDialogOpen)}
>
<PulsingBadge
color='secondary'
badgeContent={lobbyPeers.length}
> >
<SecurityIcon /> <PulsingBadge
</PulsingBadge> color='secondary'
</IconButton> badgeContent={lobbyPeers.length}
</span> >
</Tooltip> <SecurityIcon />
} </PulsingBadge>
</IconButton>
</span>
</Tooltip>
}
</div>
<div className={classes.divider} /> <div className={classes.divider} />
<Button <Button
aria-label={intl.formatMessage({ aria-label={intl.formatMessage({

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "设置", "settings.settings": "设置",
"settings.camera": "视频设备", "settings.camera": "视频设备",

View File

@ -118,6 +118,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Nastavení", "settings.settings": "Nastavení",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -119,6 +119,7 @@
"label.addVideo": "Video hinzufügen", "label.addVideo": "Video hinzufügen",
"label.promoteAllPeers": "Alle Teilnehmer reinlassen", "label.promoteAllPeers": "Alle Teilnehmer reinlassen",
"label.moreActions": "Weitere Aktionen", "label.moreActions": "Weitere Aktionen",
"label.version": null,
"settings.settings": "Einstellungen", "settings.settings": "Einstellungen",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Indstillinger", "settings.settings": "Indstillinger",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Ρυθμίσεις", "settings.settings": "Ρυθμίσεις",
"settings.camera": "Κάμερα", "settings.camera": "Κάμερα",

View File

@ -119,6 +119,7 @@
"label.addVideo": "Add video", "label.addVideo": "Add video",
"label.promoteAllPeers": "Promote all", "label.promoteAllPeers": "Promote all",
"label.moreActions": "More actions", "label.moreActions": "More actions",
"label.version": "Version",
"settings.settings": "Settings", "settings.settings": "Settings",
"settings.camera": "Camera", "settings.camera": "Camera",

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Ajustes", "settings.settings": "Ajustes",
"settings.camera": "Cámara", "settings.camera": "Cámara",

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Paramètres", "settings.settings": "Paramètres",
"settings.camera": "Caméra", "settings.camera": "Caméra",

View File

@ -119,6 +119,7 @@
"label.addVideo": "Dodaj video", "label.addVideo": "Dodaj video",
"label.promoteAllPeers": "Promoviraj sve", "label.promoteAllPeers": "Promoviraj sve",
"label.moreActions": "Više akcija", "label.moreActions": "Više akcija",
"label.version": null,
"settings.settings": "Postavke", "settings.settings": "Postavke",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -119,6 +119,7 @@
"label.addVideo": "Videó hozzáadása", "label.addVideo": "Videó hozzáadása",
"label.promoteAllPeers": "Mindenkit beengedek", "label.promoteAllPeers": "Mindenkit beengedek",
"label.moreActions": "További műveletek", "label.moreActions": "További műveletek",
"label.version": "Verzió",
"settings.settings": "Beállítások", "settings.settings": "Beállítások",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -119,6 +119,7 @@
"label.addVideo": "Aggiungi video", "label.addVideo": "Aggiungi video",
"label.promoteAllPeers": "Promuovi tutti", "label.promoteAllPeers": "Promuovi tutti",
"label.moreActions": "Altre azioni", "label.moreActions": "Altre azioni",
"label.version": null,
"settings.settings": "Impostazioni", "settings.settings": "Impostazioni",
"settings.camera": "Videocamera", "settings.camera": "Videocamera",

View File

@ -116,6 +116,7 @@
"label.advanced": "Advancēts", "label.advanced": "Advancēts",
"label.addVideo": "Pievienot video", "label.addVideo": "Pievienot video",
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Iestatījumi", "settings.settings": "Iestatījumi",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -119,6 +119,7 @@
"label.addVideo": "Legg til video", "label.addVideo": "Legg til video",
"label.promoteAllPeers": "Slipp inn alle", "label.promoteAllPeers": "Slipp inn alle",
"label.moreActions": "Flere handlinger", "label.moreActions": "Flere handlinger",
"label.version": null,
"settings.settings": "Innstillinger", "settings.settings": "Innstillinger",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -119,6 +119,7 @@
"label.addVideo": "Dodaj wideo", "label.addVideo": "Dodaj wideo",
"label.promoteAllPeers": "Wpuść wszystkich", "label.promoteAllPeers": "Wpuść wszystkich",
"label.moreActions": "Więcej akcji", "label.moreActions": "Więcej akcji",
"label.version": null,
"settings.settings": "Ustawienia", "settings.settings": "Ustawienia",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Definições", "settings.settings": "Definições",
"settings.camera": "Camera", "settings.camera": "Camera",

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Setări", "settings.settings": "Setări",
"settings.camera": "Cameră video", "settings.camera": "Cameră video",

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Ayarlar", "settings.settings": "Ayarlar",
"settings.camera": "Kamera", "settings.camera": "Kamera",

View File

@ -118,6 +118,7 @@
"label.addVideo": "新增視訊", "label.addVideo": "新增視訊",
"label.promoteAllPeers": "提升全部", "label.promoteAllPeers": "提升全部",
"label.moreActions": "更多", "label.moreActions": "更多",
"label.version": null,
"settings.settings": "設置", "settings.settings": "設置",
"settings.camera": "視訊來源", "settings.camera": "視訊來源",

View File

@ -119,6 +119,7 @@
"label.addVideo": null, "label.addVideo": null,
"label.promoteAllPeers": null, "label.promoteAllPeers": null,
"label.moreActions": null, "label.moreActions": null,
"label.version": null,
"settings.settings": "Налаштування", "settings.settings": "Налаштування",
"settings.camera": "Камера", "settings.camera": "Камера",

View File

@ -16,4 +16,22 @@ export const idle = (callback, delay) =>
handle = setTimeout(callback, delay); handle = setTimeout(callback, delay);
}; };
}; };
/**
* Error produced when a socket request has a timeout.
*/
export class SocketTimeoutError extends Error
{
constructor(message)
{
super(message);
this.name = 'SocketTimeoutError';
if (Error.hasOwnProperty('captureStackTrace')) // Just in V8.
Error.captureStackTrace(this, SocketTimeoutError);
else
this.stack = (new Error(message)).stack;
}
}

View File

@ -276,6 +276,10 @@ module.exports =
// maxUsersPerRoom : 20, // maxUsersPerRoom : 20,
// Room size before spreading to new router // Room size before spreading to new router
routerScaleSize : 40, routerScaleSize : 40,
// Socket timout value
requestTimeout : 20000,
// Socket retries when timeout
requestRetries : 3,
// Mediasoup settings // Mediasoup settings
mediasoup : mediasoup :
{ {

View File

@ -3,6 +3,7 @@ const AwaitQueue = require('awaitqueue');
const axios = require('axios'); const axios = require('axios');
const Logger = require('./Logger'); const Logger = require('./Logger');
const Lobby = require('./Lobby'); const Lobby = require('./Lobby');
const { SocketTimeoutError } = require('./errors');
const { v4: uuidv4 } = require('uuid'); const { v4: uuidv4 } = require('uuid');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const userRoles = require('../userRoles'); const userRoles = require('../userRoles');
@ -1759,9 +1760,9 @@ class Room extends EventEmitter
if (called) if (called)
return; return;
called = true; called = true;
callback(new Error('Request timeout.')); callback(new SocketTimeoutError('Request timed out'));
}, },
10000 config.requestTimeout || 20000
); );
return (...args) => return (...args) =>
@ -1775,7 +1776,7 @@ class Room extends EventEmitter
}; };
} }
_request(socket, method, data = {}) _sendRequest(socket, method, data = {})
{ {
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
{ {
@ -1797,6 +1798,33 @@ class Room extends EventEmitter
}); });
} }
async _request(socket, method, data)
{
logger.debug('_request() [method:"%s", data:"%o"]', method, data);
const {
requestRetries = 3
} = config;
for (let tries = 0; tries < requestRetries; tries++)
{
try
{
return await this._sendRequest(socket, method, data);
}
catch (error)
{
if (
error instanceof SocketTimeoutError &&
tries < requestRetries
)
logger.warn('_request() | timeout, retrying [attempt:"%s"]', tries);
else
throw error;
}
}
}
_notification(socket, method, data = {}, broadcast = false, includeSender = false) _notification(socket, method, data = {}, broadcast = false, includeSender = false)
{ {
if (broadcast) if (broadcast)

View File

@ -0,0 +1,22 @@
/**
* Error produced when a socket request has a timeout.
*/
class SocketTimeoutError extends Error
{
constructor(message)
{
super(message);
this.name = 'SocketTimeoutError';
if (Error.hasOwnProperty('captureStackTrace')) // Just in V8.
Error.captureStackTrace(this, SocketTimeoutError);
else
this.stack = (new Error(message)).stack;
}
}
module.exports =
{
SocketTimeoutError
};