This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Socket Broker Test Client</title>
|
||||
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.status {
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.connected {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
.disconnected {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
.connecting {
|
||||
background-color: #fff3cd;
|
||||
color: #856404;
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.controls input,
|
||||
.controls button {
|
||||
margin: 5px;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.controls button {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
.controls button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.controls button:disabled {
|
||||
background-color: #6c757d;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.messages {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
.message {
|
||||
margin: 10px 0;
|
||||
padding: 10px;
|
||||
background-color: white;
|
||||
border-left: 4px solid #007bff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.message .topic {
|
||||
font-weight: bold;
|
||||
color: #007bff;
|
||||
}
|
||||
.message .timestamp {
|
||||
font-size: 0.8em;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.subscriptions {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.subscription {
|
||||
display: inline-block;
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
margin: 2px;
|
||||
border-radius: 15px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Socket Broker Test Client</h1>
|
||||
|
||||
<div id="status" class="status connecting">Connecting...</div>
|
||||
|
||||
<div class="controls">
|
||||
<h3>Topic Management</h3>
|
||||
<input
|
||||
type="text"
|
||||
id="topicInput"
|
||||
placeholder="Enter topic name"
|
||||
value="test-topic"
|
||||
/>
|
||||
<button onclick="subscribe()" id="subscribeBtn">Subscribe</button>
|
||||
<button onclick="unsubscribe()" id="unsubscribeBtn" disabled>
|
||||
Unsubscribe
|
||||
</button>
|
||||
<button onclick="clearMessages()">Clear Messages</button>
|
||||
</div>
|
||||
|
||||
<div class="subscriptions">
|
||||
<h3>Active Subscriptions</h3>
|
||||
<div id="subscriptionList"></div>
|
||||
</div>
|
||||
|
||||
<div class="messages">
|
||||
<h3>Messages</h3>
|
||||
<div id="messageList">No messages yet...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let socket;
|
||||
let currentTopic = "";
|
||||
let subscriptions = new Set();
|
||||
|
||||
// Initialize socket connection
|
||||
function initSocket() {
|
||||
socket = io("http://localhost:3000");
|
||||
|
||||
socket.on("connect", () => {
|
||||
updateStatus("Connected", "connected");
|
||||
document.getElementById("subscribeBtn").disabled = false;
|
||||
});
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
updateStatus("Disconnected", "disconnected");
|
||||
document.getElementById("subscribeBtn").disabled = true;
|
||||
document.getElementById("unsubscribeBtn").disabled = true;
|
||||
});
|
||||
|
||||
socket.on("subscribed", (data) => {
|
||||
console.log("Subscribed to topic:", data.topic);
|
||||
subscriptions.add(data.topic);
|
||||
currentTopic = data.topic;
|
||||
updateSubscriptionList();
|
||||
document.getElementById("unsubscribeBtn").disabled = false;
|
||||
addMessage(
|
||||
"System",
|
||||
`Subscribed to topic: ${data.topic}`,
|
||||
"subscription"
|
||||
);
|
||||
});
|
||||
|
||||
socket.on("unsubscribed", (data) => {
|
||||
console.log("Unsubscribed from topic:", data.topic);
|
||||
subscriptions.delete(data.topic);
|
||||
if (currentTopic === data.topic) {
|
||||
currentTopic = "";
|
||||
}
|
||||
updateSubscriptionList();
|
||||
if (subscriptions.size === 0) {
|
||||
document.getElementById("unsubscribeBtn").disabled = true;
|
||||
}
|
||||
addMessage(
|
||||
"System",
|
||||
`Unsubscribed from topic: ${data.topic}`,
|
||||
"subscription"
|
||||
);
|
||||
});
|
||||
|
||||
socket.on("message", (data) => {
|
||||
console.log("Received message:", data);
|
||||
addMessage(
|
||||
data.topic,
|
||||
data.message || "No message content",
|
||||
"message",
|
||||
data.data,
|
||||
data.timestamp
|
||||
);
|
||||
});
|
||||
|
||||
socket.on("error", (error) => {
|
||||
console.error("Socket error:", error);
|
||||
addMessage("Error", error.message, "error");
|
||||
});
|
||||
}
|
||||
|
||||
function updateStatus(text, className) {
|
||||
const statusEl = document.getElementById("status");
|
||||
statusEl.textContent = text;
|
||||
statusEl.className = `status ${className}`;
|
||||
}
|
||||
|
||||
function updateSubscriptionList() {
|
||||
const listEl = document.getElementById("subscriptionList");
|
||||
if (subscriptions.size === 0) {
|
||||
listEl.innerHTML = "<em>No active subscriptions</em>";
|
||||
} else {
|
||||
listEl.innerHTML = Array.from(subscriptions)
|
||||
.map((topic) => `<span class="subscription">${topic}</span>`)
|
||||
.join("");
|
||||
}
|
||||
}
|
||||
|
||||
function subscribe() {
|
||||
const topic = document.getElementById("topicInput").value.trim();
|
||||
if (!topic) {
|
||||
alert("Please enter a topic name");
|
||||
return;
|
||||
}
|
||||
|
||||
if (subscriptions.has(topic)) {
|
||||
alert("Already subscribed to this topic");
|
||||
return;
|
||||
}
|
||||
|
||||
socket.emit("subscribe", topic);
|
||||
}
|
||||
|
||||
function unsubscribe() {
|
||||
const topic = document.getElementById("topicInput").value.trim();
|
||||
if (!topic) {
|
||||
alert("Please enter a topic name");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!subscriptions.has(topic)) {
|
||||
alert("Not subscribed to this topic");
|
||||
return;
|
||||
}
|
||||
|
||||
socket.emit("unsubscribe", topic);
|
||||
}
|
||||
|
||||
function addMessage(topic, message, type, data = null, timestamp = null) {
|
||||
const messageList = document.getElementById("messageList");
|
||||
const messageEl = document.createElement("div");
|
||||
messageEl.className = `message ${type}`;
|
||||
|
||||
let content = `<div class="topic">${topic}</div>`;
|
||||
content += `<div>${message}</div>`;
|
||||
|
||||
if (data) {
|
||||
content += `<div><small>Data: ${JSON.stringify(data)}</small></div>`;
|
||||
}
|
||||
|
||||
content += `<div class="timestamp">${
|
||||
timestamp || new Date().toLocaleTimeString()
|
||||
}</div>`;
|
||||
|
||||
messageEl.innerHTML = content;
|
||||
|
||||
if (messageList.textContent === "No messages yet...") {
|
||||
messageList.innerHTML = "";
|
||||
}
|
||||
|
||||
messageList.appendChild(messageEl);
|
||||
messageList.scrollTop = messageList.scrollHeight;
|
||||
}
|
||||
|
||||
function clearMessages() {
|
||||
document.getElementById("messageList").innerHTML = "No messages yet...";
|
||||
}
|
||||
|
||||
// Initialize when page loads
|
||||
window.onload = function () {
|
||||
initSocket();
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user