71 lines
3.1 KiB
C++
71 lines
3.1 KiB
C++
// sub_conn_thread.h
|
||
// Linux/macOS 客户端子连接 worker 线程的统一骨架。
|
||
//
|
||
// 各 worker 线程(Shell / ScreenSpy / FileManager / SystemManager 等)共有的步骤:
|
||
// 1. new IOCPClient(g_bExit, exit_while_disconnect=true)
|
||
// 2. Enter log
|
||
// 3. EnableSubConnAuth(true, g_myClientID)(子连接强制 ConnAuth)
|
||
// 4. ConnectServer(内部会执行 PerformConnAuth;失败返 false)
|
||
// 5. 创建 platform handler
|
||
// 6. setManagerCallBack 装回调
|
||
// 7. 调 onReady(发首包:TOKEN_TERMINAL_START / SendBitmapInfo() 等)
|
||
// 8. while (running && connected && !g_bExit) Sleep
|
||
// 9. 清回调防止 dangling
|
||
// 10. Leave log
|
||
// 11. catch exceptions
|
||
//
|
||
// 平台差异(通过 lambda 注入):
|
||
// - HandlerT:PTYHandler / ScreenHandler / SystemManager / FileManager
|
||
// - createHandler 可返回 nullptr 表示初始化失败(如 macOS ScreenHandler 无录屏权限)
|
||
// - onReady 完成首包发送或额外 setup
|
||
//
|
||
// 用法见 linux/main.cpp / macos/main.mm 的 *workingThread 调用点。
|
||
#pragma once
|
||
|
||
#include <memory>
|
||
#include <stdexcept>
|
||
|
||
#include "client/IOCPClient.h"
|
||
#include "common/commands.h"
|
||
#include "common/logger.h"
|
||
|
||
extern State g_bExit;
|
||
extern uint64_t g_myClientID;
|
||
extern CONNECT_ADDRESS g_SETTINGS;
|
||
|
||
// 子连接 worker 线程通用骨架。
|
||
//
|
||
// CreateFn 签名: std::unique_ptr<HandlerT>(IOCPClient*)
|
||
// 返回 nullptr 表示初始化失败(如权限拒绝),线程会跳过 callback 安装直接 leave。
|
||
// OnReadyFn 签名: void(IOCPClient*, HandlerT*)
|
||
// handler 装上 callback 后立即调用,可在此发送首包或做额外 setup。
|
||
template <class HandlerT, class CreateFn, class OnReadyFn>
|
||
inline void RunSubConnThread(const char* threadName, CreateFn createHandler, OnReadyFn onReady)
|
||
{
|
||
try {
|
||
std::unique_ptr<IOCPClient> ClientObject(new IOCPClient(g_bExit, true));
|
||
void* clientAddr = ClientObject.get();
|
||
Mprintf(">>> Enter %s [%p]\n", threadName, clientAddr);
|
||
|
||
// 子连接:开启 auth。Linux/macOS IOCPClient 不带 m_conn,显式传入 g_myClientID。
|
||
ClientObject->EnableSubConnAuth(true, g_myClientID);
|
||
|
||
if (!g_bExit && ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort())) {
|
||
std::unique_ptr<HandlerT> handler = createHandler(ClientObject.get());
|
||
if (handler) {
|
||
ClientObject->setManagerCallBack(handler.get(),
|
||
IOCPManager::DataProcess,
|
||
IOCPManager::ReconnectProcess);
|
||
onReady(ClientObject.get(), handler.get());
|
||
while (ClientObject->IsRunning() && ClientObject->IsConnected() && S_CLIENT_NORMAL == g_bExit)
|
||
Sleep(1000);
|
||
// 清除回调,防止重连线程访问已销毁的 handler
|
||
ClientObject->setManagerCallBack(nullptr, nullptr, nullptr);
|
||
}
|
||
}
|
||
Mprintf(">>> Leave %s [%p]\n", threadName, clientAddr);
|
||
} catch (const std::exception& e) {
|
||
Mprintf("*** %s exception: %s ***\n", threadName, e.what());
|
||
}
|
||
}
|