共享模块说明
share/ 目录下的文件同时被客户端和服务端引用,确保双方通信协议、数据格式、公共逻辑的一致性。
Common.bas — 公共模块
这是整个项目的核心枢纽模块,负责通信封装、路由分发、接收处理。
全局变量
vb
Public Router As New cCollection ' 业务路由容器
Public MiddleWares As New cCollection ' 中间件容器(服务端使用)
Public MiddleWaresWhiteList As New cCollection ' 中间件白名单
Public UserToken As String ' 当前客户端的登录凭证
Public IsServer As Boolean ' 标识当前运行环境是否为服务端SendTo / SendToAll — 数据发送
vb
Public Sub SendTo(Inst As cWinsock, ByVal Action As String, Optional Data As Variant, Optional ByVal IsAll As Boolean)功能: 构造标准 JSON 数据包并通过 TCP 发送。
参数:
| 参数 | 说明 |
|---|---|
Inst | cWinsock 实例 |
Action | 路由地址,如 "User/Login" |
Data | 业务数据对象(可选,默认空集合) |
IsAll | 是否为广播模式(True = 发送给所有客户端) |
构造的 JSON 结构:
vb
With New cJson
.Item("action") = Action
.Item("token") = UserToken ' 自动带上当前凭证
.RootItem.Add "data", Data
If IsAll Then
Inst.SendToAll .Encode(, , True), wcpUtf8
Else
Inst.SendData .Encode(, , True), wcpUtf8
End If
End WithSendToAll 是服务端的广播快捷方法:
vb
Public Sub SendToAll(Inst As cWinsock, ByVal Action As String, Optional Data As Variant)
SendTo Inst, Action, Data, True
End SubSendMsgbox / SendToast — 消息推送
vb
Public Sub SendMsgbox(Inst As cWinsock, ByVal Content As String, Optional ByVal Title As String)向客户端发送弹窗消息:
json
{ "action": "Message/ShowMsgbox", "data": { "Content": "...", "Title": "..." } }vb
Public Sub SendToast(Inst As cWinsock, ByVal Content As String, Optional ByVal Delay As Long = 3000, Optional ByVal Title As String)向客户端发送 Toast 通知:
json
{ "action": "Message/ShowToast", "data": { "Content": "...", "Delay": 3000, "Title": "..." } }HandleReciver — 数据接收与路由分发
vb
Public Sub HandleReciver(Client As VBMANLIB.cWinsock, ByVal bytesTotal As Long)这是整个 C/S 系统的核心分发器,所有 TCP 数据到达后都经过此函数处理。
处理流程:
1. 从 Socket 读取字节数据
2. UTF-8 解码为字符串
3. JSON 解析
4. 提取 action 字段,按 "/" 分割为 [类名, 方法名]
5. 提取 data 字段(强制为对象类型)
6. 更新全局 UserToken
7. 【中间件检查】
- 如果是 Message/* → 跳过
- 如果在白名单 → 跳过
- 否则遍历所有中间件执行 Entry
- 任一中间件返回 False → 发送错误信息并退出
8. 【路由调用】
- CallByName Router.Item(类名), 方法名, VbMethod, Client, Data
9. 异常捕获
- 业务代码出错 → 向客户端发送 Err.Description关键代码解析:
vb
' 从 Socket 取数据并 UTF-8 解码
Dim Arr() As Byte: Client.GetData Arr, vbArray
.Decode VBMAN.ToolsUtf8.Decode(Arr)
' 解析路由
Dim Action As Variant: Action = Split(.Root("action"), "/")
' data 必须是对象类型
Dim Data As New cJson: Data.Decode .Root("data")
' 中间件链式检查
For i = 1 To MiddleWares.Count
Succ = MiddleWares(i).Entry(Client, .Self, LastError)
If Succ = False Then
Common.SendMsgbox Client, LastError, "中间件拦截"
Exit Sub
End If
Next
' 动态调用业务方法
CallByName Router.Item(Action(0)), Action(1), VbMethod, Client, DataPassword — 统一密码加密
vb
Public Function Password(ByVal Pwd As String) As String
Password = VBMAN.Password.Create(Pwd, "")
End Function客户端发送密码前、服务端验证密码前,都通过此函数进行哈希处理,确保密码不以明文传输和存储。
可通过第二个参数传入盐值,增强安全性。
cFileClient.cls / cFileServer.cls — 文件传输类
位于 share/ 目录的文件传输核心类,为客户端和服务端提供分片文件传输能力。
详细文档: 参见 filetransfer.md
架构特点
┌─────────────────┐ TCP:801 ┌─────────────────┐
│ cFileClient │ ◄────────────────────► │ cFileServer │
│ (客户端) │ 独立文件传输通道 │ (服务端) │
└─────────────────┘ └─────────────────┘- 独立通道: 文件传输使用独立的 TCP 连接(默认端口 801),与主消息通道分离
- 分片传输: 大文件自动分片(默认 32KB/片),支持进度监控
- 双向传输: 客户端可上传,服务端可主动下发
- 自动归档: 服务端通过
bFileManage自动将接收的文件按用户/年月分类存储
cFileClient 核心方法
vb
' 连接到文件服务器
Public Sub StartConnectTo(ByVal Server As String, Optional ByVal Port As Long = 803)
' 发送文件到服务端
Public Function SendToServer(ByVal FileName As String) As Boolean
' 事件:发送进度
Event OnSending(ByVal FileName As String, ByVal CurrentChunk As Long, ByVal TotalChunks As Long, ByVal Percent As Long)
' 事件:发送完成
Event OnSendFinish(ByVal FileName As String)cFileServer 核心方法
vb
' 启动文件服务
Public Sub StartMe(Optional Port As Long = 801, Optional IP As String = "0.0.0.0")
' 发送文件给指定用户
Public Function SendToClient(ByVal User As String, ByVal FileName As String) As Boolean
' 事件:客户端上传进度
Event OnClientSending(ByVal User As String, ByVal FileName As String, ByVal CurrentChunk As Long, ByVal TotalChunks As Long, ByVal Percent As Long)
' 事件:客户端上传完成
Event OnClientSendFinish(ByVal User As String, ByVal FileName As String, ByVal FilePath As String)cMessage.cls — 消息处理类
这是一个两端共用的消息显示适配器,根据运行环境自动选择不同的消息展示方式。
ShowMsgbox
vb
Public Sub ShowMsgbox(Inst As cWinsock, Data As cJson)
If Common.IsServer = True Then
' 服务端避免使用 MsgBox 阻塞,改用 Toast
VBMAN.Toast.Show Data("Content"), 60000, Data("Title")
Exit Sub
End If
MsgBox Data("Content"), , Data("Title")
End Sub| 环境 | 行为 |
|---|---|
| 客户端 | 调用系统 MsgBox 弹窗 |
| 服务端 | 使用 VBMAN.Toast 显示非阻塞通知(60秒停留) |
ShowToast
vb
Public Sub ShowToast(Inst As cWinsock, Data As cJson)
VBMAN.Toast.Show Data("Content"), Data("Delay"), Data("Title")
End Sub两端统一使用 VBMAN 的 Toast 组件显示轻量通知。
共享模块的设计意义
- 协议一致性: 客户端和服务端使用完全相同的
SendTo和HandleReciver,确保 JSON 结构一致 - 代码复用:
cMessage避免了两端分别实现消息显示逻辑 - 维护便利: 修改通信协议只需改
Common.bas一处 - 扩展性: 新增共享工具类只需放入
share/目录,在两端.vbp中引用即可