From 9ffa3ee8f3d2616dc20d3e7e3769ec7c72f3e0a3 Mon Sep 17 00:00:00 2001 From: Mattermost Build Date: Sat, 18 Apr 2020 06:39:30 +0200 Subject: [PATCH] Automated cherry pick of #4111 (#4175) * Remove duplicated websocket client & constants Defunct code originally maintained in mattermost-redux, but not used in mobile, in favour of https://github.com/mattermost/mattermost-mobile/blob/master/app/client/websocket.ts * PR review: Remove redundant reference to constants * Remove deleted files from modules list --- app/mm-redux/actions/posts.ts | 3 +- app/mm-redux/client/websocket_client.ts | 254 ------------------ app/mm-redux/constants/index.ts | 3 +- app/mm-redux/constants/websocket.ts | 45 ---- app/mm-redux/reducers/entities/typing.test.js | 2 +- app/mm-redux/reducers/entities/typing.ts | 2 +- packager/moduleNames.js | 1 - packager/modulePaths.js | 1 - 8 files changed, 5 insertions(+), 306 deletions(-) delete mode 100644 app/mm-redux/client/websocket_client.ts delete mode 100644 app/mm-redux/constants/websocket.ts diff --git a/app/mm-redux/actions/posts.ts b/app/mm-redux/actions/posts.ts index ea94027f5..7f24cb45d 100644 --- a/app/mm-redux/actions/posts.ts +++ b/app/mm-redux/actions/posts.ts @@ -2,7 +2,8 @@ // See LICENSE.txt for license information. import {Client4, DEFAULT_LIMIT_AFTER, DEFAULT_LIMIT_BEFORE} from '@mm-redux/client'; -import {General, Preferences, Posts, WebsocketEvents} from '../constants'; +import {General, Preferences, Posts} from '../constants'; +import {WebsocketEvents} from '@constants'; import {PostTypes, ChannelTypes, FileTypes, IntegrationTypes} from '@mm-redux/action_types'; import {getCurrentChannelId, getMyChannelMember as getMyChannelMemberSelector, isManuallyUnread} from '@mm-redux/selectors/entities/channels'; diff --git a/app/mm-redux/client/websocket_client.ts b/app/mm-redux/client/websocket_client.ts deleted file mode 100644 index a58f0f483..000000000 --- a/app/mm-redux/client/websocket_client.ts +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. -const MAX_WEBSOCKET_FAILS = 7; -const MIN_WEBSOCKET_RETRY_TIME = 3000; // 3 sec - -const MAX_WEBSOCKET_RETRY_TIME = 300000; // 5 mins - -let Socket: any; - -class WebSocketClient { - conn?: WebSocket; - connectionUrl: null; - token: string|null; - sequence: number; - connectFailCount: number; - eventCallback?: Function; - firstConnectCallback?: Function; - reconnectCallback?: Function; - errorCallback?: Function; - closeCallback?: Function; - connectingCallback?: Function; - stop: boolean; - platform: string; - connectionTimeout: any; - - constructor() { - this.connectionUrl = null; - this.token = null; - this.sequence = 1; - this.connectFailCount = 0; - this.stop = false; - this.platform = ''; - } - - initialize(token: string|null, opts: any) { - const defaults = { - forceConnection: true, - connectionUrl: this.connectionUrl, - webSocketConnector: WebSocket, - }; - - const {connectionUrl, forceConnection, webSocketConnector, platform, ...additionalOptions} = Object.assign({}, defaults, opts); - - if (platform) { - this.platform = platform; - } - - if (forceConnection) { - this.stop = false; - } - - return new Promise((resolve, reject) => { - if (this.conn) { - resolve(); - return; - } - - if (connectionUrl == null) { - console.log('websocket must have connection url'); //eslint-disable-line no-console - reject(new Error('websocket must have connection url')); - return; - } - - if (this.connectFailCount === 0) { - console.log('websocket connecting to ' + connectionUrl); //eslint-disable-line no-console - } - - Socket = webSocketConnector; - if (this.connectingCallback) { - this.connectingCallback(); - } - - const regex = /^(?:https?|wss?):(?:\/\/)?[^/]*/; - const captured = (regex).exec(connectionUrl); - - let origin; - if (captured) { - origin = captured[0]; - - if (platform === 'android') { - // this is done cause for android having the port 80 or 443 will fail the connection - // the websocket will append them - const split = origin.split(':'); - const port = split[2]; - if (port === '80' || port === '443') { - origin = `${split[0]}:${split[1]}`; - } - } - } else { - // If we're unable to set the origin header, the websocket won't connect, but the URL is likely malformed anyway - const errorMessage = 'websocket failed to parse origin from ' + connectionUrl; - console.warn(errorMessage); // eslint-disable-line no-console - reject(new Error(errorMessage)); - return; - } - - this.conn = new Socket(connectionUrl, [], {headers: {origin}, ...(additionalOptions || {})}); - this.connectionUrl = connectionUrl; - this.token = token; - - this.conn!.onopen = () => { - if (token) { - // we check for the platform as a workaround until we fix on the server that further authentications - // are ignored - this.sendMessage('authentication_challenge', {token}); - } - - if (this.connectFailCount > 0) { - console.log('websocket re-established connection'); //eslint-disable-line no-console - if (this.reconnectCallback) { - this.reconnectCallback(); - } - } else if (this.firstConnectCallback) { - this.firstConnectCallback(); - } - - this.connectFailCount = 0; - resolve(); - }; - - this.conn!.onclose = () => { - this.conn = undefined; - this.sequence = 1; - - if (this.connectFailCount === 0) { - console.log('websocket closed'); //eslint-disable-line no-console - } - - this.connectFailCount++; - - if (this.closeCallback) { - this.closeCallback(this.connectFailCount); - } - - let retryTime = MIN_WEBSOCKET_RETRY_TIME; - - // If we've failed a bunch of connections then start backing off - if (this.connectFailCount > MAX_WEBSOCKET_FAILS) { - retryTime = MIN_WEBSOCKET_RETRY_TIME * this.connectFailCount; - if (retryTime > MAX_WEBSOCKET_RETRY_TIME) { - retryTime = MAX_WEBSOCKET_RETRY_TIME; - } - } - - if (this.connectionTimeout) { - clearTimeout(this.connectionTimeout); - } - - this.connectionTimeout = setTimeout( - () => { - if (this.stop) { - clearTimeout(this.connectionTimeout); - return; - } - this.initialize(token, opts); - }, - retryTime - ); - }; - - this.conn!.onerror = (evt) => { - if (this.connectFailCount <= 1) { - console.log('websocket error'); //eslint-disable-line no-console - console.log(evt); //eslint-disable-line no-console - } - - if (this.errorCallback) { - this.errorCallback(evt); - } - }; - - this.conn!.onmessage = (evt) => { - const msg = JSON.parse(evt.data); - if (msg.seq_reply) { - if (msg.error) { - console.warn(msg); //eslint-disable-line no-console - } - } else if (this.eventCallback) { - this.eventCallback(msg); - } - }; - }); - } - - setConnectingCallback(callback: Function) { - this.connectingCallback = callback; - } - - setEventCallback(callback: Function) { - this.eventCallback = callback; - } - - setFirstConnectCallback(callback: Function) { - this.firstConnectCallback = callback; - } - - setReconnectCallback(callback: Function) { - this.reconnectCallback = callback; - } - - setErrorCallback(callback: Function) { - this.errorCallback = callback; - } - - setCloseCallback(callback: Function) { - this.closeCallback = callback; - } - - close(stop = false) { - this.stop = stop; - this.connectFailCount = 0; - this.sequence = 1; - if (this.conn && this.conn.readyState === Socket.OPEN) { - this.conn.onclose = () => {}; //eslint-disable-line no-empty-function - this.conn.close(); - this.conn = undefined; - console.log('websocket closed'); //eslint-disable-line no-console - } - } - - sendMessage(action: string, data: any) { - const msg = { - action, - seq: this.sequence++, - data, - }; - - if (this.conn && this.conn.readyState === Socket.OPEN) { - this.conn.send(JSON.stringify(msg)); - } else if (!this.conn || this.conn.readyState === Socket.CLOSED) { - this.conn = undefined; - this.initialize(this.token, {platform: this.platform}); - } - } - - userTyping(channelId: string, parentId: string) { - this.sendMessage('user_typing', { - channel_id: channelId, - parent_id: parentId, - }); - } - - getStatuses() { - this.sendMessage('get_statuses', null); - } - - getStatusesByIds(userIds: string[]) { - this.sendMessage('get_statuses_by_ids', { - user_ids: userIds, - }); - } -} - -export default new WebSocketClient(); diff --git a/app/mm-redux/constants/index.ts b/app/mm-redux/constants/index.ts index b8ff05fd3..0b26e9c42 100644 --- a/app/mm-redux/constants/index.ts +++ b/app/mm-redux/constants/index.ts @@ -2,7 +2,6 @@ // See LICENSE.txt for license information. import General from './general'; import RequestStatus from './request_status'; -import WebsocketEvents from './websocket'; import Preferences from './preferences'; import Posts from './posts'; import Files from './files'; @@ -14,4 +13,4 @@ import Plugins from './plugins'; import Groups from './groups'; import Users from './users'; import Roles from './roles'; -export {General, Preferences, Posts, Files, RequestStatus, WebsocketEvents, Teams, Stats, Permissions, Emoji, Plugins, Groups, Users, Roles}; +export {General, Preferences, Posts, Files, RequestStatus, Teams, Stats, Permissions, Emoji, Plugins, Groups, Users, Roles}; diff --git a/app/mm-redux/constants/websocket.ts b/app/mm-redux/constants/websocket.ts deleted file mode 100644 index 7adb29c5d..000000000 --- a/app/mm-redux/constants/websocket.ts +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. -const WebsocketEvents = { - POSTED: 'posted', - POST_EDITED: 'post_edited', - POST_DELETED: 'post_deleted', - POST_UNREAD: 'post_unread', - CHANNEL_CONVERTED: 'channel_converted', - CHANNEL_CREATED: 'channel_created', - CHANNEL_DELETED: 'channel_deleted', - CHANNEL_UNARCHIVED: 'channel_restored', - CHANNEL_UPDATED: 'channel_updated', - CHANNEL_VIEWED: 'channel_viewed', - CHANNEL_MEMBER_UPDATED: 'channel_member_updated', - CHANNEL_SCHEME_UPDATED: 'channel_scheme_updated', - DIRECT_ADDED: 'direct_added', - ADDED_TO_TEAM: 'added_to_team', - LEAVE_TEAM: 'leave_team', - UPDATE_TEAM: 'update_team', - USER_ADDED: 'user_added', - USER_REMOVED: 'user_removed', - USER_UPDATED: 'user_updated', - USER_ROLE_UPDATED: 'user_role_updated', - ROLE_ADDED: 'role_added', - ROLE_REMOVED: 'role_removed', - ROLE_UPDATED: 'role_updated', - TYPING: 'typing', - STOP_TYPING: 'stop_typing', - PREFERENCE_CHANGED: 'preference_changed', - PREFERENCES_CHANGED: 'preferences_changed', - PREFERENCES_DELETED: 'preferences_deleted', - EPHEMERAL_MESSAGE: 'ephemeral_message', - STATUS_CHANGED: 'status_change', - HELLO: 'hello', - WEBRTC: 'webrtc', - REACTION_ADDED: 'reaction_added', - REACTION_REMOVED: 'reaction_removed', - EMOJI_ADDED: 'emoji_added', - LICENSE_CHANGED: 'license_changed', - CONFIG_CHANGED: 'config_changed', - PLUGIN_STATUSES_CHANGED: 'plugin_statuses_changed', - OPEN_DIALOG: 'open_dialog', - INCREASE_POST_VISIBILITY_BY_ONE: 'increase_post_visibility_by_one', -}; -export default WebsocketEvents; diff --git a/app/mm-redux/reducers/entities/typing.test.js b/app/mm-redux/reducers/entities/typing.test.js index 95ed767e2..5505c32e1 100644 --- a/app/mm-redux/reducers/entities/typing.test.js +++ b/app/mm-redux/reducers/entities/typing.test.js @@ -3,7 +3,7 @@ import assert from 'assert'; -import {WebsocketEvents} from '../../constants'; +import {WebsocketEvents} from '@constants'; import typingReducer from '@mm-redux/reducers/entities/typing'; diff --git a/app/mm-redux/reducers/entities/typing.ts b/app/mm-redux/reducers/entities/typing.ts index bccccf155..06cf10b38 100644 --- a/app/mm-redux/reducers/entities/typing.ts +++ b/app/mm-redux/reducers/entities/typing.ts @@ -1,6 +1,6 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {WebsocketEvents} from '../../constants'; +import {WebsocketEvents} from '@constants'; import {Typing} from '@mm-redux/types/typing'; import {GenericAction} from '@mm-redux/types/actions'; export default function typing(state: Typing = {}, action: GenericAction): Typing { diff --git a/packager/moduleNames.js b/packager/moduleNames.js index 5c2f0fc7d..18dadfa71 100644 --- a/packager/moduleNames.js +++ b/packager/moduleNames.js @@ -107,7 +107,6 @@ module.exports = [ 'app/mm-redux/constants/stats.ts', 'app/mm-redux/constants/teams.ts', 'app/mm-redux/constants/users.ts', - 'app/mm-redux/constants/websocket.ts', 'app/mm-redux/reducers/entities/bots.ts', 'app/mm-redux/reducers/entities/channels.ts', 'app/mm-redux/reducers/entities/emojis.ts', diff --git a/packager/modulePaths.js b/packager/modulePaths.js index 2ad64690a..24017d6d8 100644 --- a/packager/modulePaths.js +++ b/packager/modulePaths.js @@ -106,7 +106,6 @@ module.exports = [ './node_modules/app/mm-redux/constants/stats.ts', './node_modules/app/mm-redux/constants/teams.ts', './node_modules/app/mm-redux/constants/users.ts', - './node_modules/app/mm-redux/constants/websocket.ts', './node_modules/app/mm-redux/reducers/entities/bots.ts', './node_modules/app/mm-redux/reducers/entities/channels.ts', './node_modules/app/mm-redux/reducers/entities/emojis.ts',