Skip to content

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 Sub

管理请求和响应中的 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 With

Db - 数据库对象

提供数据库访问能力。

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.TransCommit

ClientInfo - 客户端信息

包含连接客户端的信息。

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 Sub

Server - 服务器配置

访问服务器配置信息。

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 If

SSE - 实时推送

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 If

TimeUse - 耗时统计

用于统计请求处理耗时。

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 Sub

UserData - 用户数据存储

用于在请求生命周期内传递自定义数据。

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 Sub

SkipNextMiddleWare - 跳过后续中间件

跳过剩余的中间件,直接进入控制器。

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 Sub

Context 生命周期

┌────────────────────────────────────────────────────────────────┐
│                         请求开始                                │
│                    创建 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

VB6及其LOGO版权为微软公司所有