首先,说一下目录结构:

一、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调用的更多相关文章

  1. [原创]C/C++语言中,如何在main.c或main.cpp中调用另一个.c文件

    C/C++语言中,如何在main.cpp中调用另一个.c文件主要有5种思路: 1.在VS2012 IDE中,将被引用的.c文件后缀名全部修改为.h,然后通过IDE的解决方案资源管理器中鼠标右键单击“头 ...

  2. C语言中,头文件和源文件的关系(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...

  3. C 语言中 setjmp 和 longjmp

    在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...

  4. C语言中的static 详细分析

    转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...

  5. C语言中system()函数的用法总结(转)

    system()函数功能强大,很多人用却对它的原理知之甚少先看linux版system函数的源码: #include <sys/types.h> #include <sys/wait ...

  6. C语言中malloc()和calloc()c函数用法

    C语言中malloc()和calloc()c函数用法   函数malloc()和calloc()都可以用来动态分配内存空间,但两者稍有区别. malloc()函数有一个参数,即要分配的内存空间的大小: ...

  7. (七)C语言中的void 和void 指针类型

    许多初学者对C中的void 和void 的指针类型不是很了解.因此常常在使用上出现一些错误,本文将告诉大家关于void 和void 指针类型的使用方法及技巧. 1.首先,我们来说说void 的含义: ...

  8. 转:C语言中的static变量和C++静态数据成员(static member)

    转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量        a.静态局部变量在函数内定义,生存期为整个程序 ...

  9. C语言中,数组名作为参数传递给函数时,退化为指针

    C语言中,数组名作为参数传递给函数时,退化为指针   C语言中,数组名作为参数传递给函数时,退化为指针:需要数组大小时, 需要一个参数传数组名,另一个传数组大小. 数组名做函数参数时,就相当于指针了. ...

随机推荐

  1. Java异常(二) 《Effective Java》中关于异常处理的几条建议

    概要 本章是从<Effective Java>摘录整理出来的关于异常处理的几条建议.内容包括:第1条: 只针对不正常的情况才使用异常第2条: 对于可恢复的条件使用被检查的异常,对于程序错误 ...

  2. centos7虚拟机(vmware)通过U盘传文件

    centos7虚拟机(vmware)通过U盘传文件 centos7虚拟机安装以后,WINDOWS给CENTOS7传文件,除了在CENTOS7安装SAMBA外,其实通过U盘也是可以的. CENTOS7对 ...

  3. Javascript:自己写异步流程编程框架

    背景 自从NodeJs出来以后,异步编程便更加系统化和框架话了,为了应对异步编程框架带来的深层嵌套问题,社区也出现了异步流程编程框架,本文主要对异步流程框架做一个简单的解析. 现配代码了 var As ...

  4. Kali Linux 与 BackTrack Linux

     (一)BackTrack BackTrack是基于Ubuntu的自启动运行光盘,它包含了一套安全及计算机取证工具.它其实是依靠融合Auditor Security Linux和WHAX(先前的Who ...

  5. 机器学习的MLE和MAP:最大似然估计和最大后验估计

    https://zhuanlan.zhihu.com/p/32480810 TLDR (or the take away) 频率学派 - Frequentist - Maximum Likelihoo ...

  6. [转]Nginx+mysql+php-fpm负载均衡配置实例

    转 : http://www.jbxue.com/article/7923.html 介绍一个nginx.mysql.php-fpm环境下配置负载均衡的例子,有需要的朋友,可以参考下. 系统环境如下: ...

  7. git如何上传所有的新文件 gitlab如何上传所有的新文件 git本地覆盖服务器 强制本地覆盖服务器

    原文地址:  https://blog.csdn.net/qq_28093585/article/details/78749153 目的描述:新建的git项目,项目中有许多要从本地上传到git仓库的新 ...

  8. 脚本不得关闭非脚本打开的窗口。Scripts may close only the windows that were opened by it

    今天脚本了里写了一句话: window.close() 但是浏览器却报了警告提示:Scripts may close only the windows that were opened by it,而 ...

  9. org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value '20Spring Jackson 反序列化Date时遇到的问题

    Jackson对于date的反序列化只支持几种,如果不符合默认格式则会报一下错误 org.codehaus.jackson.map.JsonMappingException: Can not cons ...

  10. POJ 1719 Shooting Contest(二分图匹配)

    POJ 1719 Shooting Contest id=1719" target="_blank" style="">题目链接 题意:给定一个 ...