You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言TCP JSON-RPC服务器错误捕获与客户端断开检测

问题解答

1. JSON-RPC服务器端捕获错误的方式

在Go的JSON-RPC框架中,错误捕获主要围绕两种场景处理:

  • 业务逻辑错误捕获:在RPC方法内部直接处理业务异常,将需要传递给客户端的错误通过方法返回值返回(JSON-RPC会自动序列化该错误并传递给客户端),同时可在服务器端记录错误日志:

    func (t *Arith) Add(args *Args, result *int) error {
        if args.A < 0 || args.B < 0 {
            err := fmt.Errorf("不允许传入负数:A=%d, B=%d", args.A, args.B)
            fmt.Println("服务器业务错误:", err) // 服务器端记录错误
            return err
        }
        *result = args.A + args.B
        return nil
    }
    
  • 连接与协议级错误捕获:jsonrpc.ServeConn会在连接关闭或发生底层协议错误时返回,可在goroutine中捕获其返回的错误,实现底层异常的监控:

    go func(conn net.Conn) {
        err := jsonrpc.ServeConn(conn)
        if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
            fmt.Println("服务器连接错误:", err)
        }
    }(conn)
    

2. 检测客户端断开连接(无需心跳包)

Go的net.Conn没有内置断开回调机制,但可以利用jsonrpc.ServeConn的生命周期特性实现需求:jsonrpc.ServeConn会一直阻塞处理该连接上的RPC请求,直到客户端断开连接或发生错误时返回,只需在该函数返回后打印断开提示即可。

修改后的服务器代码如下:

package main

import (
    "fmt"
    "net"
    "net/rpc"
    "net/rpc/jsonrpc"
    "strings"
)

type Arith int

type Args struct {
    A, B int
}

func (t *Arith) Add(args *Args, result *int) error {
    *result = args.A + args.B
    return nil
}

func RunServer() {
    arith := new(Arith)
    rpc.Register(arith)

    listener, err := net.Listen("tcp", ":8080")
    if err != nil {
        fmt.Println("启动服务器失败:", err)
        return
    }
    defer listener.Close()

    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println("接受连接失败:", err)
            continue
        }

        // 启动goroutine处理连接,在ServeConn返回后打印断开信息
        go func(c net.Conn) {
            // ServeConn阻塞直到连接关闭或出错
            err := jsonrpc.ServeConn(c)
            // 过滤正常关闭的提示(可选)
            if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
                fmt.Println("连接异常:", err)
            }
            fmt.Println("client disconnected!")
            c.Close()
        }(conn)
    }
}

func main() {
    RunServer()
}

原理说明:

当客户端主动调用client.Close()断开连接,或因网络异常导致连接中断时,jsonrpc.ServeConn会退出阻塞并返回,后续的断开提示语句会自动执行。这种方式完全符合JSON-RPC框架的设计逻辑,不会像虚拟读取那样干扰协议解析流程。

内容的提问来源于stack exchange,提问作者qciccoretti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:35:06