当前位置: 首页 > news >正文

【golang/jsonrpc】go-ethereum中json rpc初步使用(websocket版本)

说在前面

  • 操作系统:win11 wsl2
  • go-ethereum版本:1.15.8

关于json-rpc

  • 官网

server

  • 定义方法
    type CalculatorService struct{}
    
    func (s *CalculatorService) Add(a, b int) int {
    	return a + b
    }
    
    func (s *CalculatorService) Div(a, b int) (int, error) {
    	if b == 0 {
    		return 0, errors.New("divide by zero")
    	}
    	return a / b, nil
    }
    
    这里我们简单定义两个方法
  • 启动服务
    func main() {
    	calculator := new(CalculatorService)
    
    	// 创建 RPC 服务器
    	rpcServer := rpc.NewServer()
    
    	// 注册服务
    	if err := rpcServer.RegisterName("calculator", calculator); err != nil {
    		panic(err)
    	}
    
    	// 启动 HTTP 服务器
    	println("WebSocket server listening on :8080")
    
    	httpHandler := rpcServer.WebsocketHandler([]string{"*"})
    	http.Handle("/ws", httpHandler)
    
    	http.ListenAndServe(":8080", nil)
    }
    

client

  • 调用
    在调用的时候,方法名需要指定为receiver_method,例如我们要调用CalculatorService.Add,那么调用名为calculator_add,注意,这里的calculator为server端注册时的RegisterName("calculator", calculator),而不是CalculatorService
    func main() {
    	// 连接 WebSocket 服务端
    	client, err := rpc.DialWebsocket(context.Background(), "ws://192.168.1.6:8080/ws", "")
    	if err != nil {
    		panic(err)
    	}
    	defer client.Close()
    
    	// 调用远程方法
    	var result int
    	err = client.Call(&result, "calculator_add", 3, 5)
    	if err != nil {
    		panic(err)
    	}
    
    	fmt.Println("Result:", result) // 输出: Result: 8
    }
    
    假设将server端的RegisterName("calculator", calculator)改为RegisterName("calculate", calculator)
    panic: the method calculator_add does not exist/is not available
    

注意事项

返回值

  • server端的方法返回值只能有三种数量0,1,2
    • 0,即无返回值
    • 1,即自定义返回值或者一个error
    • 2,即自定义返回值+一个error
  • 这样,在client端调用的时候,err = client.Call(&result, "calculator_add", 3, 5)result对应自定义返回值,err对应返回的error
  • 例如,我们调用
    err = client.Call(&result, "calculate_div", 3, 0)
    if err != nil {
    	panic(err)
    }
    
    得到的err即为server端Div方法返回的error
    panic: divide by zero
    

server端调用client端

  • 支持反向调用
  • 在我们定义server端方法的时候,可以增加一个context参数
    type CalculatorService struct{}
    
    func (s *CalculatorService) Add(ctx context.Context, a, b int) int {
    	return a + b
    }
    
    func (s *CalculatorService) Div(ctx context.Context, a, b int) (int, error) {
    	if b == 0 {
    		return 0, errors.New("divide by zero")
    	}
    	return a / b, nil
    }
    
  • 这样我们就可以获取到client,进而调用其方法,例如,我们在client端添加一个方法
    type CalcService struct{}
    
    func (s *CalcService) GetParam(ctx context.Context) int {
    	return 88
    }
    
    然后在client端注册
    func main() {
    	// 连接 WebSocket 服务端
    	client, err := rpc.DialWebsocket(context.Background(), "ws://192.168.1.6:8080/ws", "")
    	if err != nil {
    		panic(err)
    	}
    	defer client.Close()
    
    	calculator := new(CalcService)
    	client.RegisterName("calc", calculator)
    
    	// 调用远程方法
    	var result int
    	err = client.Call(&result, "calculate_add", 3, 0)
    	if err != nil {
    		panic(err)
    	}
    
    	fmt.Println("Result:", result) // 输出: Result: 8
    }
    
    在server端的Add方法中,我们将b的值改为从client端获取
    func (s *CalcService) Add(ctx context.Context, a, b int) int {
    	client, ok := rpc.ClientFromContext(ctx)
    	if ok {
    		client.Call(&b, "calc_getParam")
    	}
    	return a + b
    }
    
    这样运行后的结果为:
    Result: 91
    
  • 通过这种方式,我们可以在server端添加一个Register的方法,在client连接后,client主动调用Register方法,这样我们就可以管理所有client了

相关文章:

  • vue3使用keep-alive缓存组件与踩坑日记
  • [实战] 二分查找与哈希表查找:原理、对比与C语言实现(附完整C代码)
  • PostgreSQL 实例运行状态全面检查
  • 考研数据结构精讲:数组与特殊矩阵的压缩存储技巧(包含真题及解析)
  • 大数据面试问答-Hadoop/Hive/HDFS/Yarn
  • 基于SpringBoot汽车零件商城系统设计和实现(源码+文档+部署讲解)
  • vue3+nodeJs+webSocket实现聊天功能
  • stack overflow国内无法访问原因
  • 中文编码,GB系列,UTF
  • 正则表达式使用知识(日常翻阅)
  • 基于频率约束条件的最小惯量需求评估,包括频率变化率ROCOF约束和频率最低点约束matlab/simulink
  • 探索 Rust 语言:高效、安全与并发的完美融合
  • hashcode() equals()
  • 如何使用阿里云邮件推送免费群发邮件
  • 基本命令题与答案
  • 3 VS Code 配置优化与实用插件推荐:settings.json 详解、CodeGeeX 智能编程助手及插件离线安装方法
  • 企业经营决策风险
  • 在人工智能与计算机技术融合的框架下探索高中教育数字化教学模式的创新路径
  • 系统的安全及应用
  • 【数字电路】第四章 组合逻辑电路
  • 快评|印巴为何停火?已达成“一场胜利,各自表述”的效果
  • 印巴战火LIVE丨“快速接近战争状态”:印度袭击巴军事基地,巴启动反制军事行动
  • 习近平向中国人民解放军仪仗队致意
  • 中方就乌克兰危机提出新倡议?外交部:中方立场没有变化
  • 胖东来关闭官网内容清空?工作人员:后台维护升级
  • 伯克希尔董事会投票决定:阿贝尔明年1月1日起出任CEO,巴菲特继续担任董事长