From 4de6c72a32f22fdf5492f2ee545b14e97ed9b208 Mon Sep 17 00:00:00 2001 From: xRain Date: Tue, 25 Aug 2026 12:36:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=20handler=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=94=B9=E5=90=8D=20IWebsocketHandler=20?= =?UTF-8?q?=E2=86=92=20WebSocketHandler=EF=BC=88=E4=BB=93=E9=A2=89?= =?UTF-8?q?=E6=8E=A8=E8=8D=90=E5=91=BD=E5=90=8D=EF=BC=8C=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=20I=20=E5=89=8D=E7=BC=80=EF=BC=8C=E4=B8=8D=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=EF=BC=89=EF=BC=8C=E6=96=87=E4=BB=B6=E5=90=8D?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=B8=BA=20websocket=5Fhandler.cj=EF=BC=9BRE?= =?UTF-8?q?ADME=20=E4=B8=8E=E6=B5=8B=E8=AF=95=E5=90=8C=E6=AD=A5=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=EF=BC=9B=E7=89=88=E6=9C=AC=201.2.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- cjpm.toml | 2 +- src/server/websocket_connection.cj | 8 ++++---- .../{i_websocket_handler.cj => websocket_handler.cj} | 2 +- src/server/websocket_server.cj | 6 +++--- src/tests/websocket_test.cj | 10 +++++----- 6 files changed, 18 insertions(+), 18 deletions(-) rename src/server/{i_websocket_handler.cj => websocket_handler.cj} (96%) diff --git a/README.md b/README.md index e6558f4..4362311 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ ```cangjie import simcu::websocket.client.WebSocketClient import simcu::websocket.server.WebSocketServer -import simcu::websocket.server.IWebsocketHandler +import simcu::websocket.server.WebSocketHandler import simcu::websocket.server.WebSocketConnection import simcu::websocket.common.WebSocketMessage ``` @@ -110,10 +110,10 @@ server.groups() // 所有组名(快照) ### Handler 接口 -`IWebsocketHandler` 只关心连接生命周期回调;端点路径由 `addHandler(path, factory)` 注册时指定,handler 自身不感知。每个连接在握手成功时由工厂创建一个独立的 handler 实例,因此 handler 内可持有该连接的会话状态(如 connectionId / 组信息),但不要持有会跨连接共享的 scoped 服务。 +`WebSocketHandler` 只关心连接生命周期回调;端点路径由 `addHandler(path, factory)` 注册时指定,handler 自身不感知。每个连接在握手成功时由工厂创建一个独立的 handler 实例,因此 handler 内可持有该连接的会话状态(如 connectionId / 组信息),但不要持有会跨连接共享的 scoped 服务。 ```cangjie -public interface IWebsocketHandler { +public interface WebSocketHandler { func onConnect(conn: WebSocketConnection): Unit func onMessage(conn: WebSocketConnection, msg: WebSocketMessage): Unit func onClose(conn: WebSocketConnection, code: Int64, reason: String): Unit @@ -124,7 +124,7 @@ public interface IWebsocketHandler { 实现示例: ```cangjie -class MyHandler <: IWebsocketHandler { +class MyHandler <: WebSocketHandler { public override func onConnect(conn: WebSocketConnection): Unit { conn.joinGroup("authed") // 握手成功即入组 } diff --git a/cjpm.toml b/cjpm.toml index eaf58bf..154eb4d 100644 --- a/cjpm.toml +++ b/cjpm.toml @@ -3,7 +3,7 @@ cjc-version = "1.1.3" name = "websocket" organization = "simcu" description = "SimApi WebSocket 库(RFC 6455):事件回调式客户端与接口式服务端。客户端 connect/send(三重重载)/ping/close/terminate + onOpen/onMessage/onError/onClose;服务端 WebSocketServer(port) + addHandler(path, factory) 按路径路由、每连接独立 handler,链式门面 group(name)/conn(connId) 支持组管理/组播/单播/广播,连接断开自动清组" -version = "1.2.0" +version = "1.2.1" target-dir = "" output-type = "static" diff --git a/src/server/websocket_connection.cj b/src/server/websocket_connection.cj index 67f635e..36e3fe1 100644 --- a/src/server/websocket_connection.cj +++ b/src/server/websocket_connection.cj @@ -1,7 +1,7 @@ /* * simcu::websocket.server —— 服务端单条 WebSocket 连接。 * - * 由 WebSocketServer 在握手成功后创建并交给匹配的 IWebsocketHandler。 + * 由 WebSocketServer 在握手成功后创建并交给匹配的 WebSocketHandler。 * 提供 send(三重重载:WebSocketMessage / String / Array)/ ping / close / terminate,以及只读属性 * connectionId / readyState / remoteAddress / requestPath / requestQuery。 */ @@ -21,7 +21,7 @@ import simcu::websocket.common.WebSocketException /// 服务端单条 WebSocket 连接(由对应 handler 处理回调)。 public class WebSocketConnection { private let parent: ?WebSocketServer - private let handler: IWebsocketHandler + private let handler: WebSocketHandler private let frame: FrameStream private let stateLock = Mutex() private var state: ReadyState = ReadyState.Open @@ -40,7 +40,7 @@ public class WebSocketConnection { public let requestQuery: String /// 回调归属的 handler(由 WebSocketServer 按路径匹配后注入)。 - internal prop wsHandler: IWebsocketHandler { + internal prop wsHandler: WebSocketHandler { get() { handler } } @@ -49,7 +49,7 @@ public class WebSocketConnection { get() { parent } } - internal init(parent: ?WebSocketServer, handler: IWebsocketHandler, frame: FrameStream, + internal init(parent: ?WebSocketServer, handler: WebSocketHandler, frame: FrameStream, connId: Int64, requestPath: String, requestQuery: String) { this.parent = parent this.handler = handler diff --git a/src/server/i_websocket_handler.cj b/src/server/websocket_handler.cj similarity index 96% rename from src/server/i_websocket_handler.cj rename to src/server/websocket_handler.cj index 0c09bf7..2acef9e 100644 --- a/src/server/i_websocket_handler.cj +++ b/src/server/websocket_handler.cj @@ -11,7 +11,7 @@ package simcu::websocket.server import simcu::websocket.common.WebSocketMessage /// WebSocket 服务端 handler 接口(多 handler 按注册路径路由)。 -public interface IWebsocketHandler { +public interface WebSocketHandler { /// 握手成功、连接建立后触发。 func onConnect(conn: WebSocketConnection): Unit diff --git a/src/server/websocket_server.cj b/src/server/websocket_server.cj index 12a6d42..50efd78 100644 --- a/src/server/websocket_server.cj +++ b/src/server/websocket_server.cj @@ -32,7 +32,7 @@ import simcu::websocket.common.WebSocketException public class WebSocketServer { private let bindPort: UInt16 private let maxPayload: Int64 - private var pathFactories = HashMap IWebsocketHandler>() + private var pathFactories = HashMap WebSocketHandler>() private var serverSock: ?TcpServerSocket = None private var running = false private var connections = HashMap() @@ -50,7 +50,7 @@ public class WebSocketServer { /// 注册一个 handler 工厂并绑定到端点路径(多 handler 按路径路由)。 /// 每次握手成功都会调用工厂创建一个新的 handler 实例(每连接一个), /// 因此不要在工厂里复用有状态对象(如 scoped 服务),应让各回调按需现场解析。 - public func addHandler(path: String, factory: () -> IWebsocketHandler): Unit { + public func addHandler(path: String, factory: () -> WebSocketHandler): Unit { pathFactories[path] = factory } @@ -212,7 +212,7 @@ public class WebSocketServer { // ===== 监听与握手 ===== /// 按请求路径匹配 handler 工厂。无匹配返回 None。 - private func findFactory(path: String): ?() -> IWebsocketHandler { + private func findFactory(path: String): ?() -> WebSocketHandler { pathFactories.get(path) } diff --git a/src/tests/websocket_test.cj b/src/tests/websocket_test.cj index a518913..bd53071 100644 --- a/src/tests/websocket_test.cj +++ b/src/tests/websocket_test.cj @@ -18,7 +18,7 @@ import simcu::websocket.client.WebSocketClient import simcu::websocket.common.MessageType import simcu::websocket.common.WebSocketException import simcu::websocket.common.WebSocketMessage -import simcu::websocket.server.IWebsocketHandler +import simcu::websocket.server.WebSocketHandler import simcu::websocket.server.WebSocketConnection import simcu::websocket.server.WebSocketServer @@ -48,7 +48,7 @@ private func waitUntil(timeoutMs: Int64, condition: () -> Bool): Bool { } /// 测试用 handler:把事件回调逻辑收进接口方法,行为写入 harness。 -class TestWsHandler <: IWebsocketHandler { +class TestWsHandler <: WebSocketHandler { let harness: WsTestHarness init(harness: WsTestHarness) { @@ -77,7 +77,7 @@ class TestWsHandler <: IWebsocketHandler { } /// 广播场景:harness1 收到广播后转发文本。 -class EchoHandler <: IWebsocketHandler { +class EchoHandler <: WebSocketHandler { let harness: WsTestHarness init(harness: WsTestHarness) { @@ -102,7 +102,7 @@ class EchoHandler <: IWebsocketHandler { } /// 服务端主动关闭场景:连接建立后立即 close。 -class CloseOnConnectHandler <: IWebsocketHandler { +class CloseOnConnectHandler <: WebSocketHandler { init() {} public override func onConnect(conn: WebSocketConnection): Unit { @@ -123,7 +123,7 @@ class CloseOnConnectHandler <: IWebsocketHandler { } /// 分组场景:连接建立后加入 "room" 组,便于验证组播/单播。 -class GroupJoinHandler <: IWebsocketHandler { +class GroupJoinHandler <: WebSocketHandler { public override func onConnect(conn: WebSocketConnection): Unit { conn.joinGroup("room") }