首先,说一下目录结构:

一、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. iOS 字符串 中包含 % 百分号的方法

    百分号的转换,NSString中需要格式化的字符串中百分号使用%%表示,而char*中百分号也是使用%%表示. 例如:NSLog(@"%%%@%%",@"hello&qu ...

  2. CoreTelephony.framework 引入程序方法

    #import <CoreTelephony/CTTelephonyNetworkInfo.h> #import <CoreTelephony/CTCarrier.h> 参考: ...

  3. SIP SDP Profile-level-id解析

    转自:http://blog.csdn.net/wh8_2011/article/details/53558504 基于SIP协议的VOIP通信,该字段通常位于视频协商sdp报文中,如: video  ...

  4. Java POI 3.17写入、导入EXCEL性能测试

    我们先测试一下写入 50000 条 程序源码: 写入的excel文件信息 再看一下文件的结构 我们再次测试一下导入数据库的性能(用移动的网络上传至电信服务器): 在导入的过程中也可以中止导入行为: 上 ...

  5. python的重试库tenacity用法以及类似库retry、requests实现

    介绍 tenacity is an Apache 2.0 licensed general-purpose retrying library, written in Python, to simpli ...

  6. Guava Enums

    概述 Enums提供了几个操作Enum的便利方法 常用方法 Field getField(Enum<?> enumValue): 返回变量名为enumValue变量值的Field < ...

  7. ASP.NET Razor 简介

    ylbtech-.NET: ASP.NET Razor 简介 Razor 不是一种编程语言.它是服务器端的标记语言. 1. 什么是 Razor?返回顶部 Razor 是一种标记语法,可以让您将基于服务 ...

  8. 从客户端(SeekingJobs="<B>·</B> 物流规划,<B>·</...")中检测到有潜在危险的 Request.Form 值。

    今天提交各东西发觉出错了,错误信息如下: “/”应用程序中的服务器错误. 从客户端(SeekingJobs="<B>·</B> 物流规划,<B>·< ...

  9. matlib实现梯度下降法(序一)

    数据来源:http://archive.ics.uci.edu/ml/datasets/Combined+Cycle+Power+Plant 数据描述: 有四个输入特征,这些数据来自电厂,这四个特征和 ...

  10. Libnids读书笔记 (转)

    一.当日工作(或学习)内容及进展情况(以条目式陈述,必要时配图说明) Libnids读书笔记: Libnids(Library Network Intusion Detection System)网络 ...