YStudio Y++

WebSocket类使用说明

Y++ / YStudio 开发文档 · 一点滴

WebSocket类 提供 客户端 WebSocket(ws:// / wss://):消息帧收发,不必自己处理粘包。底层为 WinHTTP(Windows 8+)。

类型名必须写 WebSocket类。声明变量时一般会自动创建会话,多数情况不必手写 创建WebSocket()

TCP类 分工:自定义字节流/多客户端服务端用 TCP;浏览器式双向消息用 WebSocket(写法更短)。
支持 客户端连接服务端启动监听(明文 ws;命名与 TCP 对齐:客户进入 / 数据到达 / 客户离开)。

相关:TCP类HTTP类JSON类(解析文本帧)。


1. 粗暴写法(推荐先会这个)

1.1 同步:连 → 发 → 收 → 关

可用完整 URL,或主机 + 端口(与 TCP 连接 同风格):

WebSocket类 ws
如果 (ws.连接_同步("127.0.0.1", 8080) == 假) {
    信息框(ws.错误信息, 0)
    返回()
}
' 等价:ws.连接_同步("ws://127.0.0.1:8080/")
ws.发送("ping")
文本 r = ws.接收()          ' 等到下一条完整文本消息;超时默认 30 秒
信息框(r, 0)
ws.关闭()

WSS:ws.连接_同步("example.com", 443, 真)ws.连接_同步("wss://example.com/ws")

1.2 异步:先注册事件,再连接

事件 一个方法挂一个回调(与 TCP 相同),不要往 连接 里塞回调。

WebSocket类 ws

函数 开了(整数 id, 文本 IP, 整数 端口, 文本 IP端口) {
    输出("已连 " + IP端口)
}
函数 收到(整数 id, 文本 IP, 整数 端口, 文本 IP端口, 文本 msg) {
    输出(msg)
}
函数 关了(整数 id, 文本 IP, 整数 端口, 文本 IP端口, 整数 code, 文本 reason) {
    输出("关闭 " + 到文本(code))
}
函数 失败(文本 reason) {
    信息框(reason, 0)
}

函数 主窗口.创建完毕() {
    ws.客户进入(&开了)
    ws.数据到达(&收到)
    ws.客户离开(&关了)
    ws.连接失败(&失败)
    ws.连接("127.0.0.1", 8080)          ' 或 ws.连接("ws://127.0.0.1:8080/")
}

客户端连接 ID 固定为 1(与 TCP 客户端一致)。
IP / IP端口 / msg 仅在本回调内有效(连接目标在握手时解析缓存)。


2. 使用顺序

  1. 声明 WebSocket类
  2. 按需配置:超时、请求头、子协议、心跳、代理、TLS 验证(均在连接前)
  3. 先注册事件,再 连接 / 连接_同步
  4. 发送 / 发送字节集;同步场景可用 接收 / 接收字节集
  5. 结束时 关闭重置(重置保留已注册事件)

3. 事件(界面线程回调)

0 可清除该事件。推荐名与旧名对照:

推荐名 旧名(仍可用) 回调形参 说明
客户进入 连接成功 (整数 连接ID, 文本 IP, 整数 端口, 文本 IP端口) 仅异步 连接 成功;同步成功不触发
连接失败 (文本 原因) 仅异步失败;同步看返回值与 错误信息
数据到达 消息到达 (整数 连接ID, 文本 IP, 整数 端口, 文本 IP端口, 文本 数据) 文本帧
数据到达字节集 消息到达字节集 (整数 连接ID, 文本 IP, 整数 端口, 文本 IP端口, 字节集 数据) 二进制帧
客户离开 连接关闭 (整数 连接ID, 文本 IP, 整数 端口, 文本 IP端口, 整数 状态码, 文本 原因) 本端/对端/异常关闭
心跳超时 (整数 连接ID, 文本 IP, 整数 端口, 文本 IP端口) 空闲超过「心跳间隔+超时」

回调内不要长时间阻塞。文本参数仅在本函数内有效。


4. 属性(只读,无括号)

属性 类型 说明
超时 整数 毫秒;写入用 置超时
错误信息 文本 最近失败原因
URL 文本 当前目标 URL
是否已连接 逻辑
是否连接中 逻辑 异步握手中
子协议 文本 协商结果或已设置值
关闭码 整数
关闭原因 文本
最大帧长 整数 默认 1MB

5. 方法与可选参数默认

方括号为可选;省略时用下列最优默认。

5.1 配置

方法 签名 默认/规则
置超时 置超时([整数 毫秒=30000]) ≤0 → 30000
置请求头 置请求头(文本 名, 文本 值) → 逻辑 握手附加头
删除请求头 删除请求头(文本 名) → 逻辑
清空请求头 清空请求头()
置子协议 置子协议([文本 协议=""]) 空=不发送
置心跳 置心跳([整数 间隔毫秒=30000], [整数 超时毫秒=10000]) 间隔 ≤0 关心跳
置最大帧长 置最大帧长([整数 字节=1048576]) ≤0 → 1MB
置代理 置代理(文本 地址, [文本 账号=""], [文本 密码=""])
置TLS验证 置TLS验证([逻辑 验证=真]) 默认真;仅测试可关
置TLS主机名 置TLS主机名(文本 主机名) 可选;一般 URL 主机即可

5.2 连接与收发

方法 签名 说明
连接 连接(文本 URL) → 逻辑 异步;完整 ws:// / wss://
连接 连接(文本 主机, 整数 端口, [整数 加密=0]) → 逻辑 异步;加密≠0 用 wss;默认路径 /
连接_同步 同上两种重载 阻塞握手;成功不触发 客户进入
发送 发送(文本 数据) → 逻辑 文本帧
发送字节集 发送字节集(字节集 数据) → 逻辑 二进制帧
发送Ping 发送Ping([字节集 载荷]) → 逻辑 兼容保留(WinHTTP 无独立 Ping 帧)
接收 接收() → 文本 等下一条消息(整帧)
接收字节集 接收字节集() → 字节集
关闭 关闭([整数 状态码=1000], [文本 原因=""]) 正常关闭码 1000
重置 重置() 断开并清错误,保留事件与配置
取远程IP / 取客户IP () → 文本 连接目标主机(URL 解析缓存)
取远程端口 / 取客户端口 () → 整数
取远程地址 / 取客户地址 () → 文本 主机:端口

鉴权示例:

ws.置请求头("Authorization", "Bearer xxx")
ws.置子协议("chat.v1")
ws.连接("wss://api.example.com/v1/ws")

6. 服务端写法

WebSocket类 srv
函数 进入(整数 id, 文本 IP, 整数 端口, 文本 IP端口) {
    输出("进入 " + IP端口)
}
函数 收到(整数 id, 文本 IP, 整数 端口, 文本 IP端口, 文本 msg) {
    srv.发送(id, msg)   ' 回显
}
函数 离开(整数 id, 文本 IP, 整数 端口, 文本 IP端口, 整数 code, 文本 reason) {
    输出("离开 " + 到文本(id))
}
函数 主窗口.创建完毕() {
    srv.客户进入(&进入)
    srv.数据到达(&收到)
    srv.客户离开(&离开)
    srv.启动(9000, "127.0.0.1")
}
  • 服务端:发送(连接ID, 文本) / 广播(文本) / 断开(id) / 关闭全部
  • 明文 ws:直接 启动(端口);浏览器连 ws://127.0.0.1:端口/
  • 加密 wss(与 TCP TLS 相同,Schannel + PFX):
srv.置TLS(真)
srv.置TLS证书("server.pfx", "密码")
srv.启动(9443, "127.0.0.1")
' 客户端:ws.置TLS验证(假)   ' 自签测试
'          ws.连接_同步("wss://127.0.0.1:9443/")

可选:置TLS要求客户端证书 / 置TLS根证书(mTLS)。