mira-app-core
Version:
Core library for Mira TypeScript project - provides base functionality without auto-execution
162 lines • 5.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MiraWebsocketServer = void 0;
const ws_1 = require("ws");
const WebSocketRouter_1 = require("./WebSocketRouter");
const event_manager_1 = require("./event-manager");
class MiraWebsocketServer {
constructor(port, backend) {
this.libraryClients = {};
this.port = port;
this.backend = backend;
this.libraries = this.backend.libraries;
}
async start(basePath) {
this.wss = new ws_1.WebSocketServer({ port: this.port });
this.wss.on('connection', (ws, request) => {
const urlString = request.url ?? '';
const url = new URL(urlString, `ws://${request.headers.host}`);
const clientId = url.searchParams.get('clientId');
const libraryId = url.searchParams.get('libraryId');
if (clientId == null || libraryId == null) {
return ws.close();
}
// 将请求信息保存到 ws 对象上
Object.assign(ws, {
clientId: clientId,
libraryId: libraryId,
requestInfo: {
url: request.url,
headers: request.headers,
remoteAddress: request.socket.remoteAddress
}
});
// 保存连接
if (!this.libraryClients[libraryId]) {
this.libraryClients[libraryId] = [];
}
if (!this.libraryClients[libraryId].includes(ws)) {
this.libraryClients[libraryId].push(ws);
}
this.handleConnection(ws);
});
console.log(`[!]Serving at ws://localhost:${this.port}`);
}
broadcastToClients(eventName, eventData) {
const obj = this.libraries.get(eventData.libraryId);
if (obj) {
const eventManager = obj.eventManager;
if (eventManager) {
eventManager.broadcast(eventName, new event_manager_1.EventArgs(eventName, eventData));
}
}
}
getWsClientById(libraryId, clientId) {
const clients = this.libraryClients[libraryId];
if (clients) {
return clients.find((client) => client.clientId === clientId);
}
}
showDialogToWeboscket(ws, data) {
this.sendToWebsocket(ws, {
eventName: 'dialog', data: Object.assign({
title: '提示',
message: '',
url: ''
}, data)
});
}
sendToWebsocket(ws, data) {
ws.send(JSON.stringify(data));
}
broadcastPluginEvent(eventName, data) {
const libraryId = data?.libraryId ?? data?.message?.libraryId;
const obj = this.libraries.get(libraryId);
if (obj) {
const eventManager = obj.eventManager;
if (eventManager) {
return eventManager.broadcast(eventName, new event_manager_1.EventArgs(eventName, data));
}
}
return Promise.resolve(false);
}
handleConnection(ws) {
ws.on('message', async (message) => {
try {
const data = JSON.parse(message);
await this.handleMessage(ws, data);
}
catch (e) {
this.sendToWebsocket(ws, {
error: 'Invalid message format',
details: e instanceof Error ? e.message : String(e)
});
}
});
ws.on('close', () => {
// Remove from all library client lists
Object.keys(this.libraryClients).forEach(libraryId => {
const index = this.libraryClients[libraryId].findIndex(client => client === ws);
console.log({ index });
if (index !== -1) {
this.libraryClients[libraryId].splice(index, 1);
}
});
});
}
async handleMessage(ws, row) {
const payload = row.payload || {};
const action = row.action;
const requestId = row.requestId;
const libraryId = row.libraryId;
const data = payload.data || {};
const recordType = payload.type;
const exists = this.libraries.exists(libraryId);
if (!exists) {
this.sendToWebsocket(ws, {
status: 'error',
msg: 'Library not found!'
});
return;
}
const obj = this.libraries.get(libraryId);
if (!obj) {
this.sendToWebsocket(ws, {
status: 'error',
msg: 'Library service not found'
});
return;
}
const handler = await WebSocketRouter_1.WebSocketRouter.route(this, obj.libraryService, ws, {
...row,
...payload
});
if (handler) {
await handler.handle();
}
else {
this.sendToWebsocket(ws, {
status: 'error',
message: `Unsupported action: ${action} and record type: ${recordType}`,
requestId
});
}
}
broadcastLibraryEvent(libraryId, eventName, data) {
const message = JSON.stringify({ eventName: eventName, data: data });
if (this.libraryClients[libraryId]) {
this.libraryClients[libraryId].forEach(client => {
if (client.readyState === ws_1.WebSocket.OPEN) {
client.send(message);
}
});
}
}
async stop() {
this.libraries.clear();
this.wss?.close();
console.log('WebSocket server stopped');
}
}
exports.MiraWebsocketServer = MiraWebsocketServer;
//# sourceMappingURL=WebSocketServer.js.map