找回密码
 会员注册
查看: 22|回复: 0

快速搭建GoJSON-RPCServer

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
64872
发表于 2024-10-10 15:10:19 | 显示全部楼层 |阅读模式
快速搭建Go JSON-RPC Server 快速搭建Go JSON-RPC Server 张大辉 贝壳产品技术 贝壳产品技术 “贝壳产品技术公众号”作为贝壳官方产品技术号,致力打造贝壳产品、技术干货分享平台,面向互联网/O2O开发/产品从业者,每周推送优质产品技术文章、技术沙龙活动及招聘信息等。欢迎大家关注我们。 242篇内容 2018年11月02日 20:00 作者张大辉(企业代号名),目前负责贝壳找房PHP、GO方向研发工作。1前言jsonrpc是无状态、轻量级的远程过程调用协议,传递数据格式为JSON。GO 官方提供rpc包和jsonrpc包,与rpc包不同的是,jsonrpc可以实现跨平台通信。本文将介绍如何用Go快速搭建一个jsonrpc Server,用PHP实现jsonrpc client进行验证,同时也记录下验证过程中出现的坑。2实现jsonrpc_server2.1 引入包1import(2"net/rpc"3"net"4"log"5"net/rpc/jsonrpc"6"fmt"7)2.2 定义 server端要伺服的 rpc method 1//rpchandler 2typeEdwinint 3//定义rpcmethod第一个参数是请求对象,第二参数是返回对象,返回值是返回rpc内部调用过程中出现的错误信息 4func(this*Edwin)Add(argsmap[string]float64,res*float64)error{ 5*res=args["num1"]+args["num2"] 6returnnil 7} 8func(this*Edwin)Multi(argsmap[string]interface{},res*float64)error{ 9*res=args["num1"].(float64)*args["num2"].(float64)10returnnil11}2.3 注册rpc handler,开启server connection 1rpc.Register(new(Edwin)) 2 3l,err:=net.Listen("tcp",":11223") 4 5iferr!=nil{ 6log.Fatalln("listenerror:",err) 7} 8 9for{10conn,err:=l.Accept()1112iferr!=nil{13log.Fatalln("acceptfailed:",err)14}1516fmt.Println("jsonrpcserverstartlisenon11223...")171819gofunc(connnet.Conn){20fmt.Println("anewconnectioniscoming...")21jsonrpc.ServeConn(conn)22}(conn)23}3php实现jsonrpc_client 1classJsonRpc{ 2private$conn; 3 4function__construct($host,$port){ 5$this->conn=fsockopen($host,$port,$errno,$errStr,2); 6 7} 8 9publicfunctioncall($method,$params){1011$err=fwrite($this->conn,json_encode([12'method'=>$method,13'params'=>array($params),14'id'=>1,15]));1617if(empty($err)){18returnfalse;19}2021stream_set_timeout($this->conn,0,300);2223$line=fgets($this->conn);24if($line===false){25returnNULL;26}2728fclose($this->conn);2930returnjson_decode($line,true);31}32}3334$client=newJsonRPC("127.0.0.1",11223);35$client2=newJsonRPC("127.0.0.1",11223);36$ret=$client->Call("Edwin2.Multi",array("num1"=>14,"num2"=>20));37$ret2=$client2->Call("Edwin2.Add",array("num1"=>14,"num2"=>20));38var_export($ret);39var_export($ret2);4验证 1#开启jsonrpcserver 2gorunjsonrpc_server.go 3#正常会输出监听信息 4>jsonrpcserverstartlisenon11223... 5>anewconnectioniscoming... 6#执行jsonrpcclient 7phpjsonrpc_clinent.php 8#正常输出以下信息 9>array(10'id'=>1,11'result'=>280,12'error'=>NULL,13)array(14'id'=>1,15'result'=>34,16'error'=>NULL,17)5验证中的问题问题代码:1$err=fwrite($this->conn,json_encode([2'method'=>$method,3'params'=>array($params),4//'params'=>$params//不能这么用5'id'=>1,6]));params参数必须用array包含,如果直接传递过去,将报出以下错误信息:1array(2'id'=>1,3'result'=>NULL,4'error'=>'json:cannotunmarshalobjectintoGovalueoftype[1]interface{}',5)根据JSON-RPC规范,参数params可以是Json Array,也可以是Json Object,可是为什么还报错呢?于是查看源码,发现:1在src/net/rpc/jsonrpc/server.go第95行,go官方实现指定params必须是数组:2varparams[1]interface{}3params[0]=x4returnjson.Unmarshal(*c.req.Params,¶ms)5...通过这个坑发现,Go jsonrpc并未严格按照JSON-RPC规范实现。6内部处理流程 预览时标签不可点 阅读原文关闭更多小程序广告搜索「undefined」网络结果 阅读原文
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-29 01:28 , Processed in 1.005784 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表