动手实现一个简单的 rpc 框架到入门 grpc (上)
rpc 全称 Remote Procedure Call
远程过程调用,即调用远程方法。我们调用当前进程中的方法时很简单,但是想要调用不同进程,甚至不同主机、不同语言中的方法时就需要借助 rpc 来实现,下面我一步步实现一个简单的 rpc 调用。
server 端注册函数,运行并接收客户端请求
func main() {
srv := NewServer()
srv.Register("fn", fn)
srv.Run()
}
//为了简单,这里只需要接收到消息打印出就代表执行成功
func fn(args ...interface{}) {
fmt.println(args)
}
定义请求格式
type rpcData struct {
Name string //函数名
Args []interface{} //参数
}
server 运行起来后,接收 socket 请求,解析消息调用已注册的函数
//server结构体
type server struct {
conn net.Conn //socket连接
maps map[string]reflect.Value //函数字典
}
//构造函数
func NewServer() *server {
return &server{
maps: make(map[string]reflect.Value),
}
}
//注册函数
func (s *server) Register(fname string, fun interface{}) {
if _, ok := s.maps[fname]; !ok {
s.maps[fname] = reflect.ValueOf(fun)
}
}
//运行一个socket接收请求
func (s *server) Run() {
listen, err := net.Listen("tcp4", ":3001")
if err != nil {
panic(err)
}
for {
s.conn, err = listen.Accept()
if err != nil {
continue
}
go s.handleConnect()
}
}
处理请求时,这里为了简单我使用 json 解析,同时需要定义一个简单的协议:客户端发送时,前4个字节放置消息长度,这样服务端接收到时就能知道消息的长度,从而正常解码消息
func (s *server) handleConnect() {
for {
header := make([]byte, 4)
if _, err := s.conn.Read(header); err != nil {
continue
}
bodyLen := binary.BigEndian.Uint32(header)
body := make([]byte, int(bodyLen))
if _, err := s.conn.Read(body); err != nil {
continue
}
var req rpcData
if err := json.Unmarshal(body, &req); err != nil {
continue
}
inArgs := make([]reflect.Value, len(req.Args))
for i := range req.Args {
inArgs[i] = reflect.ValueOf(req.Args[i])
}
fn := s.maps[req.Name]
fn.Call(inArgs)
}
}
client 端只需调用函数,通过网络发送请求
func main() {
var req = rpcData{"fn", []interface{}{1, "aaa"}}
rpcCall(req)
}
func rpcCall(data rpcData) {
conn, err := net.Dial("tcp4", "127.0.0.1:3001")
if err != nil {
panic(err)
}
req, err := json.Marshal(data)
if err != nil {
panic(err)
}
buf := make([]byte, 4+len(req))
binary.BigEndian.PutUint32(buf[:4], uint32(len(req)))
copy(buf[4:], req)
_, err = conn.Write(buf)
if err != nil {
panic(err)
}
}
测试时,首先运行 server,然后运行 client,只要看到正确的打印就代表调用成功,这就是一个最简单(简陋)的 rpc 了。
当我们使用 grpc 这些 rpc 框架时,就可以不用自己实现消息编码解码、socket连接这些细节,专注于业务逻辑,而且更为可靠。
动手实现一个简单的 rpc 框架到入门 grpc (上)的更多相关文章
- 动手实现一个简单的 rpc 框架到入门 grpc (下)
之前手动实现了一次简陋的 rpc 调用,为了简单使用了 json 编码信息,其实这是非常不可靠的,go 中 json 解析会有一些问题,比如整数会变成浮点数,而且 json 字符串比较占空间. gRP ...
- 徒手撸一个简单的RPC框架
来源:https://juejin.im/post/5c4481a4f265da613438aec3 之前在牛逼哄哄的 RPC 框架,底层到底什么原理得知了RPC(远程过程调用)简单来说就是调用远程的 ...
- 动手写一个简单的Web框架(模板渲染)
动手写一个简单的Web框架(模板渲染) 在百度上搜索jinja2,显示的大部分内容都是jinja2的渲染语法,这个不是Web框架需要做的事,最终,居然在Werkzeug的官方文档里找到模板渲染的代码. ...
- 动手写一个简单的Web框架(Werkzeug路由问题)
动手写一个简单的Web框架(Werkzeug路由问题) 继承上一篇博客,实现了HelloWorld,但是这并不是一个Web框架,只是自己手写的一个程序,别人是无法通过自己定义路由和返回文本,来使用的, ...
- 动手写一个简单的Web框架(HelloWorld的实现)
动手写一个简单的Web框架(HelloWorld的实现) 关于python的wsgi问题可以看这篇博客 我就不具体阐述了,简单来说,wsgi标准需要我们提供一个可以被调用的python程序,可以实函数 ...
- 自己动手写一个简单的MVC框架(第一版)
一.MVC概念回顾 路由(Route).控制器(Controller).行为(Action).模型(Model).视图(View) 用一句简单地话来描述以上关键点: 路由(Route)就相当于一个公司 ...
- 一个简单的"RPC框架"代码分析
0,服务接口定义---Echo.java /* * 定义了服务器提供的服务类型 */ public interface Echo { public String echo(String string) ...
- 自己动手写一个简单的MVC框架(第二版)
一.ASP.NET MVC核心机制回顾 在ASP.NET MVC中,最核心的当属“路由系统”,而路由系统的核心则源于一个强大的System.Web.Routing.dll组件. 在这个System.W ...
- 一个简单的RPC框架
一个 系统模型 二.数据库代码实现 1. mkdir database cd database vim dbInit.c /* * * Database Init tool * */ #include ...
随机推荐
- EasyARM-iMX257 linux两年前的笔记
我依然清晰的记得刚拿到Imx283 257的情景,兴奋中充满忧虑,对操作系统的概念只知一二,不知三四!!周立功出品的资料我一直觉得是比较精品的,同样这款iMX283配套的文档资料(v1.04)也是比较 ...
- 快速升级Zabbix 5.0 版本
Zabbix 5.0 增加了很多新功能,如:垂直菜单.隐藏菜单.用户界面中的测试项目.限制代理检查.查找并替换预处理步骤 ES7支持等等...快来部署体验一把尝鲜体验 Zabbix 5.0 吧 ...
- 安装apoc插件
APOC是Neo4j 3.3版本推出时推荐的一个Java存储过程包,包含丰富的函数和存储过程,作为对Cypher所不能提供的复杂图算法和数据操作功能的补充,APOC还具有使用灵活.高性能等优势. 1. ...
- void out2() const{
include "stdafx.h" include using namespace std; class aa{ int num; public: aa(){ int b =10 ...
- filebeat v6.3 如何增加ip 字段
我们知道filebeat获取数据之后是会自动获取主机名的,项目上有需要filebeat送数据的时候送一个ip字段出来 方法:配置filebeat配置文件 解释一下:field 是字段模块 在这个模块下 ...
- Fibonacci(模板)【矩阵快速幂】
Fibonacci 题目链接(点击) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 20989 Accepted: 14 ...
- CSS基础之简单介绍
网页诞生初期,没有描述样式的语言,创建了很多用于描述样式的标签.但这些标签破坏了html作为一门结构语言的表现. 于是,W3C在1995年开始起草CSS,提出将结构和样式分离的解决方案. 元素 元素是 ...
- 网易java高级开发课程 面对上亿数据量,网易用啥技术?
- 安装Centos 7 并且配置远程登录
安装: 1.安装VMware fusion.https://www.vmware.com/cn/products/fusion/fusion-evaluation.html 2.下载centos 7 ...
- swift对象存储安装
对象存储服务概览 OpenStack对象存储是一个多租户的对象存储系统,它支持大规模扩展,可以以低成本来管理大型的非结构化数据,通过RESTful HTTP 应用程序接口. 它包含下列组件: 代理服务 ...