sing-song-player-3vx0f39v / web-socket.html
soiz1's picture
Update web-socket.html
045586e
raw
history blame
5.19 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>
</tr>
</thead>
<tbody id="userTableBody"></tbody>
</table>
<script>
const socket = io("https://web-socket-server-14ap.onrender.com/");
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", async (userSessions) => {
console.log("userSessionsUpdate受信", userSessions);
tbody.innerHTML = "";
for (let key in markers) {
map.removeLayer(markers[key]);
}
markers = {};
const positions = {};
for (const [socketId, info] of Object.entries(userSessions)) {
if (info.loc) {
const [lat, lon] = info.loc.split(',').map(parseFloat);
if (!isNaN(lat) && !isNaN(lon)) {
positions[socketId] = { lat, lon };
}
}
}
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]?.[elementKey];
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"));
tbody.appendChild(tr);
const pos = positions[socketId];
if (pos) {
const prevPos = previousSessions[socketId]?.geoPosition;
let changedPos = true;
if (prevPos && Math.abs(prevPos.lat - pos.lat) < 0.0001 && Math.abs(prevPos.lon - pos.lon) < 0.0001) {
changedPos = false;
}
const color = info.disconnectTime
? "gray"
: changedPos
? "red"
: "black";
const marker = createCircleMarker(pos.lat, pos.lon, color, `SocketID: ${socketId}<br>IP: ${info.ip || "-"}`);
marker.addTo(map);
markers[socketId] = marker;
}
}
const markerPositions = Object.values(markers).map(m => m.getLatLng());
if (markerPositions.length > 0) {
const group = L.featureGroup(Object.values(markers));
map.fitBounds(group.getBounds().pad(0.5));
}
const sessionsToStore = {};
for (const [socketId, info] of Object.entries(userSessions)) {
sessionsToStore[socketId] = {
...info,
geoPosition: positions[socketId] || null
};
}
localStorage.setItem(STORAGE_KEY, JSON.stringify(sessionsToStore));
previousSessions = sessionsToStore;
});
</script>
</body>
</html>