Create web-socket.html
Browse files- web-socket.html +111 -0
web-socket.html
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="ja">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8" />
|
5 |
+
<title>管理ページ(IP・接続時間表示)</title>
|
6 |
+
<script src="https://cdn.socket.io/4.0.1/socket.io.min.js"></script>
|
7 |
+
<style>
|
8 |
+
table { border-collapse: collapse; width: 100%; }
|
9 |
+
th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }
|
10 |
+
th { background-color: #eee; }
|
11 |
+
.highlight {
|
12 |
+
background-color: #f99;
|
13 |
+
transition: background-color 1s ease;
|
14 |
+
}
|
15 |
+
</style>
|
16 |
+
</head>
|
17 |
+
<body>
|
18 |
+
<h1>現在の接続ユーザー数: <span id="userCount">0</span></h1>
|
19 |
+
<div>更新まで: <span id="countdown">5</span>秒</div>
|
20 |
+
<table>
|
21 |
+
<thead>
|
22 |
+
<tr>
|
23 |
+
<th>Socket ID</th>
|
24 |
+
<th>IPアドレス</th>
|
25 |
+
<th>接続時間</th>
|
26 |
+
<th>切断時間</th>
|
27 |
+
</tr>
|
28 |
+
</thead>
|
29 |
+
<tbody id="userTableBody"></tbody>
|
30 |
+
</table>
|
31 |
+
|
32 |
+
<script>
|
33 |
+
const socket = io("https://web-socket-server-14ap.onrender.com/");
|
34 |
+
|
35 |
+
// ローカルストレージのキー
|
36 |
+
const STORAGE_KEY = "userSessions";
|
37 |
+
|
38 |
+
// localStorageから前回セッション情報を取得(無ければ空オブジェクト)
|
39 |
+
let previousSessions = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
|
40 |
+
let countdown = 5;
|
41 |
+
|
42 |
+
const userCountElem = document.getElementById("userCount");
|
43 |
+
const countdownElem = document.getElementById("countdown");
|
44 |
+
const tbody = document.getElementById("userTableBody");
|
45 |
+
|
46 |
+
// カウントダウンタイマー
|
47 |
+
setInterval(() => {
|
48 |
+
countdown--;
|
49 |
+
if (countdown < 0) countdown = 5;
|
50 |
+
countdownElem.textContent = countdown;
|
51 |
+
}, 1000);
|
52 |
+
|
53 |
+
// 5秒ごとに更新要求(サーバーが自動送信なら不要)
|
54 |
+
setInterval(() => {
|
55 |
+
socket.emit("requestUserSessions");
|
56 |
+
}, 5000);
|
57 |
+
|
58 |
+
socket.on("updateUserCount", (count) => {
|
59 |
+
userCountElem.textContent = count;
|
60 |
+
});
|
61 |
+
|
62 |
+
socket.on("userSessionsUpdate", (userSessions) => {
|
63 |
+
tbody.innerHTML = "";
|
64 |
+
|
65 |
+
for (const [socketId, info] of Object.entries(userSessions)) {
|
66 |
+
const tr = document.createElement("tr");
|
67 |
+
|
68 |
+
function createTd(text, elementKey) {
|
69 |
+
const td = document.createElement("td");
|
70 |
+
td.textContent = text;
|
71 |
+
|
72 |
+
const prevValue = previousSessions[socketId] ? previousSessions[socketId][elementKey] : undefined;
|
73 |
+
const currValue = info[elementKey];
|
74 |
+
|
75 |
+
let changed = false;
|
76 |
+
if (elementKey === "connectTime" || elementKey === "disconnectTime") {
|
77 |
+
changed = prevValue !== currValue;
|
78 |
+
} else {
|
79 |
+
changed = prevValue !== currValue;
|
80 |
+
}
|
81 |
+
|
82 |
+
if (changed) {
|
83 |
+
td.classList.add("highlight");
|
84 |
+
setTimeout(() => td.classList.remove("highlight"), 1000);
|
85 |
+
}
|
86 |
+
|
87 |
+
return td;
|
88 |
+
}
|
89 |
+
|
90 |
+
tr.appendChild(createTd(socketId, "socketId"));
|
91 |
+
tr.appendChild(createTd(info.ip || "-", "ip"));
|
92 |
+
tr.appendChild(createTd(info.connectTime ? new Date(info.connectTime).toLocaleString() : "-", "connectTime"));
|
93 |
+
tr.appendChild(createTd(info.disconnectTime ? new Date(info.disconnectTime).toLocaleString() : "-", "disconnectTime"));
|
94 |
+
|
95 |
+
tbody.appendChild(tr);
|
96 |
+
}
|
97 |
+
|
98 |
+
// 今回のデータをlocalStorageに保存(ディープコピー推奨)
|
99 |
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(userSessions));
|
100 |
+
// previousSessionsも更新
|
101 |
+
previousSessions = JSON.parse(JSON.stringify(userSessions));
|
102 |
+
});
|
103 |
+
|
104 |
+
// 初回ロード時に前回のセッションを表示(あるなら)
|
105 |
+
if (Object.keys(previousSessions).length > 0) {
|
106 |
+
// 自己発火用の擬似的なイベントで描画のみ実施
|
107 |
+
socket.emit("userSessionsUpdate", previousSessions);
|
108 |
+
}
|
109 |
+
</script>
|
110 |
+
</body>
|
111 |
+
</html>
|