From 68e2bd1a6c46c578905b5c6e3e6a3b9ef6d73408 Mon Sep 17 00:00:00 2001 From: hippoz Date: Tue, 17 Nov 2020 17:20:33 +0200 Subject: [PATCH] make socket connection more robust --- app/resources/js/app.js | 85 ++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/app/resources/js/app.js b/app/resources/js/app.js index bd41cea..b55ffc6 100755 --- a/app/resources/js/app.js +++ b/app/resources/js/app.js @@ -64,6 +64,12 @@ class GatewayConnection { } } +GatewayConnection.prototype.disconnect = function() { + this.socket?.disconnect(); + this.socket = null; + this.isConnected = false; +}; + GatewayConnection.prototype.connect = function(token) { console.log('[*] [gateway] [handshake] Trying to connect to gateway'); this.socket = io('/gateway', { @@ -73,21 +79,25 @@ GatewayConnection.prototype.connect = function(token) { transports: ['websocket'] }); - this.socket.on('hello', () => { - console.log('[*] [gateway] [handshake] Got hello from server, sending yoo...'); - this.socket.emit('yoo'); - this.isConnected = true; - this.onConnect('CONNECT_RECEIVED_HELLO'); + this.socket.on('connect', () => { + this.socket.once('hello', () => { + console.log('[*] [gateway] [handshake] Got hello from server, sending yoo...'); + this.socket.emit('yoo'); + this.isConnected = true; + this.onConnect('CONNECT_RECEIVED_HELLO'); + }); }); this.socket.on('error', (e) => { console.log('[E] [gateway] Gateway error', e); this.isConnected = false; + this.socket = null; this.onDisconnect('DISCONNECT_ERR', e); }); this.socket.on('disconnectNotification', (e) => { console.log('[E] [gateway] Received disconnect notfication', e); this.isConnected = false; + this.socket = null; this.onDisconnect('DISCONNECT_NOTIF', e); }); this.socket.on('disconnect', (e) => { @@ -171,7 +181,7 @@ const app = new Vue({ credentials: 'include' }); - if (res.status === 200) { + if (res.ok) { const json = await res.json(); if (json.user.permissionLevel >= 1) { this.loggedInUser = json.user; @@ -202,21 +212,17 @@ const app = new Vue({ performGatewayConnection: function() { // TODO: again, the thing im doing with the token is not very secure, since its being sent by the current user info endpoint and is also being send through query parameters this.gateway.onDisconnect = (e) => { - this.resetSnackbarButton(); - this.notification('ERROR: You have been disconnected from the gateway. Realtime features such as chat will not work and unexpected errors may occur.'); - }; - this.gateway.onConnect = () => { - this.gateway.socket.on('message', this.processMessage); + this.okNotification('Connection lost.'); }; this.gateway.connect(this.loggedInUser.token); + this.gateway.socket.on('message', this.processMessage); }, processMessage: async function(messageObject) { if (!this.messages[messageObject.category._id]) this.$set(this.messages, messageObject.category._id, []); this.messages[messageObject.category._id].push(messageObject); if (messageObject.author.username !== this.loggedInUser.username && messageObject.category._id !== this.selection.category._id) { - this.resetSnackbarButton(); - this.notification(`${messageObject.author.username}: ${messageObject.content}`); + this.okNotification(`${messageObject.author.username}: ${messageObject.content}`); } }, openChatForCategory: async function(categoryId) { @@ -238,7 +244,7 @@ const app = new Vue({ credentials: 'include' }); - if (res.status === 200) { + if (res.ok) { const json = await res.json(); this.selection.category.title = 'categories'; @@ -264,8 +270,7 @@ const app = new Vue({ this.selection.posts.push({ title: v.title, body: '', _id: v._id, creator: v.creator }); } } else { - this.resetSnackbarButton(); - this.notification('Failed to fetch category list'); + this.okNotification('Failed to fetch category list'); } }, browse: async function(category) { @@ -279,7 +284,7 @@ const app = new Vue({ credentials: 'include' }); - if (res.status === 200) { + if (res.ok) { const json = await res.json(); this.selection.category.title = title; @@ -296,8 +301,7 @@ const app = new Vue({ this.selection.posts.push({ title: v.title, body: v.body, _id: v._id, creator: v.creator }); } } else { - this.resetSnackbarButton(); - this.notification('Failed to fetch category'); + this.okNotification('Failed to fetch category'); } }, refresh: function() { @@ -331,23 +335,21 @@ const app = new Vue({ credentials: 'include' }); - if (res.status === 200) { + if (res.ok) { const json = await res.json(); this.viewingProfile.username = json.user.username; this.viewingProfile._id = json.user._id; this.viewingProfile.role = json.user.role; this.viewingProfile.show = true; } else { - this.resetSnackbarButton(); - this.notification('Failed to fetch user data'); + this.okNotification('Failed to fetch user data'); } }, // Content creation showCreatePostDialog: function() { if (!this.selection.category.isCategory) { - this.resetSnackbarButton(); - this.notification('You are not in a category'); + this.okNotification('You are not in a category'); return; } @@ -355,8 +357,7 @@ const app = new Vue({ }, createPost: async function() { if (!this.selection.category.isCategory) { - this.resetSnackbarButton(); - this.notification('You are not in a category'); + this.okNotification('You are not in a category'); return; } @@ -377,25 +378,21 @@ const app = new Vue({ }) }); - if (res.status !== 200) { + if (res.ok) { if (res.status === 401 || res.status === 403) { - this.resetSnackbarButton(); - this.notification('You are not allowed to do that'); + this.okNotification('You are not allowed to do that'); return; } if (res.status === 429) { - this.resetSnackbarButton(); - this.notification('Chill! You are posting too much!'); + this.okNotification('Chill! You are posting too much!'); return; } const json = await res.json(); - this.resetSnackbarButton(); - this.notification(getCreatePostError(json)); + this.okNotification(getCreatePostError(json)); return; } else { - this.resetSnackbarButton(); - this.notification('Successfully created post'); + this.okNotification('Successfully created post'); this.dialog.show.createPost = false; this.browse(this.selection.category); return; @@ -416,25 +413,21 @@ const app = new Vue({ }) }); - if (res.status !== 200) { + if (res.ok) { if (res.status === 401 || res.status === 403) { - this.resetSnackbarButton(); - this.notification('You are not allowed to do that'); + this.okNotification('You are not allowed to do that'); return; } if (res.status === 429) { - this.resetSnackbarButton(); - this.notification('Chill! You are posting too much!'); + this.okNotification('Chill! You are posting too much!'); return; } const json = await res.json(); - this.resetSnackbarButton(); - this.notification(getCreateCategoryError(json)); + this.okNotification(getCreateCategoryError(json)); return; } else { - this.resetSnackbarButton(); - this.notification('Successfully created category'); + this.okNotification('Successfully created category'); this.dialog.show.createCategory = false; this.browseCategories(); return; @@ -467,5 +460,9 @@ const app = new Vue({ this.snackbarNotification = text; this.showSnackbarNotification = true; }, + okNotification: function(text) { + this.resetSnackbarButton(); + this.notification(text); + } } }); \ No newline at end of file