forked from mirror/MCSM-Daemon
新增 直接与守护进程WS连接功能
This commit is contained in:
parent
b78e4e1a21
commit
415240b128
10
src/app.ts
10
src/app.ts
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @Author: Copyright(c) 2020 Suwings
|
||||
* @Date: 2020-11-23 17:45:02
|
||||
* @LastEditTime: 2021-07-15 22:50:51
|
||||
* @LastEditTime: 2021-07-16 19:00:10
|
||||
* @Description: Daemon service startup file
|
||||
*/
|
||||
|
||||
@ -65,7 +65,13 @@ const io = new Server(httpServer, {
|
||||
serveClient: false,
|
||||
pingInterval: 3000,
|
||||
pingTimeout: 5000,
|
||||
cookie: false
|
||||
cookie: false,
|
||||
path: "/socket.io",
|
||||
cors: {
|
||||
origin: "*",
|
||||
methods: ["GET", "POST"],
|
||||
credentials: true
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化应用实例系统 & 装载应用实例
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @Author: Copyright(c) 2020 Suwings
|
||||
* @Date: 2020-11-23 17:45:02
|
||||
* @LastEditTime: 2021-06-21 18:12:27
|
||||
* @LastEditTime: 2021-07-16 16:59:19
|
||||
* @Description: 身份认证控制器组
|
||||
* @Projcet: MCSManager Daemon
|
||||
* @License: MIT
|
||||
@ -16,7 +16,9 @@ import RouterContext from "../entity/ctx";
|
||||
// 权限认证中间件
|
||||
routerApp.use((event, ctx, _, next) => {
|
||||
const socket = ctx.socket;
|
||||
// 除 auth 控制器是公开访问,其他控制器必须得到授权才可访问
|
||||
// 放行所有数据流控制器
|
||||
if (event.startsWith("stream")) return next();
|
||||
// 除 auth 控制器是公开访问,其他业务控制器必须得到授权才可访问
|
||||
if (event === "auth") return next();
|
||||
if (!ctx.session) throw new Error("Session does not exist in authentication middleware.");
|
||||
// 若未验证则阻止除 auth 事件外的所有事件
|
||||
@ -53,7 +55,7 @@ routerApp.on("auth", (ctx, data) => {
|
||||
});
|
||||
|
||||
// 登录成功后必须执行此函数
|
||||
function loginSuccessful(ctx: RouterContext, data: any) {
|
||||
function loginSuccessful(ctx: RouterContext, data: string) {
|
||||
ctx.session.key = data;
|
||||
ctx.session.login = true;
|
||||
ctx.session.id = ctx.socket.id;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @Author: Copyright(c) 2020 Suwings
|
||||
* @Date: 2020-11-23 17:45:02
|
||||
* @LastEditTime: 2021-07-02 19:38:02
|
||||
* @LastEditTime: 2021-07-16 20:06:11
|
||||
* @Description: 应用实例所有主动性事件
|
||||
* @Projcet: MCSManager Daemon
|
||||
* @License: MIT
|
||||
@ -23,6 +23,7 @@ InstanceSubsystem.on("data", (instanceUuid: string, text: string) => {
|
||||
|
||||
// 实例退出事件
|
||||
InstanceSubsystem.on("exit", (obj: any) => {
|
||||
// 警告,重构后的广播是不安全的
|
||||
protocol.broadcast("instance/stopped", {
|
||||
instanceUuid: obj.instanceUuid,
|
||||
instanceName: obj.instanceName
|
||||
|
76
src/routers/stream_router.ts
Normal file
76
src/routers/stream_router.ts
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* @Author: Copyright(c) 2020 Suwings
|
||||
* @Date: 2021-06-22 22:44:06
|
||||
* @LastEditTime: 2021-07-16 19:25:05
|
||||
* @Description: 文件管理系统路由层
|
||||
* @Projcet: MCSManager Daemon
|
||||
* @License: MIT
|
||||
*/
|
||||
|
||||
import * as protocol from "../service/protocol";
|
||||
import { routerApp } from "../service/router";
|
||||
import { missionPassport } from "../service/mission_passport";
|
||||
import InstanceSubsystem from "../service/system_instance";
|
||||
import logger from '../service/log';
|
||||
import SendCommand from '../entity/commands/cmd';
|
||||
|
||||
// 权限认证中间件
|
||||
routerApp.use((event, ctx, data, next) => {
|
||||
// 放行数据流身份验证路由
|
||||
if (event === "stream/auth") return next();
|
||||
// 检查数据流其他路由
|
||||
if (event.startsWith("stream")) {
|
||||
if (ctx.session.stream && ctx.session.stream.check === true) {
|
||||
return next();
|
||||
}
|
||||
return protocol.error(ctx, "error", "权限不足,非法访问");
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
// 可公开访问数据流身份验证路由
|
||||
routerApp.on("stream/auth", (ctx, data) => {
|
||||
try {
|
||||
const password = data.password;
|
||||
const mission = missionPassport.getMission(password, "stream_channel");
|
||||
if (!mission) throw new Error("任务不存在");
|
||||
|
||||
// 实例UUID参数必须来自于任务参数,不可直接使用
|
||||
const instance = InstanceSubsystem.getInstance(mission.parameter.instanceUuid);
|
||||
if (!instance) throw new Error("实例不存在");
|
||||
|
||||
// 加入数据流认证标识
|
||||
logger.info(`会话 ${ctx.socket.id} ${ctx.socket.handshake.address} 数据流通道身份验证成功`);
|
||||
ctx.session.stream = {
|
||||
check: true,
|
||||
instanceUuid: instance.instanceUuid
|
||||
};
|
||||
|
||||
// 开始向此 Socket 转发输出流数据
|
||||
InstanceSubsystem.forward(instance.instanceUuid, ctx.socket);
|
||||
logger.info(`会话 ${ctx.socket.id} ${ctx.socket.handshake.address} 已与 ${instance.instanceUuid} 建立数据通道`);
|
||||
|
||||
// 注册断开时取消转发事件
|
||||
ctx.socket.on("disconnect", () => {
|
||||
InstanceSubsystem.stopForward(instance.instanceUuid, ctx.socket);
|
||||
logger.info(`会话 ${ctx.socket.id} ${ctx.socket.handshake.address} 已与 ${instance.instanceUuid} 断开数据通道`);
|
||||
});
|
||||
protocol.response(ctx, true);
|
||||
} catch (error) {
|
||||
protocol.responseError(ctx, error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 列出指定实例工作目录的文件列表
|
||||
routerApp.on("stream/input", (ctx, data) => {
|
||||
try {
|
||||
const command = data.command;
|
||||
const instanceUuid = ctx.session.stream.instanceUuid;
|
||||
const instance = InstanceSubsystem.getInstance(instanceUuid);
|
||||
instance.exec(new SendCommand(command));
|
||||
} catch (error) {
|
||||
protocol.responseError(ctx, error);
|
||||
}
|
||||
});
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @Author: Copyright(c) 2020 Suwings
|
||||
* @Date: 2020-11-23 17:45:02
|
||||
* @LastEditTime: 2021-07-16 15:28:47
|
||||
* @LastEditTime: 2021-07-16 19:32:02
|
||||
* @Description: Route navigator, used to analyze the Socket.io protocol and encapsulate and forward to a custom route
|
||||
* @Projcet: MCSManager Daemon
|
||||
* @License: MIT
|
||||
@ -54,8 +54,8 @@ export function navigation(socket: Socket) {
|
||||
// Register all middleware with Socket
|
||||
for (const fn of routerApp.getMiddlewares()) {
|
||||
socket.use((packet, next) => {
|
||||
const protocol = packet[1];
|
||||
if (!protocol) return logger.info(`session $(socket.id) request data protocol format is incorrect`);
|
||||
const protocol = packet[1] as IPacket;
|
||||
if (!protocol) return logger.info(`session ${socket.id} request data protocol format is incorrect`);
|
||||
const ctx = new RouterContext(protocol.uuid, socket, session);
|
||||
fn(packet[0], ctx, protocol.data, next);
|
||||
});
|
||||
@ -63,7 +63,7 @@ export function navigation(socket: Socket) {
|
||||
// Register all events with Socket
|
||||
for (const event of routerApp.eventNames()) {
|
||||
socket.on(event, (protocol: IPacket) => {
|
||||
if (!protocol) return logger.info(`session $(socket.id) request data protocol format is incorrect`);
|
||||
if (!protocol) return logger.info(`session ${socket.id} request data protocol format is incorrect`);
|
||||
const ctx = new RouterContext(protocol.uuid, socket, session, event.toString());
|
||||
routerApp.emitRouter(event as string, ctx, protocol.data);
|
||||
});
|
||||
@ -78,5 +78,6 @@ import "../routers/passport_router";
|
||||
import "../routers/Instance_router";
|
||||
import "../routers/instance_event_router";
|
||||
import "../routers/file_router";
|
||||
import "../routers/stream_router";
|
||||
|
||||
logger.info(`Complete. Total routing controller ${routerApp.eventNames().length}, middleware ${routerApp.middlewares.length}.`);
|
||||
|
Loading…
Reference in New Issue
Block a user