summaryrefslogtreecommitdiffstats
path: root/webapp
diff options
context:
space:
mode:
authorJoram Wilander <jwawilander@gmail.com>2016-07-12 09:36:27 -0400
committerGitHub <noreply@github.com>2016-07-12 09:36:27 -0400
commitad343a0f4ad175053f7d0da12a0587bcbb396d1c (patch)
tree8e1be00202a1d3a037ec75879538eb0ba1f25c01 /webapp
parent06eacf30b97aacf6544552448635b7f078d2c90b (diff)
downloadchat-ad343a0f4ad175053f7d0da12a0587bcbb396d1c.tar.gz
chat-ad343a0f4ad175053f7d0da12a0587bcbb396d1c.tar.bz2
chat-ad343a0f4ad175053f7d0da12a0587bcbb396d1c.zip
Added infrastructure for basic WebSocket API (#3432)
Diffstat (limited to 'webapp')
-rw-r--r--webapp/actions/global_actions.jsx4
-rw-r--r--webapp/actions/websocket_actions.jsx148
-rw-r--r--webapp/package.json2
-rw-r--r--webapp/utils/websocket_client.jsx7
-rw-r--r--webapp/webpack.config.js9
5 files changed, 53 insertions, 117 deletions
diff --git a/webapp/actions/global_actions.jsx b/webapp/actions/global_actions.jsx
index d9b89f987..8d90b226d 100644
--- a/webapp/actions/global_actions.jsx
+++ b/webapp/actions/global_actions.jsx
@@ -12,7 +12,6 @@ import TeamStore from 'stores/team_store.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import SearchStore from 'stores/search_store.jsx';
-import * as Websockets from 'actions/websocket_actions.jsx';
import {handleNewPost} from 'actions/post_actions.jsx';
import Constants from 'utils/constants.jsx';
@@ -20,6 +19,7 @@ const ActionTypes = Constants.ActionTypes;
import Client from 'utils/web_client.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
+import WebSocketClient from 'utils/websocket_client.jsx';
import * as Utils from 'utils/utils.jsx';
import en from 'i18n/en.json';
@@ -439,7 +439,7 @@ var lastTimeTypingSent = 0;
export function emitLocalUserTypingEvent(channelId, parentId) {
const t = Date.now();
if ((t - lastTimeTypingSent) > Constants.UPDATE_TYPING_MS) {
- Websockets.sendMessage({channel_id: channelId, action: 'typing', props: {parent_id: parentId}, state: {}});
+ WebSocketClient.userTyping(channelId, parentId);
lastTimeTypingSent = t;
}
}
diff --git a/webapp/actions/websocket_actions.jsx b/webapp/actions/websocket_actions.jsx
index 7be9d84f3..e6997b9cc 100644
--- a/webapp/actions/websocket_actions.jsx
+++ b/webapp/actions/websocket_actions.jsx
@@ -11,6 +11,7 @@ import ErrorStore from 'stores/error_store.jsx';
import NotificationStore from 'stores/notification_store.jsx'; //eslint-disable-line no-unused-vars
import Client from 'utils/web_client.jsx';
+import WebSocketClient from 'utils/websocket_client.jsx';
import * as Utils from 'utils/utils.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
@@ -23,16 +24,9 @@ const SocketEvents = Constants.SocketEvents;
import {browserHistory} from 'react-router/es6';
const MAX_WEBSOCKET_FAILS = 7;
-const MIN_WEBSOCKET_RETRY_TIME = 3000; // 3 sec
-const MAX_WEBSOCKET_RETRY_TIME = 300000; // 5 mins
-
-var conn = null;
-var connectFailCount = 0;
-var pastFirstInit = false;
-var manuallyClosed = false;
export function initialize() {
- if (window.WebSocket && !conn) {
+ if (window.WebSocket) {
let protocol = 'ws://';
if (window.location.protocol === 'https:') {
protocol = 'wss://';
@@ -40,85 +34,35 @@ export function initialize() {
const connUrl = protocol + location.host + ((/:\d+/).test(location.host) ? '' : Utils.getWebsocketPort(protocol)) + Client.getUsersRoute() + '/websocket';
- if (connectFailCount === 0) {
- console.log('websocket connecting to ' + connUrl); //eslint-disable-line no-console
- }
-
- manuallyClosed = false;
-
- conn = new WebSocket(connUrl);
-
- conn.onopen = () => {
- if (connectFailCount > 0) {
- console.log('websocket re-established connection'); //eslint-disable-line no-console
- AsyncClient.getChannels();
- AsyncClient.getPosts(ChannelStore.getCurrentId());
- }
-
- if (pastFirstInit) {
- ErrorStore.clearLastError();
- ErrorStore.emitChange();
- }
-
- pastFirstInit = true;
- connectFailCount = 0;
- };
-
- conn.onclose = () => {
- conn = null;
-
- if (connectFailCount === 0) {
- console.log('websocket closed'); //eslint-disable-line no-console
- }
-
- if (manuallyClosed) {
- return;
- }
-
- connectFailCount = connectFailCount + 1;
-
- var retryTime = MIN_WEBSOCKET_RETRY_TIME;
-
- if (connectFailCount > MAX_WEBSOCKET_FAILS) {
- ErrorStore.storeLastError({message: Utils.localizeMessage('channel_loader.socketError', 'Please check connection, Mattermost unreachable. If issue persists, ask administrator to check WebSocket port.')});
-
- // If we've failed a bunch of connections then start backing off
- retryTime = MIN_WEBSOCKET_RETRY_TIME * connectFailCount * connectFailCount;
- if (retryTime > MAX_WEBSOCKET_RETRY_TIME) {
- retryTime = MAX_WEBSOCKET_RETRY_TIME;
- }
- }
-
- ErrorStore.setConnectionErrorCount(connectFailCount);
- ErrorStore.emitChange();
-
- setTimeout(
- () => {
- initialize();
- },
- retryTime
- );
- };
-
- conn.onerror = (evt) => {
- if (connectFailCount <= 1) {
- console.log('websocket error'); //eslint-disable-line no-console
- console.log(evt); //eslint-disable-line no-console
- }
- };
-
- conn.onmessage = (evt) => {
- const msg = JSON.parse(evt.data);
- handleMessage(msg);
- };
+ WebSocketClient.initialize(connUrl);
+ WebSocketClient.setEventCallback(handleEvent);
+ WebSocketClient.setReconnectCallback(handleReconnect);
+ WebSocketClient.setCloseCallback(handleClose);
}
}
-function handleMessage(msg) {
- // Let the store know we are online. This probably shouldn't be here.
- UserStore.setStatus(msg.user_id, 'online');
+export function close() {
+ WebSocketClient.close();
+}
+
+function handleReconnect() {
+ AsyncClient.getChannels();
+ AsyncClient.getPosts(ChannelStore.getCurrentId());
+ ErrorStore.clearLastError();
+ ErrorStore.emitChange();
+}
+
+function handleClose(failCount) {
+ if (failCount > MAX_WEBSOCKET_FAILS) {
+ ErrorStore.storeLastError({message: Utils.localizeMessage('channel_loader.socketError', 'Please check connection, Mattermost unreachable. If issue persists, ask administrator to check WebSocket port.')});
+ }
+
+ ErrorStore.setConnectionErrorCount(failCount);
+ ErrorStore.emitChange();
+}
- switch (msg.action) {
+function handleEvent(msg) {
+ switch (msg.event) {
case SocketEvents.POSTED:
case SocketEvents.EPHEMERAL_MESSAGE:
handleNewPostEvent(msg);
@@ -172,36 +116,14 @@ function handleMessage(msg) {
}
}
-export function sendMessage(msg) {
- if (conn && conn.readyState === WebSocket.OPEN) {
- var teamId = TeamStore.getCurrentId();
- if (teamId && teamId.length > 0) {
- msg.team_id = teamId;
- }
-
- conn.send(JSON.stringify(msg));
- } else if (!conn || conn.readyState === WebSocket.Closed) {
- conn = null;
- initialize();
- }
-}
-
-export function close() {
- manuallyClosed = true;
- connectFailCount = 0;
- if (conn && conn.readyState === WebSocket.OPEN) {
- conn.close();
- }
-}
-
function handleNewPostEvent(msg) {
- const post = JSON.parse(msg.props.post);
+ const post = JSON.parse(msg.data.post);
handleNewPost(post, msg);
}
function handlePostEditEvent(msg) {
// Store post
- const post = JSON.parse(msg.props.post);
+ const post = JSON.parse(msg.data.post);
PostStore.storePost(post);
PostStore.emitChange();
@@ -214,7 +136,7 @@ function handlePostEditEvent(msg) {
}
function handlePostDeleteEvent(msg) {
- const post = JSON.parse(msg.props.post);
+ const post = JSON.parse(msg.data.post);
GlobalActions.emitPostDeletedEvent(post);
}
@@ -257,12 +179,12 @@ function handleUserRemovedEvent(msg) {
if (UserStore.getCurrentId() === msg.user_id) {
AsyncClient.getChannels();
- if (msg.props.remover_id !== msg.user_id &&
+ if (msg.data.remover_id !== msg.user_id &&
msg.channel_id === ChannelStore.getCurrentId() &&
$('#removed_from_channel').length > 0) {
var sentState = {};
sentState.channelName = ChannelStore.getCurrent().display_name;
- sentState.remover = UserStore.getProfile(msg.props.remover_id).username;
+ sentState.remover = UserStore.getProfile(msg.data.remover_id).username;
BrowserStore.setItem('channel-removed-state', sentState);
$('#removed_from_channel').modal('show');
@@ -290,12 +212,10 @@ function handleChannelDeletedEvent(msg) {
}
function handlePreferenceChangedEvent(msg) {
- const preference = JSON.parse(msg.props.preference);
+ const preference = JSON.parse(msg.data.preference);
GlobalActions.emitPreferenceChangedEvent(preference);
}
function handleUserTypingEvent(msg) {
- if (TeamStore.getCurrentId() === msg.team_id) {
- GlobalActions.emitRemoteUserTypingEvent(msg.channel_id, msg.user_id, msg.props.parent_id);
- }
+ GlobalActions.emitRemoteUserTypingEvent(msg.channel_id, msg.user_id, msg.data.parent_id);
}
diff --git a/webapp/package.json b/webapp/package.json
index 3db9d0794..984affd08 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -18,7 +18,7 @@
"keymirror": "0.1.1",
"marked": "mattermost/marked#12d2be4cdf54d4ec95fead934e18840b6a2c1a7b",
"match-at": "0.1.0",
- "mattermost": "mattermost/mattermost-javascript#5815f14f0d1960aa4c99797b09d949d2959eb24f",
+ "mattermost": "mattermost/mattermost-javascript#4cdaeba22ff82bf93dc417af1ab4e89e3248d624",
"object-assign": "4.1.0",
"perfect-scrollbar": "0.6.11",
"react": "15.0.2",
diff --git a/webapp/utils/websocket_client.jsx b/webapp/utils/websocket_client.jsx
new file mode 100644
index 000000000..135d96466
--- /dev/null
+++ b/webapp/utils/websocket_client.jsx
@@ -0,0 +1,7 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import WebSocketClient from 'mattermost/websocket_client.jsx';
+
+var WebClient = new WebSocketClient();
+export default WebClient;
diff --git a/webapp/webpack.config.js b/webapp/webpack.config.js
index 2911c0c7d..88635ef03 100644
--- a/webapp/webpack.config.js
+++ b/webapp/webpack.config.js
@@ -53,6 +53,15 @@ var config = {
}
},
{
+ test: /node_modules\/mattermost\/websocket_client\.jsx?$/,
+ loader: 'babel',
+ query: {
+ presets: ['react', 'es2015-webpack', 'stage-0'],
+ plugins: ['transform-runtime'],
+ cacheDirectory: DEV
+ }
+ },
+ {
test: /\.json$/,
loader: 'json'
},