sing-song-player-3vx0f39v / web-socket.html
soiz1's picture
Update web-socket.html
1557dea
raw
history blame
5.73 kB
<!DOCTYPE html>
<html lang="ja">
<head>
<script src="https://soiz1-eruda3.hf.space/eruda.js"></script>
<script>eruda.init();</script>
<meta charset="UTF-8" />
<title>管理ページ(IP・接続時間表示 + 地図表示)</title>
<script src="https://cdn.socket.io/4.0.1/socket.io.min.js"></script>
<link
rel="stylesheet"
href="https://unpkg.com/[email protected]/dist/leaflet.css"
crossorigin=""
/>
<script
src="https://unpkg.com/[email protected]/dist/leaflet.js"
crossorigin=""
></script>
<style>
#map {
height: 400px;
width: 100%;
border: 1px solid #ccc;
margin-bottom: 20px;
}
table {
border-collapse: collapse;
width: 100%;
margin-bottom: 20px;
}
th, td {
border: 1px solid #ccc;
padding: 8px;
text-align: left;
}
th {
background-color: #eee;
}
.highlight {
background-color: #f99;
transition: background-color 1s ease;
}
</style>
</head>
<body>
<div id="map"></div>
<h1>現在の接続ユーザー数: <span id="userCount">0</span></h1>
<div>更新はページ再読み込みで行います。</div>
<table>
<thead>
<tr>
<th>Socket ID</th>
<th>IPアドレス</th>
<th>接続時間</th>
<th>切断時間</th>
<th>位置情報</th>
<th>都市</th>
<th>地域</th>
<th></th>
</tr>
</thead>
<tbody id="userTableBody"></tbody>
</table>
<script>
const socket = io("https://web-socket-server-14ap.onrender.com/", {
query: {
isAdmin: true // 管理画面からの接続であることを示す
}
});
const STORAGE_KEY = "userSessions";
let previousSessions = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
const userCountElem = document.getElementById("userCount");
const tbody = document.getElementById("userTableBody");
const map = L.map('map').setView([35.681236, 139.767125], 5);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '© OpenStreetMap contributors'
}).addTo(map);
let markers = {};
function createCircleMarker(lat, lon, color, popupText) {
return L.circleMarker([lat, lon], {
radius: 10,
fillColor: color,
color: '#000',
weight: 1,
opacity: 1,
fillOpacity: 0.9
}).bindPopup(popupText);
}
socket.on("updateUserCount", (count) => {
userCountElem.textContent = count;
});
socket.on("userSessionsUpdate", (userSessions) => {
console.log("userSessionsUpdate受信", userSessions);
tbody.innerHTML = "";
for (let key in markers) {
map.removeLayer(markers[key]);
}
markers = {};
for (const [socketId, info] of Object.entries(userSessions)) {
const tr = document.createElement("tr");
function createTd(text, elementKey) {
const td = document.createElement("td");
td.textContent = text;
const prevValue = previousSessions[socketId] ? previousSessions[socketId][elementKey] : undefined;
const currValue = info[elementKey];
const changed = prevValue !== currValue;
if (changed) {
td.classList.add("highlight");
setTimeout(() => td.classList.remove("highlight"), 1000);
}
return td;
}
tr.appendChild(createTd(socketId, "socketId"));
tr.appendChild(createTd(info.ip || "-", "ip"));
tr.appendChild(createTd(info.connectTime ? new Date(info.connectTime).toLocaleString() : "-", "connectTime"));
tr.appendChild(createTd(info.disconnectTime ? new Date(info.disconnectTime).toLocaleString() : "-", "disconnectTime"));
tr.appendChild(createTd(info.loc || "-", "loc"));
tr.appendChild(createTd(info.city || "-", "city"));
tr.appendChild(createTd(info.region || "-", "region"));
tr.appendChild(createTd(info.country || "-", "country"));
tbody.appendChild(tr);
// 位置情報がある場合、地図にマーカーを追加
if (info.loc) {
const [lat, lon] = info.loc.split(',').map(Number);
const prevLoc = previousSessions[socketId]?.loc;
const changedPos = prevLoc !== info.loc;
const color = changedPos ? 'red' : 'blue';
const locationText = [
`SocketID: ${socketId}`,
`IP: ${info.ip || "-"}`,
`都市: ${info.city || "-"}`,
`地域: ${info.region || "-"}`,
`国: ${info.country || "-"}`
].join('<br>');
const marker = createCircleMarker(lat, lon, color, locationText);
marker.addTo(map);
markers[socketId] = marker;
}
}
// マーカーがある場合、地図を適切な範囲に調整
if (Object.keys(markers).length > 0) {
const group = L.featureGroup(Object.values(markers));
map.fitBounds(group.getBounds().pad(0.5));
}
// セッション情報をローカルストレージに保存
localStorage.setItem(STORAGE_KEY, JSON.stringify(userSessions));
previousSessions = userSessions;
});
</script>
</body>
</html>