服务端 handler 接口改名 IWebsocketHandler → WebSocketHandler(仓颉推荐命名,去掉 I 前缀,不保留兼容),文件名同步为 websocket_handler.cj;README 与测试同步更新;版本 1.2.1

This commit is contained in:
2026-08-25 12:36:56 +08:00
parent cbfa3fcbdc
commit 4de6c72a32
6 changed files with 18 additions and 18 deletions
+4 -4
View File
@@ -29,7 +29,7 @@
```cangjie ```cangjie
import simcu::websocket.client.WebSocketClient import simcu::websocket.client.WebSocketClient
import simcu::websocket.server.WebSocketServer import simcu::websocket.server.WebSocketServer
import simcu::websocket.server.IWebsocketHandler import simcu::websocket.server.WebSocketHandler
import simcu::websocket.server.WebSocketConnection import simcu::websocket.server.WebSocketConnection
import simcu::websocket.common.WebSocketMessage import simcu::websocket.common.WebSocketMessage
``` ```
@@ -110,10 +110,10 @@ server.groups() // 所有组名(快照)
### Handler 接口 ### Handler 接口
`IWebsocketHandler` 只关心连接生命周期回调;端点路径由 `addHandler(path, factory)` 注册时指定,handler 自身不感知。每个连接在握手成功时由工厂创建一个独立的 handler 实例,因此 handler 内可持有该连接的会话状态(如 connectionId / 组信息),但不要持有会跨连接共享的 scoped 服务。 `WebSocketHandler` 只关心连接生命周期回调;端点路径由 `addHandler(path, factory)` 注册时指定,handler 自身不感知。每个连接在握手成功时由工厂创建一个独立的 handler 实例,因此 handler 内可持有该连接的会话状态(如 connectionId / 组信息),但不要持有会跨连接共享的 scoped 服务。
```cangjie ```cangjie
public interface IWebsocketHandler { public interface WebSocketHandler {
func onConnect(conn: WebSocketConnection): Unit func onConnect(conn: WebSocketConnection): Unit
func onMessage(conn: WebSocketConnection, msg: WebSocketMessage): Unit func onMessage(conn: WebSocketConnection, msg: WebSocketMessage): Unit
func onClose(conn: WebSocketConnection, code: Int64, reason: String): Unit func onClose(conn: WebSocketConnection, code: Int64, reason: String): Unit
@@ -124,7 +124,7 @@ public interface IWebsocketHandler {
实现示例: 实现示例:
```cangjie ```cangjie
class MyHandler <: IWebsocketHandler { class MyHandler <: WebSocketHandler {
public override func onConnect(conn: WebSocketConnection): Unit { public override func onConnect(conn: WebSocketConnection): Unit {
conn.joinGroup("authed") // 握手成功即入组 conn.joinGroup("authed") // 握手成功即入组
} }
+1 -1
View File
@@ -3,7 +3,7 @@ cjc-version = "1.1.3"
name = "websocket" name = "websocket"
organization = "simcu" 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) 支持组管理/组播/单播/广播,连接断开自动清组" 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 = "" target-dir = ""
output-type = "static" output-type = "static"
+4 -4
View File
@@ -1,7 +1,7 @@
/* /*
* simcu::websocket.server —— 服务端单条 WebSocket 连接。 * simcu::websocket.server —— 服务端单条 WebSocket 连接。
* *
* 由 WebSocketServer 在握手成功后创建并交给匹配的 IWebsocketHandler。 * 由 WebSocketServer 在握手成功后创建并交给匹配的 WebSocketHandler。
* 提供 send(三重重载:WebSocketMessage / String / Array<Byte>/ ping / close / terminate,以及只读属性 * 提供 send(三重重载:WebSocketMessage / String / Array<Byte>/ ping / close / terminate,以及只读属性
* connectionId / readyState / remoteAddress / requestPath / requestQuery。 * connectionId / readyState / remoteAddress / requestPath / requestQuery。
*/ */
@@ -21,7 +21,7 @@ import simcu::websocket.common.WebSocketException
/// 服务端单条 WebSocket 连接(由对应 handler 处理回调)。 /// 服务端单条 WebSocket 连接(由对应 handler 处理回调)。
public class WebSocketConnection { public class WebSocketConnection {
private let parent: ?WebSocketServer private let parent: ?WebSocketServer
private let handler: IWebsocketHandler private let handler: WebSocketHandler
private let frame: FrameStream private let frame: FrameStream
private let stateLock = Mutex() private let stateLock = Mutex()
private var state: ReadyState = ReadyState.Open private var state: ReadyState = ReadyState.Open
@@ -40,7 +40,7 @@ public class WebSocketConnection {
public let requestQuery: String public let requestQuery: String
/// 回调归属的 handler(由 WebSocketServer 按路径匹配后注入)。 /// 回调归属的 handler(由 WebSocketServer 按路径匹配后注入)。
internal prop wsHandler: IWebsocketHandler { internal prop wsHandler: WebSocketHandler {
get() { handler } get() { handler }
} }
@@ -49,7 +49,7 @@ public class WebSocketConnection {
get() { parent } get() { parent }
} }
internal init(parent: ?WebSocketServer, handler: IWebsocketHandler, frame: FrameStream, internal init(parent: ?WebSocketServer, handler: WebSocketHandler, frame: FrameStream,
connId: Int64, requestPath: String, requestQuery: String) { connId: Int64, requestPath: String, requestQuery: String) {
this.parent = parent this.parent = parent
this.handler = handler this.handler = handler
@@ -11,7 +11,7 @@ package simcu::websocket.server
import simcu::websocket.common.WebSocketMessage import simcu::websocket.common.WebSocketMessage
/// WebSocket 服务端 handler 接口(多 handler 按注册路径路由)。 /// WebSocket 服务端 handler 接口(多 handler 按注册路径路由)。
public interface IWebsocketHandler { public interface WebSocketHandler {
/// 握手成功、连接建立后触发。 /// 握手成功、连接建立后触发。
func onConnect(conn: WebSocketConnection): Unit func onConnect(conn: WebSocketConnection): Unit
+3 -3
View File
@@ -32,7 +32,7 @@ import simcu::websocket.common.WebSocketException
public class WebSocketServer { public class WebSocketServer {
private let bindPort: UInt16 private let bindPort: UInt16
private let maxPayload: Int64 private let maxPayload: Int64
private var pathFactories = HashMap<String, () -> IWebsocketHandler>() private var pathFactories = HashMap<String, () -> WebSocketHandler>()
private var serverSock: ?TcpServerSocket = None private var serverSock: ?TcpServerSocket = None
private var running = false private var running = false
private var connections = HashMap<Int64, WebSocketConnection>() private var connections = HashMap<Int64, WebSocketConnection>()
@@ -50,7 +50,7 @@ public class WebSocketServer {
/// 注册一个 handler 工厂并绑定到端点路径(多 handler 按路径路由)。 /// 注册一个 handler 工厂并绑定到端点路径(多 handler 按路径路由)。
/// 每次握手成功都会调用工厂创建一个新的 handler 实例(每连接一个), /// 每次握手成功都会调用工厂创建一个新的 handler 实例(每连接一个),
/// 因此不要在工厂里复用有状态对象(如 scoped 服务),应让各回调按需现场解析。 /// 因此不要在工厂里复用有状态对象(如 scoped 服务),应让各回调按需现场解析。
public func addHandler(path: String, factory: () -> IWebsocketHandler): Unit { public func addHandler(path: String, factory: () -> WebSocketHandler): Unit {
pathFactories[path] = factory pathFactories[path] = factory
} }
@@ -212,7 +212,7 @@ public class WebSocketServer {
// ===== 监听与握手 ===== // ===== 监听与握手 =====
/// 按请求路径匹配 handler 工厂。无匹配返回 None。 /// 按请求路径匹配 handler 工厂。无匹配返回 None。
private func findFactory(path: String): ?() -> IWebsocketHandler { private func findFactory(path: String): ?() -> WebSocketHandler {
pathFactories.get(path) pathFactories.get(path)
} }
+5 -5
View File
@@ -18,7 +18,7 @@ import simcu::websocket.client.WebSocketClient
import simcu::websocket.common.MessageType import simcu::websocket.common.MessageType
import simcu::websocket.common.WebSocketException import simcu::websocket.common.WebSocketException
import simcu::websocket.common.WebSocketMessage import simcu::websocket.common.WebSocketMessage
import simcu::websocket.server.IWebsocketHandler import simcu::websocket.server.WebSocketHandler
import simcu::websocket.server.WebSocketConnection import simcu::websocket.server.WebSocketConnection
import simcu::websocket.server.WebSocketServer import simcu::websocket.server.WebSocketServer
@@ -48,7 +48,7 @@ private func waitUntil(timeoutMs: Int64, condition: () -> Bool): Bool {
} }
/// 测试用 handler:把事件回调逻辑收进接口方法,行为写入 harness。 /// 测试用 handler:把事件回调逻辑收进接口方法,行为写入 harness。
class TestWsHandler <: IWebsocketHandler { class TestWsHandler <: WebSocketHandler {
let harness: WsTestHarness let harness: WsTestHarness
init(harness: WsTestHarness) { init(harness: WsTestHarness) {
@@ -77,7 +77,7 @@ class TestWsHandler <: IWebsocketHandler {
} }
/// 广播场景:harness1 收到广播后转发文本。 /// 广播场景:harness1 收到广播后转发文本。
class EchoHandler <: IWebsocketHandler { class EchoHandler <: WebSocketHandler {
let harness: WsTestHarness let harness: WsTestHarness
init(harness: WsTestHarness) { init(harness: WsTestHarness) {
@@ -102,7 +102,7 @@ class EchoHandler <: IWebsocketHandler {
} }
/// 服务端主动关闭场景:连接建立后立即 close。 /// 服务端主动关闭场景:连接建立后立即 close。
class CloseOnConnectHandler <: IWebsocketHandler { class CloseOnConnectHandler <: WebSocketHandler {
init() {} init() {}
public override func onConnect(conn: WebSocketConnection): Unit { public override func onConnect(conn: WebSocketConnection): Unit {
@@ -123,7 +123,7 @@ class CloseOnConnectHandler <: IWebsocketHandler {
} }
/// 分组场景:连接建立后加入 "room" 组,便于验证组播/单播。 /// 分组场景:连接建立后加入 "room" 组,便于验证组播/单播。
class GroupJoinHandler <: IWebsocketHandler { class GroupJoinHandler <: WebSocketHandler {
public override func onConnect(conn: WebSocketConnection): Unit { public override func onConnect(conn: WebSocketConnection): Unit {
conn.joinGroup("room") conn.joinGroup("room")
} }