Go语言中的RPC调用
首先,说一下目录结构:

一、HttpRPC
1、建立服务文件
/*Go RPC的函数只有符合下面的条件才能被远程访问,不然会被忽略,详细的要求如下:
函数必须是导出的(首字母大写)
必须有两个导出类型的参数,
第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的
函数还要有一个返回值error
举个例子,正确的RPC函数格式如下:
func (t *T) MethodName(argType T1, replyType *T2) error
*/
package common import (
"errors"
) type Args struct {
A, B float32
}
type Result struct {
Value float32
}
type MathService struct {
} func (s *MathService) Add(args *Args, result *Result) error {
result.Value = args.A + args.B
return nil
} func (s *MathService) Divide(args *Args, result *Result) error {
if args.B == 0 {
return errors.New("除数不能为零!")
}
result.Value = args.A / args.B
return nil
}
2、服务端代码:
package main import (
"fmt"
"net/http"
"net/rpc" "../common"
) func main() {
var ms = new(common.MathService)
rpc.Register(ms)
rpc.HandleHTTP() //将Rpc绑定到HTTP协议上。
fmt.Println("启动服务...")
err := http.ListenAndServe(":1234", nil)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println("服务已停止!")
}
3、客户端调用代码:
package main import (
"fmt"
"net/rpc" "../common"
) func main() {
var args = common.Args{17, 8}
var result = common.Result{} var client, err = rpc.DialHTTP("tcp", "127.0.0.1:1234")
if err != nil {
fmt.Println("连接RPC服务失败:", err)
}
err = client.Call("MathService.Divide", args, &result)
if err != nil {
fmt.Println("调用失败:", err)
}
fmt.Println("调用结果:", result.Value)
}
4、测试:

二、HttpRPC
1、建立服务文件
/*Go RPC的函数只有符合下面的条件才能被远程访问,不然会被忽略,详细的要求如下:
函数必须是导出的(首字母大写)
必须有两个导出类型的参数,
第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的
函数还要有一个返回值error
举个例子,正确的RPC函数格式如下:
func (t *T) MethodName(argType T1, replyType *T2) error
*/
package common import (
"errors"
) type Args struct {
A, B float32
}
type Result struct {
Value float32
}
type MathService struct {
} func (s *MathService) Add(args *Args, result *Result) error {
result.Value = args.A + args.B
return nil
} func (s *MathService) Divide(args *Args, result *Result) error {
if args.B == 0 {
return errors.New("除数不能为零!")
}
result.Value = args.A / args.B
return nil
}
2、服务端文件
package main import (
"fmt"
"net"
"net/rpc" "../common"
) func main() {
var ms = new(common.MathService) //实例化服务对像
rpc.Register(ms) //注册这个服务
fmt.Println("启动服务...")
var address, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:1234") //定义TCP的服务承载地址
listener, err := net.ListenTCP("tcp", address) //监听TCP连接
if err != nil {
fmt.Println("启动失败!", err)
}
for {
conn, err := listener.Accept() //如果接受到连接
if err != nil {
continue
}
fmt.Println("接收到一个调用请求...")
rpc.ServeConn(conn) //让此rpc绑定到该Tcp连接上。
}
//fmt.Println("服务已停止!")
}
3、客户端代码:
// main.go
package main import (
"fmt"
"net/rpc" "../common"
) func main() {
var client, err = rpc.Dial("tcp", "127.0.0.1:1234")
if err != nil {
fmt.Println("连接不到服务器:", err)
}
var args = common.Args{40, 3}
var result = common.Result{}
fmt.Println("开始调用!")
err = client.Call("MathService.Add", args, &result)
if err != nil {
fmt.Println("调用失败!", err)
}
fmt.Println("调用成功!结果:", result.Value)
}
4、效果:

Go语言中的RPC调用的更多相关文章
- [原创]C/C++语言中,如何在main.c或main.cpp中调用另一个.c文件
C/C++语言中,如何在main.cpp中调用另一个.c文件主要有5种思路: 1.在VS2012 IDE中,将被引用的.c文件后缀名全部修改为.h,然后通过IDE的解决方案资源管理器中鼠标右键单击“头 ...
- C语言中,头文件和源文件的关系(转)
简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...
- C 语言中 setjmp 和 longjmp
在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...
- C语言中的static 详细分析
转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...
- C语言中system()函数的用法总结(转)
system()函数功能强大,很多人用却对它的原理知之甚少先看linux版system函数的源码: #include <sys/types.h> #include <sys/wait ...
- C语言中malloc()和calloc()c函数用法
C语言中malloc()和calloc()c函数用法 函数malloc()和calloc()都可以用来动态分配内存空间,但两者稍有区别. malloc()函数有一个参数,即要分配的内存空间的大小: ...
- (七)C语言中的void 和void 指针类型
许多初学者对C中的void 和void 的指针类型不是很了解.因此常常在使用上出现一些错误,本文将告诉大家关于void 和void 指针类型的使用方法及技巧. 1.首先,我们来说说void 的含义: ...
- 转:C语言中的static变量和C++静态数据成员(static member)
转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量 a.静态局部变量在函数内定义,生存期为整个程序 ...
- C语言中,数组名作为参数传递给函数时,退化为指针
C语言中,数组名作为参数传递给函数时,退化为指针 C语言中,数组名作为参数传递给函数时,退化为指针:需要数组大小时, 需要一个参数传数组名,另一个传数组大小. 数组名做函数参数时,就相当于指针了. ...
随机推荐
- Netbeans 安装emmet插件
一.下载插件 http://plugins.netbeans.org/plugin/48315/emmet 二.点击工具-> 插件 -> 已下载 -> 添加插件 ->(导入下载 ...
- Exchange2003/2010共存模式环境迁移
一.我司的exchange2010架构设计基于中心的模式进行.而且基于exchange2010sp3进行. 基于dag三台架构设计进行,截止到5月14日,北京局基于2台dag进行,大连局基于excha ...
- Greenplum入门——基础知识、安装、常用函数
Greenplum入门——基础知识.安装.常用函数 2017年10月08日 22:03:09 在咖啡里溺水的鱼 阅读数:8709 版权声明:本文为博主原创,允许非商业性质转载但请注明原作者和出处 ...
- Asp.Net Core 文件上传处理
本文主要介绍后台接收处理 1.在使用控制器接收 : [HttpPost] : public IActionResult UploadFiles(IList<IFormFile> files ...
- Python集合模块collections
collections collections是Python内建的一个集合模块,提供了许多有用的集合类. namedtuple 我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: ...
- [转]最完美解决Nginx部署ThinkPHP项目的办法
From : http://www.htmltec.com/archives/302 网上通用解决方法的配置如下: server { location / { index index.htm inde ...
- IIS7增加mine类型,以便可以访问apk
1.打开IIS 2.找到mine类型,单击右边的添加 3.输入apk的配置 application/vnd.android-package-archive .这样,用户就可以直接访问apk了
- django错误:Connection reset by peer
django使用自身的web服务器时,处理并发的能力很弱,如果客户端并发连接数超过了其承载量,服务器会将其中一些连接关闭,从而导致这个问题 https://blog.csdn.net/xc_zhou/ ...
- (八十七)AutoLayout的简单介绍与实例
AutoLayout是继AutoResizing之后的一种自己主动布局方法.攻克了AutoResizing无法处理控件间相互关系的问题. AutoLayout在storyboard中通过底部工具条设置 ...
- [leetcode]Pascal's Triangle @ Python
原题地址:https://oj.leetcode.com/problems/pascals-triangle/ 题意: Given numRows, generate the first numRow ...