Skip to content

Commit 98f17a1

Browse files
committed
better message styles, added error handler for websockets, enlarged messages size to 1 MB
1 parent 0431e64 commit 98f17a1

3 files changed

Lines changed: 107 additions & 17 deletions

File tree

chat/css/style.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ form.login-form input[type=submit]{
116116
clear:both;
117117
}
118118
.message.content div{
119-
max-width: 225px;
119+
max-width: calc(100% - 30px);
120120
position: relative;
121121
display: inline-block;
122122
padding: 8px;

chat/data/index.js

Lines changed: 105 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var WebSocketServer = require('ws').Server,
1+
var WebSocket = require('ws'),
22
Url = require('url'),
33
fs = require('fs'),
44
expressSession = require('express-session');
@@ -21,9 +21,9 @@ App.prototype = {
2121
this._httpServer = httpServer;
2222
this._expressServer = expressServer;
2323
this._sessionParser = sessionParser;
24-
console.log("Initializing websocket serverving:");
25-
this._wss = new WebSocketServer({ server: httpServer });
24+
this._wss = new WebSocket.Server({ server: httpServer });
2625
this._wss.on('connection', this._webSocketConnectionHandler.bind(this));
26+
console.log("WebSocket serving initialized.");
2727
},
2828
_webSocketConnectionHandler: function (ws, req) {
2929
this._sessionParser(
@@ -33,14 +33,14 @@ App.prototype = {
3333
);
3434
},
3535
_webSocketSessionParsedHandler: function (ws, req) {
36-
ws.upgradeReq = req; // necessary for WebSocketServer 3.0.0+, https://github.com/websockets/ws/pull/1099
36+
ws.upgradeReqSessionID = req.sessionID; // necessary for WebSocket.Server 3.0.0+, https://github.com/websockets/ws/pull/1099
3737
var sessionId = req.session.id;
3838
if (typeof(this._allowedSessionIds[sessionId]) == 'undefined') {
39-
console.log("Connected not authorized user with session id: " + sessionId);
39+
console.log("Connected not authorized user with session id: '" + sessionId + "'.");
4040
ws.close(4000, 'Not authorized session.');
4141

4242
} else if (this._allowedSessionIds[sessionId]){
43-
console.log("Connected authorized user with session id: " + sessionId);
43+
console.log("Connected authorized user with session id: '" + sessionId + "'.");
4444
this._sendToMyself('connection', {
4545
message: 'Welcome, you are connected.'
4646
}, ws);
@@ -53,6 +53,7 @@ App.prototype = {
5353
}
5454
}.bind(this));
5555
ws.on('close', this._webSocketOnClose.bind(this, sessionId));
56+
ws.on('error', this._webSocketOnError.bind(this, sessionId));
5657
}
5758
},
5859
_webSocketOnMessage: function (str, bufferCont, sessionId) {
@@ -130,17 +131,58 @@ App.prototype = {
130131
user: userToDelete.user
131132
});
132133

133-
console.log(onlineUser.user + ' exited the chat room');
134+
console.log("User '" + onlineUser.user + "' exited the chat room.");
135+
},
136+
_webSocketOnError: function (sessionId) {
137+
// session id authorization boolean to false after user is disconnected
138+
this._allowedSessionIds[sessionId] = false;
139+
140+
var onlineUser = {}, userToDelete = {}, uidToDelete = '';
141+
for (var uid in this._onlineUsers) {
142+
onlineUser = this._onlineUsers[uid];
143+
if (sessionId != onlineUser.sessionId) continue;
144+
userToDelete = onlineUser;
145+
uidToDelete = uid;
146+
break;
147+
}
148+
149+
this._onlineUsersCount--;
150+
delete this._onlineUsers[uidToDelete];
151+
152+
var onlineUsersToSendBack = {};
153+
for (var uid in this._onlineUsers)
154+
onlineUsersToSendBack[uid] = this._onlineUsers[uid].user;
155+
156+
this._sendToAllExceptMyself('logout', {
157+
onlineUsers: onlineUsersToSendBack,
158+
onlineUsersCount: this._onlineUsersCount,
159+
id: userToDelete.id,
160+
user: userToDelete.user
161+
});
162+
163+
console.log("User '" + onlineUser.user + "' exited the chat room (connection error).");
134164
},
135165
_sendToAll: function (eventName, data) {
136166
var response = {
137167
eventName: eventName,
138168
data: data
139169
}
140170
this._data.push(response);
141-
this._wss.clients.forEach(function (client) {
142-
client.send(JSON.stringify(response));
143-
});
171+
if (this._data.length > App.LAST_MESSAGES_TO_SEND)
172+
this._data.shift();
173+
this._wss.clients.forEach(function (client, index) {
174+
try {
175+
if (client.readyState === WebSocket.OPEN) {
176+
client.send(JSON.stringify(response));
177+
} else if (client.readyState !== WebSocket.CONNECTING) {
178+
client.terminate();
179+
var clientPos = this._wss.clients.indexOf(client);
180+
if (clientPos !== -1) this._wss.clients.splice(clientPos, 1);
181+
}
182+
} catch (e) {
183+
console.log(e);
184+
}
185+
}.bind(this));
144186
},
145187
_sendToSingle: function (eventName, data, targetSessionId) {
146188
var response = {
@@ -150,17 +192,65 @@ App.prototype = {
150192
var responseStr = JSON.stringify(response);
151193
response.targetSessionId = targetSessionId;
152194
this._data.push(response);
153-
this._wss.clients.forEach(function (client) {
154-
if (client.upgradeReq.sessionID == targetSessionId)
155-
client.send(responseStr);
156-
});
195+
if (this._data.length > App.LAST_MESSAGES_TO_SEND)
196+
this._data.shift();
197+
this._wss.clients.forEach(function (client, index) {
198+
try {
199+
if (client.upgradeReqSessionID == targetSessionId) {
200+
if (client.readyState === WebSocket.OPEN) {
201+
client.send(responseStr);
202+
} else if (client.readyState !== WebSocket.CONNECTING) {
203+
client.terminate();
204+
var clientPos = this._wss.clients.indexOf(client);
205+
if (clientPos !== -1) this._wss.clients.splice(clientPos, 1);
206+
}
207+
}
208+
} catch (e) {
209+
console.log(e);
210+
}
211+
}.bind(this));
157212
},
158213
_sendToMyself: function (eventName, data, ws) {
159214
var responseStr = JSON.stringify({
160215
eventName: eventName,
161216
data: data
162217
});
163-
ws.send(responseStr);
218+
try {
219+
if (ws.readyState === WebSocket.OPEN) {
220+
ws.send(responseStr);
221+
} else if (ws.readyState !== WebSocket.CONNECTING) {
222+
ws.terminate();
223+
var clientPos = this._wss.clients.indexOf(ws);
224+
if (clientPos !== -1) this._wss.clients.splice(clientPos, 1);
225+
}
226+
} catch (e) {
227+
console.log(e);
228+
}
229+
},
230+
_sendToAllExceptMyself: function (eventName, data, myselfSessionId) {
231+
var response = {
232+
eventName: eventName,
233+
data: data
234+
};
235+
var responseStr = JSON.stringify(response);
236+
this._data.push(response);
237+
if (this._data.length > App.LAST_MESSAGES_TO_SEND)
238+
this._data.shift();
239+
this._wss.clients.forEach(function (client, index) {
240+
try {
241+
if (client.upgradeReqSessionID !== myselfSessionId) {
242+
if (client.readyState === WebSocket.OPEN) {
243+
client.send(responseStr);
244+
} else if (client.readyState !== WebSocket.CONNECTING) {
245+
client.terminate();
246+
var clientPos = this._wss.clients.indexOf(client);
247+
if (clientPos !== -1) this._wss.clients.splice(clientPos, 1);
248+
}
249+
}
250+
} catch (e) {
251+
console.log(e);
252+
}
253+
}.bind(this));
164254
},
165255
httpRequestHandler: function (request, response, callback) {
166256
if (request.method == 'POST' && typeof(request.query['login-submit']) != 'undefined') {

chat/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<div class="message-cont">
3636
<textarea
3737
type="text"
38-
maxlength="140"
38+
maxlength="1048576"
3939
placeholder="Write text message, hit Ctrl + Enter to send"
4040
name="message"></textarea>
4141
</div>

0 commit comments

Comments
 (0)