Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ab4de44
fix: replace UUID generation with custom request ID function
AxiosLeo May 15, 2025
f68e441
feat: implement socket workflow with request handling and validation
AxiosLeo May 15, 2025
68c56e1
fix: correct SocketApplication import path in index.js
AxiosLeo May 15, 2025
a0c6379
feat: add utility functions and SocketClient class for enhanced socke…
AxiosLeo May 29, 2025
6d935ff
fix: update request ID generation to use _uuid_salt for improved uniq…
AxiosLeo May 29, 2025
85f8068
feat: enhance VSCode launch configuration and add socket client/serve…
AxiosLeo Jun 4, 2025
fc3c023
feat: enhance socket ping functionality and improve request ID genera…
AxiosLeo Jun 4, 2025
8c481df
feat: add SocketContext and SocketApplication classes for enhanced so…
AxiosLeo Jun 4, 2025
75dc866
fix: correct error handling in socket client by enabling error logging
AxiosLeo Jun 4, 2025
8a5b900
feat: add WebSocketApplication class and update index.js to include W…
AxiosLeo Jul 7, 2025
3becef8
feat: implement API router and WebSocket server with HTML client for …
AxiosLeo Jul 7, 2025
ae35a53
feat: add ws dependency for WebSocket support in the project
AxiosLeo Jul 7, 2025
6dcbdac
feat: update VSCode launch configuration with clearer names and add W…
AxiosLeo Jul 7, 2025
df4ee00
feat: enhance API router logging by including query, body, and test p…
AxiosLeo Jul 7, 2025
c8869cd
feat: update WebSocketApplication to accept custom websocket options …
AxiosLeo Jul 7, 2025
7251d06
refactor: improve connection handling
AxiosLeo Jul 8, 2025
e4a74b6
feat: enhance types
AxiosLeo Jul 8, 2025
45c22a2
fix: correct initContext function type clarity
AxiosLeo Jul 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,42 @@
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"name": "Web server",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/bin/koapp.js",
"args": ["http", "-p", "8080"]
},
{
"type": "node",
"request": "launch",
"name": "Test Program",
"name": "Test web server",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/tests/bootstrap.js",
"args": []
},
{
"type": "node",
"request": "launch",
"name": "Example: Socket Client",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/examples/socket.client.js",
"args": []
},
{
"type": "node",
"request": "launch",
"name": "Example: Socket Server",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/examples/socket.server.js",
"args": []
},
{
"type": "node",
"request": "launch",
"name": "Example: WebSocket Server",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/examples/websocket.server.js",
"args": []
}
]
}
34 changes: 34 additions & 0 deletions examples/api.router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const { success } = require('../src/response');

const { Router } = require('..');
const { debug } = require('@axiosleo/cli-tool');

const root = new Router(null, {
middlewares: [async (context) => {
debug.log(`[${context.app_id}] ${context.method}: ${context.router.pathinfo}`);
}],
afters: [async (context) => {
debug.log({
query: context.query,
body: context.body,
test: context.params.id
});
}]
});

root.get('/api/test/{:id}', async (context) => {
success({
query: context.query,
body: context.body,
test: context.params.id
});
});

root.any('/***', async (context) => {
success({
query: context.query,
body: context.body
});
});

module.exports = root;
41 changes: 41 additions & 0 deletions examples/socket.client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

const { debug } = require('@axiosleo/cli-tool');
const { _sleep } = require('@axiosleo/cli-tool/src/helper/cmd');
const { SocketClient } = require('..');

let client = null;

/**
* @returns {SocketClient}
*/
function getClient() {
if (!client) {
client = new SocketClient();
}
return client;
}

async function main() {
try {
const client = getClient();
await client.send('get', '/api/test/123', {
test: 123
}, {
data: {
t: 1
}
});
} catch (err) {
debug.log('error', err.code);
}

await _sleep(3000);
process.nextTick(main);
}

main().then(() => {
// debug.log('done');
}).catch((err) => {
debug.log(err);
});
16 changes: 16 additions & 0 deletions examples/socket.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const SocketApplication = require('../src/apps/socket');

const root = require('./api.router');

const app = new SocketApplication({
routers: [root],
ping: {
open: true,
interval: 1000 * 10,
data: 'this is a ping message.'
}
});

app.start();
192 changes: 192 additions & 0 deletions examples/socket.web.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WebSocket Example</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.container {
display: flex;
flex-direction: column;
gap: 20px;
}
.status {
padding: 10px;
border-radius: 4px;
margin-bottom: 10px;
}
.connected {
background-color: #d4edda;
color: #155724;
}
.disconnected {
background-color: #f8d7da;
color: #721c24;
}
.message-container {
border: 1px solid #ddd;
padding: 10px;
height: 300px;
overflow-y: auto;
margin-bottom: 10px;
}
.message {
margin: 5px 0;
padding: 5px;
border-radius: 4px;
}
.received {
background-color: #e9ecef;
}
.sent {
background-color: #cce5ff;
text-align: right;
}
.input-group {
display: flex;
gap: 10px;
}
input[type="text"] {
flex: 1;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 8px 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="container">
<h1>WebSocket Example</h1>

<div id="status" class="status disconnected">Disconnected</div>

<div class="input-group">
<input
type="text"
id="serverUrl"
value="ws://localhost:8081/api/test/123"
placeholder="WebSocket Server URL"
/>
<button id="connectBtn">Connect</button>
<button id="disconnectBtn" disabled>Disconnect</button>
</div>

<div id="messageContainer" class="message-container"></div>

<div class="input-group">
<input
type="text"
id="messageInput"
placeholder="Type your message..."
disabled
/>
<button id="sendBtn" disabled>Send</button>
</div>
</div>

<script>
let socket = null;
const statusDiv = document.getElementById("status");
const serverUrlInput = document.getElementById("serverUrl");
const messageInput = document.getElementById("messageInput");
const messageContainer = document.getElementById("messageContainer");
const connectBtn = document.getElementById("connectBtn");
const disconnectBtn = document.getElementById("disconnectBtn");
const sendBtn = document.getElementById("sendBtn");

function updateStatus(connected) {
statusDiv.className = `status ${
connected ? "connected" : "disconnected"
}`;
statusDiv.textContent = connected ? "Connected" : "Disconnected";

connectBtn.disabled = connected;
disconnectBtn.disabled = !connected;
messageInput.disabled = !connected;
sendBtn.disabled = !connected;
}

function addMessage(message, type) {
const messageDiv = document.createElement("div");
messageDiv.className = `message ${type}`;
messageDiv.textContent = message;
messageContainer.appendChild(messageDiv);
messageContainer.scrollTop = messageContainer.scrollHeight;
}

connectBtn.addEventListener("click", () => {
const url = serverUrlInput.value;
try {
socket = new WebSocket(url);

socket.onopen = () => {
updateStatus(true);
addMessage("Connected to server", "received");
};

socket.onclose = () => {
updateStatus(false);
addMessage("Disconnected from server", "received");
};

socket.onerror = (error) => {
console.error("WebSocket error:", error);
addMessage("Error occurred", "received");
};

socket.onmessage = (event) => {
addMessage(`Received: ${event.data}`, "received");
};
} catch (error) {
console.error("Connection error:", error);
addMessage("Failed to connect", "received");
}
});

disconnectBtn.addEventListener("click", () => {
if (socket) {
socket.close();
socket = null;
}
});

sendBtn.addEventListener("click", () => {
const message = messageInput.value;
const url = serverUrlInput.value;
const urlObj = new URL(url);
if (message && socket) {
socket.send(JSON.stringify({ message }));
addMessage(`Sent: ${message}`, "sent");
messageInput.value = "";
}
});

messageInput.addEventListener("keypress", (event) => {
if (event.key === "Enter") {
sendBtn.click();
}
});
</script>
</body>
</html>
14 changes: 14 additions & 0 deletions examples/websocket.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const { WebSocketApplication } = require('../src/apps');
const root = require('./api.router');

const app = new WebSocketApplication({
routers: [root],
port: 8081,
ping: {
open: false,
interval: 1000 * 3,
data: 'this is a ping message'
}
});

app.start();
Loading