Repository navigation
Expand file tree
/
Copy pathserverSocket.js
More file actions
140 lines (125 loc) · 4.87 KB
/
Copy pathserverSocket.js
File metadata and controls
140 lines (125 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const socketIO = require("socket.io");
const sharedSession = require("express-socket.io-session");
const ChatroomUsers = require("./socketClasses/chatroom-users");
const chatRoomsData = [
{
name: "NodeJS",
imageUrl:
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Node.js_logo.svg/590px-Node.js_logo.svg.png",
},
{
name: "ReactJS",
imageUrl:
"https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/React.svg/800px-React.svg.png",
},
{
name: "MongoDB",
imageUrl:
"https://infinapps.com/wp-content/uploads/2018/10/mongodb-logo.png",
},
{
name: "ExpressJS",
imageUrl:
"https://manticore-labs.com/wp-content/uploads/2019/02/express.png",
},
{
name: "MERN",
imageUrl:
"https://upload.wikimedia.org/wikipedia/commons/thumb/9/94/MERN-logo.png/800px-MERN-logo.png",
},
{
name: "Socket.io",
imageUrl:
"https://image.codeforgeek.com/wp-content/uploads/2018/11/socket.io_.png",
},
];
/**
* Create/Restore Chatrooms when the server is launched.
*/
const chatRooms = new ChatroomUsers();
//Seed the database
chatRoomsData.forEach(room => chatRooms.addNewRoom(room));
module.exports = (server, sessionMiddleware) => {
/**
* Create Socket IO server on the top of the http server.
*/
const io = socketIO(server);
// This io middleware sync the req.session object with
// the socketClient.handshake.session object in order to share
// the same session between express and socket.io.
// The Id of the session at the mongo store can be found
// as the socketClient.handshake.sessionID
io.use(sharedSession(sessionMiddleware), { autoSave: true });
io.on("connection", socketClient => {
const url = socketClient.handshake.headers.referer;
const username = socketClient.handshake.session.username;
const sessionID = socketClient.handshake.sessionID;
//Maintain all sockets of a user in the same chanel in order
//notify the rest of its sockets when the user logout
socketClient.join(sessionID);
//In case of logout, emit this to all user sockets
socketClient.on("logout", () => {
socketClient.to(sessionID).emit("logout");
});
//URL has to have a room name to join the socket to an
//specific room
if (url.includes("room")) {
const roomName = url.split("/").pop();
//Date string with format "d/m/yy hh:mm"(6/5/21 15:13)
let messageDate = new Date().toLocaleString("default", {
dateStyle: "short",
timeStyle: "short",
});
//Join the user socket to the corresponding chanel
socketClient.join(roomName);
//Join the user socket to its own room-username chanel
//This will allow me to handle the disconnection when
//the same user is connected to the same room using
//different browser tabs (each tab use a differnt socket).
socketClient.join(`${roomName}${username}`);
//Add the user to the list of online users of the given
//room and notify the rest of the users in the room.
//In case the use has been previously added, its name
//is not added to the list of online users and the
//notification is not sent.
if (chatRooms.addUserToChatroom(roomName, username)) {
const roomMessage = { username, messageDate };
// notify other users about the user connection
socketClient.to(roomName).emit("addOnlineUser", roomMessage);
}
//Listening for incomming room messages
socketClient.on("privateMessage", message => {
//Date string with format "d/m/yy hh:mm"(6/5/21 15:13)
let messageDate = new Date().toLocaleString("default", {
dateStyle: "short",
timeStyle: "short",
});
const roomMessage = { username, message, messageDate };
//Sent the incoming message to the room
socketClient.to(roomName).emit("privateMessage", roomMessage);
//Store the message in the database
chatRooms.addNewMessage(roomName, roomMessage);
});
socketClient.on("disconnect", async () => {
// get all sockets of a user for a given room
const matchingSockets = await io
.in(`${roomName}${username}`)
.allSockets();
// check if all user sockets for a given room are closed.
const isDisconnected = matchingSockets.size === 0;
if (isDisconnected) {
//Date string with format "d/m/yy hh:mm"(6/5/21 15:13)
let messageDate = new Date().toLocaleString("default", {
dateStyle: "short",
timeStyle: "short",
});
const roomMessage = { username, messageDate };
// notify other users about the user disconnection
socketClient.to(roomName).emit("removeOnlineUser", roomMessage);
//Remove user from onlineUser list in the database
chatRooms.removeUserFromChatroom(roomName, username);
}
});
}
});
};