feat(base/conference): CONFERENCE_FAILED on CONNECTION_FAILED

Emits CONFERENCE_FAILED in response to CONNECTION_FAILED event
which then triggers JitsiConference.leave() through the middleware
processing. Also base/conference state will be adjusted. It is to have
a consistent redux state in which both connection and conference are
failed. It could happen that in a buggy environment the XMPP connection
is dropped, but the media is still flowing which would result in weird
user experience.
This commit is contained in:
paweldomas 2018-06-07 15:05:00 +02:00
parent b2f76f3ed6
commit 57b302da3e
2 changed files with 63 additions and 2 deletions

View File

@ -199,7 +199,8 @@ export function conferenceFailed(conference: Object, error: string) {
// Make the error resemble an Error instance (to the extent that // Make the error resemble an Error instance (to the extent that
// jitsi-meet needs it). // jitsi-meet needs it).
error: { error: {
name: error name: error,
recoverable: undefined
} }
}; };
} }

View File

@ -7,7 +7,7 @@ import {
createPinnedEvent, createPinnedEvent,
sendAnalytics sendAnalytics
} from '../../analytics'; } from '../../analytics';
import { CONNECTION_ESTABLISHED } from '../connection'; import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../connection';
import { setVideoMuted, VIDEO_MUTISM_AUTHORITY } from '../media'; import { setVideoMuted, VIDEO_MUTISM_AUTHORITY } from '../media';
import { import {
getLocalParticipant, getLocalParticipant,
@ -20,6 +20,7 @@ import UIEvents from '../../../../service/UI/UIEvents';
import { TRACK_ADDED, TRACK_REMOVED } from '../tracks'; import { TRACK_ADDED, TRACK_REMOVED } from '../tracks';
import { import {
conferenceFailed,
conferenceLeft, conferenceLeft,
createConference, createConference,
setLastN, setLastN,
@ -62,6 +63,9 @@ MiddlewareRegistry.register(store => next => action => {
case CONNECTION_ESTABLISHED: case CONNECTION_ESTABLISHED:
return _connectionEstablished(store, next, action); return _connectionEstablished(store, next, action);
case CONNECTION_FAILED:
return _connectionFailed(store, next, action);
case DATA_CHANNEL_OPENED: case DATA_CHANNEL_OPENED:
return _syncReceiveVideoQuality(store, next, action); return _syncReceiveVideoQuality(store, next, action);
@ -168,6 +172,62 @@ function _connectionEstablished({ dispatch }, next, action) {
return result; return result;
} }
/**
* Notifies the feature base/conference that the action
* {@code CONNECTION_FAILED} is being dispatched within a specific redux
* store.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code CONNECTION_FAILED} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _connectionFailed({ dispatch, getState }, next, action) {
const result = next(action);
// FIXME: Workaround for the web version. Currently, the creation of the
// conference is handled by /conference.js and appropriate failure handlers
// are set there.
if (typeof APP === 'undefined') {
const { connection } = action;
const { error } = action;
forEachConference(getState, conference => {
// It feels that it would make things easier if JitsiConference
// in lib-jitsi-meet would monitor it's connection and emit
// CONFERENCE_FAILED when it's dropped. It has more knowledge on
// whether it can recover or not. But because the reload screen
// and the retry logic is implemented in the app maybe it can be
// left this way for now.
if (conference.getConnection() === connection) {
// XXX Note that on mobile the error type passed to
// connectionFailed is always an object with .name property.
// This fact needs to be checked prior to enabling this logic on
// web.
const conferenceAction
= conferenceFailed(conference, error.name);
// Copy the recoverable flag if set on the CONNECTION_FAILED
// action to not emit recoverable action caused by
// a non-recoverable one.
if (typeof error.recoverable !== 'undefined') {
conferenceAction.error.recoverable = error.recoverable;
}
dispatch(conferenceAction);
}
return true;
});
}
return result;
}
/** /**
* Notifies the feature base/conference that the action {@code PIN_PARTICIPANT} * Notifies the feature base/conference that the action {@code PIN_PARTICIPANT}
* is being dispatched within a specific redux store. Pins the specified remote * is being dispatched within a specific redux store. Pins the specified remote