cHttpServerContext 上下文对象
简介
cHttpServerContext 是 HttpServer 框架的核心对象,贯穿整个请求生命周期。它封装了 HTTP 请求处理所需的全部信息和功能,作为中间件和控制器之间数据传递的载体。
请求生命周期中的 Context:
Request Arrive
│
▼
┌─────────────────────────────────────────────────────────────┐
│ cHttpServerContext │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Request │ │ Session │ │ Response │ │
│ │ (请求信息) │ │ (会话数据) │ │ (响应构建) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Cookies │ │ Db │ │ Client │ │
│ │ (Cookie) │ │ (数据库) │ │ (客户端) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ SSE │ │ UserData │ (自定义数据传递) │
│ │(实时推送) │ │ (扩展存储) │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
Middleware -> Controller -> Response核心属性
Request - 请求对象
包含客户端发送的所有请求信息。
vb
Public Request As cHttpServerRequest常用访问方式:
vb
' 获取请求方法
Dim method As String
method = ctx.Request.MethodName ' "GET" / "POST" / "PUT" / "DELETE"
' 获取请求路径
Dim path As String
path = ctx.Request.PathInfo ' "/user/list"
' 获取查询参数
Dim page As String
page = ctx.Request.QueryString("page")
' 获取表单数据
Dim username As String
username = ctx.Request.Form("username")
' 获取 JSON 数据
Dim name As String
name = ctx.Request.Json.GetItem("name")
' 智能获取(自动从 Query/Form/Json 查找)
Dim value As Variant
value = ctx.Request("keyword")
' 获取请求头
Dim token As String
token = ctx.Request.Header("Authorization")Response - 响应对象
用于构建和发送 HTTP 响应。
vb
Public Response As cHttpServerResponse常用方法:
vb
' 返回文本
ctx.Response.Text "Hello World"
' 返回 HTML
ctx.Response.Html "<h1>标题</h1>"
' 返回 JSON
ctx.Response.Json data, 0, "Success"
' 返回文件
ctx.Response.File "/path/to/file.pdf"
' 返回错误状态
ctx.Response.State404 "页面不存在"
ctx.Response.State500 "服务器内部错误"
ctx.Response.State401 "未授权"Session - 会话对象
管理用户会话数据,支持内存、文件、数据库三种存储方式。
vb
Public Session As cHttpServerSession常用操作:
vb
' 存储数据
ctx.Session("user_id") = "123"
ctx.Session("username") = "张三"
' 读取数据
Dim userId As String
userId = ctx.Session("user_id")
' 检查存在性
If ctx.Session.Exists("user_id") Then
' 用户已登录
End If
' 设置超时(分钟)
ctx.Session.TimeOut = 60
' 删除数据
ctx.Session.Remove("temp_data")
' 清空会话
ctx.Session.Clear
' 放弃会话(退出登录)
ctx.Session.Abandon登录验证示例:
vb
Public Sub CheckLogin(ctx As cHttpServerContext)
If Not ctx.Session.Exists("user_id") Then
ctx.Response.State401 "请先登录"
ctx.Abort ' 终止后续处理
End If
End SubCookies - Cookie 对象
管理请求和响应中的 Cookie。
vb
Public Cookies As cHttpServerCookies读取请求 Cookie:
vb
If ctx.Cookies.Exists("remember") Then
Dim token As String
token = ctx.Cookies.Cookie("remember").Value
End If设置响应 Cookie:
vb
With ctx.Cookies.Cookie("session_id")
.Value = GenerateToken()
.Expires = DateAdd("h", 2, Now)
.HttpOnly = True
.Secure = True
.Path = "/"
.SameSite = "Strict"
End WithDb - 数据库对象
提供数据库访问能力。
vb
Public Db As cDataBase查询示例:
vb
' 简单查询
If ctx.Db.Sql("SELECT * FROM users WHERE id=?") _
.Param("id", userId, adVarChar) _
.Fetch Then
Dim user As Scripting.Dictionary
Set user = ctx.Db.Rows(1)
End If
' 插入数据
ctx.Db.Sql("INSERT INTO logs (action, time) VALUES (?, NOW())") _
.Param("action", "login", adVarChar) _
.ExecParam
' 事务处理
ctx.Db.TransBegin
' ... 执行多个 SQL ...
ctx.Db.TransCommitClientInfo - 客户端信息
包含连接客户端的信息。
vb
Public ClientInfo As cHttpServerClientInfo属性:
vb
Dim ip As String
ip = ctx.ClientInfo.IP ' "192.168.1.100"
Dim port As Long
port = ctx.ClientInfo.Port ' 52341
Dim hSocket As Long
hSocket = ctx.ClientInfo.hSocket ' 套接字句柄
Dim connectTime As Date
connectTime = ctx.ClientInfo.ConnectAt应用场景:
vb
' IP 黑名单检查
Public Sub CheckIP(ctx As cHttpServerContext)
Dim blacklist As Variant
blacklist = Array("192.168.1.100", "10.0.0.50")
If InArray(ctx.ClientInfo.IP, blacklist) Then
ctx.Response.State403 "IP 已被封禁"
ctx.Abort
End If
End Sub
' 记录访问日志
Public Sub LogAccess(ctx As cHttpServerContext)
Dim log As String
log = Now & " | " & ctx.ClientInfo.IP & " | " & ctx.Request.PathInfo
Call WriteLog(log)
End SubServer - 服务器配置
访问服务器配置信息。
vb
Public Server As cHttpServerSvr属性:
vb
Dim webRoot As String
webRoot = ctx.Server.WebRoot ' "C:\WebRoot"
Dim port As Long
port = ctx.Server.Port ' 8080
Dim ip As String
ip = ctx.Server.IP ' "0.0.0.0"检查静态文件:
vb
If ctx.Server.IsStaticFile("/image/logo.png") Then
ctx.Response.File "/image/logo.png"
End IfSSE - 实时推送
Server-Sent Events 实时推送对象。
vb
Public SSE As New cSSEContext使用示例:
vb
' 发送消息给指定客户端
Call ctx.SSE.Send(ctx.ClientInfo.hSocket, "event", "data", "id")
' 广播给所有客户端
Call ctx.SSE.Broadcast("notification", "系统公告")
' 检查连接状态
If ctx.SSE.IsConnected(ctx.ClientInfo.hSocket) Then
' 客户端在线
End IfTimeUse - 耗时统计
用于统计请求处理耗时。
vb
Public TimeUse As New cTimeUse使用示例:
vb
Public Sub SlowOperation(ctx As cHttpServerContext)
ctx.TimeUse.Start
' ... 执行耗时操作 ...
Sleep 2000
ctx.TimeUse.End_
Debug.Print "操作耗时: " & ctx.TimeUse.Elapsed & " ms"
' 输出: 操作耗时: 2000 ms
End SubUserData - 用户数据存储
用于在请求生命周期内传递自定义数据。
vb
Public UserData As New Scripting.Dictionary中间件与控制器间传递数据:
vb
' === 中间件中设置 ===
Public Sub AuthMiddleware(ctx As cHttpServerContext)
' 验证 Token 后存储用户信息
ctx.UserData("user_id") = "123"
ctx.UserData("username") = "张三"
ctx.UserData("role") = "admin"
End Sub
' === 控制器中使用 ===
Public Sub GetData(ctx As cHttpServerContext)
' 获取中间件设置的数据
Dim userId As String
userId = ctx.UserData("user_id")
' 根据角色返回不同数据
If ctx.UserData("role") = "admin" Then
' 返回完整数据
Else
' 返回部分数据
End If
End Sub控制方法
Abort - 终止请求
终止后续所有处理(中间件、控制器)。
vb
Public Sub Abort()示例:
vb
Public Sub CheckAuth(ctx As cHttpServerContext)
If Not IsValidToken(ctx) Then
ctx.Response.State401 "未授权"
ctx.Abort ' 终止后续处理
End If
End SubSkipNextMiddleWare - 跳过后续中间件
跳过剩余的中间件,直接进入控制器。
vb
Public Sub SkipNextMiddleWare()示例:
vb
Public Sub CacheMiddleware(ctx As cHttpServerContext)
' 检查缓存命中
If CacheExists(ctx.Request.PathInfo) Then
ctx.Response.Text GetCache(ctx.Request.PathInfo)
ctx.SkipNextMiddleWare ' 跳过其他中间件
End If
End Sub完整请求处理示例
vb
' cOrderController.cls
Option Explicit
' GET /api/orders
Public Sub List(ctx As cHttpServerContext)
' 1. 性能统计开始
ctx.TimeUse.Start
' 2. 权限检查(从中间件传递的数据)
Dim userId As String
userId = ctx.UserData("user_id")
If userId = "" Then
ctx.Response.State401 "请先登录"
ctx.Abort
Exit Sub
End If
' 3. 获取请求参数
Dim page As Long, limit As Long
page = CLng(ctx.Request.QueryString("page"))
limit = CLng(ctx.Request.QueryString("limit"))
' 4. 数据库查询
Dim sql As String
sql = "SELECT * FROM orders WHERE user_id=? ORDER BY created_at DESC LIMIT ?,?"
If Not ctx.Db.Sql(sql) _
.Param("user_id", userId, adVarChar) _
.Param("offset", (page - 1) * limit, adInteger) _
.Param("limit", limit, adInteger) _
.Fetch Then
ctx.Response.State500 "查询失败"
Exit Sub
End If
' 5. 构建响应
Dim result As New Scripting.Dictionary
result("items") = ctx.Db.Rows
result("page") = page
result("total") = ctx.Db.Count("orders WHERE user_id='" & userId & "'")
ctx.Response.Json result, 0, "Success"
' 6. 记录访问日志
Call WriteLog(ctx.ClientInfo.IP & " 查询了订单列表")
' 7. 性能统计结束
ctx.TimeUse.End_
Debug.Print "请求处理耗时: " & ctx.TimeUse.Elapsed & "ms"
End Sub
' POST /api/orders
Public Sub Create(ctx As cHttpServerContext)
' 1. 获取当前用户
Dim userId As String
userId = ctx.UserData("user_id")
' 2. 获取请求数据
Dim productId As String, quantity As Long
productId = ctx.Request.Json.GetItem("product_id")
quantity = ctx.Request.Json.GetItem("quantity")
' 3. 开启事务
If Not ctx.Db.TransBegin Then
ctx.Response.State500 "系统错误"
Exit Sub
End If
On Error GoTo Rollback
' 4. 检查库存
Dim stock As Long
stock = GetProductStock(ctx.Db, productId)
If stock < quantity Then
ctx.Response.Json Nothing, 1, "库存不足"
GoTo Rollback
End If
' 5. 创建订单
Dim orderId As String
orderId = GenerateOrderId()
ctx.Db.Sql("INSERT INTO orders (id, user_id, product_id, quantity) VALUES (?, ?, ?, ?)") _
.Param("id", orderId, adVarChar) _
.Param("user_id", userId, adVarChar) _
.Param("product_id", productId, adVarChar) _
.Param("quantity", quantity, adInteger) _
.ExecParam
' 6. 扣减库存
ctx.Db.Sql("UPDATE products SET stock = stock - ? WHERE id = ?") _
.Param("quantity", quantity, adInteger) _
.Param("product_id", productId, adVarChar) _
.ExecParam
' 7. 提交事务
ctx.Db.TransCommit
' 8. 返回结果
Dim result As New Scripting.Dictionary
result("order_id") = orderId
ctx.Response.Json result, 0, "订单创建成功"
' 9. 发送实时通知
Call ctx.SSE.Send(ctx.ClientInfo.hSocket, "order_created", _
"{\"order_id\":\"" & orderId & "\"}")
Exit Sub
Rollback:
ctx.Db.TransRollback
End SubContext 生命周期
┌────────────────────────────────────────────────────────────────┐
│ 请求开始 │
│ 创建 Context 对象 │
└────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ 1. 解析请求 │
│ - ctx.Request 填充数据 │
│ - ctx.ClientInfo 填充客户端信息 │
│ - ctx.Cookies 解析请求 Cookie │
│ - ctx.Session 加载会话数据 │
└────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ 2. 执行前置中间件 (可读写 ctx.UserData) │
│ - 中间件可以访问和修改 Context 的所有属性 │
│ - 可调用 ctx.Abort 终止请求 │
│ - 可调用 ctx.SkipNextMiddleWare 跳过剩余中间件 │
│ - 通过 ctx.UserData("key") = value 传递数据给后续流程 │
└────────────────────────────────────────────────────────────────┘
│ ctx.UserData 向下传递
▼
┌────────────────────────────────────────────────────────────────┐
│ 3. 执行控制器 (可读写 ctx.UserData) │
│ - 读取 ctx.Request 获取请求数据 │
│ - 使用 ctx.Db 操作数据库 │
│ - 操作 ctx.Session 管理会话 │
│ - 设置 ctx.Cookies 写入响应 Cookie │
│ - 调用 ctx.Response 发送响应 │
│ - 使用 ctx.SSE 发送实时消息(如需要) │
│ - 读取 ctx.UserData 获取中间件传递的数据 │
│ - 通过 ctx.UserData 传递数据给后置处理 │
└────────────────────────────────────────────────────────────────┘
│ ctx.UserData 向下传递
▼
┌────────────────────────────────────────────────────────────────┐
│ 4. 执行后置处理 (可读取 ctx.UserData) │
│ - 保存 ctx.Session 到持久化存储 │
│ - 发送响应 Cookie │
│ - 执行后置中间件 │
│ - 读取 ctx.UserData 进行日志记录、统计等 │
└────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ 请求结束 │
│ 释放 Context 对象 │
└────────────────────────────────────────────────────────────────┘最后更新: 2026-05-17