Skip to content

Commit 481ef22

Browse files
feat: add page displaying all events
1 parent 77ee068 commit 481ef22

File tree

11 files changed

+280
-32
lines changed

11 files changed

+280
-32
lines changed

lib/index.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,11 @@ const registerListeners = (
334334
socket.data[key] = createProxy(data[key]);
335335
}
336336

337-
adminNamespace.emit("socket_connected", serialize(socket, nsp.name));
337+
adminNamespace.emit(
338+
"socket_connected",
339+
serialize(socket, nsp.name),
340+
new Date()
341+
);
338342

339343
socket.conn.on("upgrade", (transport: any) => {
340344
socket.data._admin.transport = transport.name;
@@ -346,17 +350,23 @@ const registerListeners = (
346350
});
347351

348352
socket.on("disconnect", (reason: string) => {
349-
adminNamespace.emit("socket_disconnected", nsp.name, socket.id, reason);
353+
adminNamespace.emit(
354+
"socket_disconnected",
355+
nsp.name,
356+
socket.id,
357+
reason,
358+
new Date()
359+
);
350360
});
351361
});
352362

353363
nsp.adapter.on("join-room", (room: string, id: string) => {
354-
adminNamespace.emit("room_joined", nsp.name, room, id);
364+
adminNamespace.emit("room_joined", nsp.name, room, id, new Date());
355365
});
356366

357367
nsp.adapter.on("leave-room", (room: string, id: string) => {
358368
process.nextTick(() => {
359-
adminNamespace.emit("room_left", nsp.name, room, id);
369+
adminNamespace.emit("room_left", nsp.name, room, id, new Date());
360370
});
361371
});
362372
};

lib/typed-events.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,16 @@ export interface ServerEvents {
3636
config: (config: Config) => void;
3737
server_stats: (stats: ServerStats) => void;
3838
all_sockets: (sockets: SerializedSocket[]) => void;
39-
socket_connected: (socket: SerializedSocket) => void;
39+
socket_connected: (socket: SerializedSocket, timestamp: Date) => void;
4040
socket_updated: (socket: Partial<SerializedSocket>) => void;
41-
socket_disconnected: (nsp: string, id: string, reason: string) => void;
42-
room_joined: (nsp: string, room: string, id: string) => void;
43-
room_left: (nsp: string, room: string, id: string) => void;
41+
socket_disconnected: (
42+
nsp: string,
43+
id: string,
44+
reason: string,
45+
timestamp: Date
46+
) => void;
47+
room_joined: (nsp: string, room: string, id: string, timestamp: Date) => void;
48+
room_left: (nsp: string, room: string, id: string, timestamp: Date) => void;
4449
}
4550

4651
export interface ClientEvents {

test/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ describe("Socket.IO Admin (server instrumentation)", () => {
264264

265265
// connect
266266
const serverSocket = await waitFor(io, "connection");
267-
const socket = await waitFor(adminSocket, "socket_connected");
267+
const [socket] = await waitFor(adminSocket, "socket_connected");
268268

269269
expect(socket.id).to.eql(serverSocket.id);
270270
expect(socket.nsp).to.eql("/");
@@ -329,7 +329,7 @@ describe("Socket.IO Admin (server instrumentation)", () => {
329329

330330
const serverSocket = await waitFor(io, "connection");
331331

332-
const socket = await waitFor(adminSocket, "socket_connected");
332+
const [socket] = await waitFor(adminSocket, "socket_connected");
333333
expect(socket.data).to.eql({ count: 1, array: [1] });
334334

335335
serverSocket.data.count++;
@@ -401,7 +401,7 @@ describe("Socket.IO Admin (server instrumentation)", () => {
401401
forceNew: true,
402402
});
403403

404-
const socket = await waitFor(adminSocket, "socket_connected");
404+
const [socket] = await waitFor(adminSocket, "socket_connected");
405405

406406
expect(socket.nsp).to.eql("/dynamic-101");
407407
clientSocket.disconnect();

ui/src/App.vue

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ import {
4040
VSlideYReverseTransition,
4141
} from "vuetify/lib";
4242
43+
// created on the client side, for backward compatibility
44+
function defaultTimestamp() {
45+
return new Date().toISOString();
46+
}
47+
4348
export default {
4449
name: "App",
4550
@@ -153,25 +158,41 @@ export default {
153158
socket.on("all_sockets", (sockets) => {
154159
this.$store.commit("main/onAllSockets", sockets);
155160
});
156-
socket.on("socket_connected", (socket) => {
157-
this.$store.commit("main/onSocketConnected", socket);
158-
});
161+
socket.on(
162+
"socket_connected",
163+
(socket, timestamp = defaultTimestamp()) => {
164+
this.$store.commit("main/onSocketConnected", {
165+
timestamp,
166+
socket,
167+
});
168+
}
169+
);
159170
socket.on("socket_updated", (socket) => {
160171
this.$store.commit("main/onSocketUpdated", socket);
161172
});
162-
socket.on("socket_disconnected", (nsp, id, reason) => {
163-
this.$store.commit("main/onSocketDisconnected", {
164-
nsp,
165-
id,
166-
reason,
167-
});
168-
});
169-
socket.on("room_joined", (nsp, room, id) => {
170-
this.$store.commit("main/onRoomJoined", { nsp, room, id });
171-
});
172-
socket.on("room_left", (nsp, room, id) => {
173-
this.$store.commit("main/onRoomLeft", { nsp, room, id });
174-
});
173+
socket.on(
174+
"socket_disconnected",
175+
(nsp, id, reason, timestamp = defaultTimestamp()) => {
176+
this.$store.commit("main/onSocketDisconnected", {
177+
timestamp,
178+
nsp,
179+
id,
180+
reason,
181+
});
182+
}
183+
);
184+
socket.on(
185+
"room_joined",
186+
(nsp, room, id, timestamp = defaultTimestamp()) => {
187+
this.$store.commit("main/onRoomJoined", { timestamp, nsp, room, id });
188+
}
189+
);
190+
socket.on(
191+
"room_left",
192+
(nsp, room, id, timestamp = defaultTimestamp()) => {
193+
this.$store.commit("main/onRoomLeft", { timestamp, nsp, room, id });
194+
}
195+
);
175196
},
176197
177198
onSubmit(form) {

ui/src/components/EventType.vue

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<template>
2+
<v-chip :color="color" outlined>
3+
{{ $t("events.type." + type) }}
4+
</v-chip>
5+
</template>
6+
7+
<script>
8+
import colors from "vuetify/lib/util/colors";
9+
10+
export default {
11+
name: "EventType",
12+
13+
props: {
14+
type: String,
15+
},
16+
17+
computed: {
18+
color() {
19+
switch (this.type) {
20+
case "connection":
21+
return colors.green.base;
22+
case "room_joined":
23+
return colors.teal.base;
24+
case "room_left":
25+
return colors.amber.base;
26+
case "disconnection":
27+
return colors.red.base;
28+
}
29+
return colors.gray.base;
30+
},
31+
},
32+
};
33+
</script>

ui/src/components/NavigationDrawer.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ export default {
6767
icon: "mdi-account-circle-outline",
6868
to: { name: "clients" },
6969
},
70+
{
71+
title: this.$t("events.title"),
72+
icon: "mdi-calendar-text-outline",
73+
to: { name: "events" },
74+
},
7075
{
7176
title: this.$t("servers.title"),
7277
icon: "mdi-server",

ui/src/locales/en.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"connected": "connected",
1616
"disconnected": "disconnected",
1717
"data": "Data",
18+
"timestamp": "Timestamp",
19+
"args": "Arguments",
1820
"connection": {
1921
"title": "Connection",
2022
"serverUrl": "Server URL",
@@ -84,5 +86,14 @@
8486
"language": "Language",
8587
"readonly": "Read-only?",
8688
"dark-theme": "Dark theme?"
89+
},
90+
"events": {
91+
"title": "Events",
92+
"type": {
93+
"connection": "Connection",
94+
"disconnection": "Disconnection",
95+
"room_joined": "Room joined",
96+
"room_left": "Room left"
97+
}
8798
}
8899
}

ui/src/locales/fr.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
"status": "Statut",
1515
"connected": "connecté",
1616
"disconnected": "déconnecté",
17+
"data": "Données",
18+
"timestamp": "Horodatage",
19+
"args": "Arguments",
1720
"connection": {
1821
"title": "Connexion",
1922
"serverUrl": "URL du serveur",
@@ -80,5 +83,14 @@
8083
"language": "Langue",
8184
"readonly": "Lecture seule ?",
8285
"dark-theme": "Mode sombre ?"
86+
},
87+
"events": {
88+
"title": "Évènements",
89+
"type": {
90+
"connection": "Connexion",
91+
"disconnection": "Déconnexion",
92+
"room_joined": "Salle rejointe",
93+
"room_left": "Salle quittée"
94+
}
8395
}
8496
}

ui/src/router/index.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Clients from "../views/Clients";
88
import Client from "../views/Client";
99
import Servers from "../views/Servers";
1010
import Room from "../views/Room";
11+
import Events from "@/views/Events";
1112

1213
Vue.use(VueRouter);
1314

@@ -72,13 +73,22 @@ const routes = [
7273
topLevel: false,
7374
},
7475
},
76+
{
77+
path: "/events/",
78+
name: "events",
79+
component: Events,
80+
meta: {
81+
topLevel: true,
82+
index: 4,
83+
},
84+
},
7585
{
7686
path: "/servers/",
7787
name: "servers",
7888
component: Servers,
7989
meta: {
8090
topLevel: true,
81-
index: 4,
91+
index: 5,
8292
},
8393
},
8494
];

ui/src/store/modules/main.js

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const getOrCreateNamespace = (namespaces, name) => {
1010
name,
1111
sockets: [],
1212
rooms: [],
13+
events: [],
1314
};
1415
namespaces.push(namespace);
1516
return namespace;
@@ -64,6 +65,17 @@ const addSocket = (state, socket) => {
6465
}
6566
};
6667

68+
const MAX_ARRAY_LENGTH = 1000;
69+
let EVENT_COUNTER = 0;
70+
71+
const pushEvents = (array, event) => {
72+
event.eventId = ++EVENT_COUNTER; // unique id
73+
array.push(event);
74+
if (array.length > MAX_ARRAY_LENGTH) {
75+
array.shift();
76+
}
77+
};
78+
6779
export default {
6880
namespaced: true,
6981
state: {
@@ -97,6 +109,9 @@ export default {
97109
rooms: (state) => {
98110
return state.selectedNamespace ? state.selectedNamespace.rooms : [];
99111
},
112+
events: (state) => {
113+
return state.selectedNamespace ? state.selectedNamespace.events : [];
114+
},
100115
},
101116
mutations: {
102117
selectNamespace(state, namespace) {
@@ -114,8 +129,14 @@ export default {
114129
find(state.namespaces, { name: "/" }) || state.namespaces[0];
115130
}
116131
},
117-
onSocketConnected(state, socket) {
132+
onSocketConnected(state, { timestamp, socket }) {
118133
addSocket(state, socket);
134+
const namespace = getOrCreateNamespace(state.namespaces, socket.nsp);
135+
pushEvents(namespace.events, {
136+
type: "connection",
137+
timestamp,
138+
id: socket.id,
139+
});
119140
},
120141
onSocketUpdated(state, socket) {
121142
const namespace = getOrCreateNamespace(state.namespaces, socket.nsp);
@@ -124,7 +145,7 @@ export default {
124145
merge(existingSocket, socket);
125146
}
126147
},
127-
onSocketDisconnected(state, { nsp, id }) {
148+
onSocketDisconnected(state, { timestamp, nsp, id, reason }) {
128149
const namespace = getOrCreateNamespace(state.namespaces, nsp);
129150
const [socket] = remove(namespace.sockets, { id });
130151
if (socket) {
@@ -137,17 +158,29 @@ export default {
137158
remove(state.clients, { id: socket.clientId });
138159
}
139160
}
161+
pushEvents(namespace.events, {
162+
type: "disconnection",
163+
timestamp,
164+
id,
165+
args: reason,
166+
});
140167
},
141-
onRoomJoined(state, { nsp, room, id }) {
168+
onRoomJoined(state, { nsp, room, id, timestamp }) {
142169
const namespace = getOrCreateNamespace(state.namespaces, nsp);
143170
const socket = find(namespace.sockets, { id });
144171
if (socket) {
145172
pushUniq(socket.rooms, room);
146173
const _room = getOrCreateRoom(namespace, room);
147174
_room.sockets.push(socket);
148175
}
176+
pushEvents(namespace.events, {
177+
type: "room_joined",
178+
timestamp,
179+
id,
180+
args: room,
181+
});
149182
},
150-
onRoomLeft(state, { nsp, room, id }) {
183+
onRoomLeft(state, { timestamp, nsp, room, id }) {
151184
const namespace = getOrCreateNamespace(state.namespaces, nsp);
152185
const socket = find(namespace.sockets, { id });
153186
if (socket) {
@@ -159,6 +192,12 @@ export default {
159192
_room.active = false;
160193
remove(namespace.rooms, { name: room });
161194
}
195+
pushEvents(namespace.events, {
196+
type: "room_left",
197+
timestamp,
198+
id,
199+
args: room,
200+
});
162201
},
163202
},
164203
};

0 commit comments

Comments
 (0)