go语言net包rpc远程调用的使用示例

rpc 包提供了一个方法来通过网络或者其他的I/O连接进入对象的外部方法. 一个server注册一个对象, 标记它成为可见对象类型名字的服务。注册后,对象的外部方法就可以远程调用了。一个server可以注册多个 不同类型的对象,但是却不可以注册多个相同类型的对象。

只有满足这些标准的方法才会被远程调用视为可见;其他的方法都会被忽略:

- 方法是外部可见的。
- 方法有两个参数,参数的类型都是外部可见的。
- 方法的第二个参数是一个指针。
- 方法有返回类型错误

一、基于http的RPC

服务端:

package main;

import (

  "net/rpc"

  "net/http"

  "log"

)

//go对RPC的支持,支持三个级别:TCP、HTTP、JSONRPC

//go的RPC只支持GO开发的服务器与客户端之间的交互,因为采用了gob编码

//注意字段必须是导出

type Params struct {

  Width, Height int;

}

type Rect struct{}

//函数必须是导出的

//必须有两个导出类型参数

//第一个参数是接收参数

//第二个参数是返回给客户端参数,必须是指针类型

//函数还要有一个返回值error

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

func main() {

  rect := new(Rect);

  //注册一个rect服务

  rpc.Register(rect);

  //把服务处理绑定到http协议上

  rpc.HandleHTTP();

  err := http.ListenAndServe(":8080", nil);

  if err != nil {

    log.Fatal(err);

  }

}

客户端:

package main;

import (

  "net/rpc"

  "log"

  "fmt"

)

type Params struct {

  Width, Height int;

}

func main() {

  //连接远程rpc服务

  rpc, err := rpc.DialHTTP("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //调用远程方法

  //注意第三个参数是指针类型

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

}

二、基于tcp的RPC

服务端:

package main;

import (

  "net"

  "log"

  "net/rpc"

)

//注意字段必须是导出

type Params struct {

  Width, Height int;

}

type Rect struct{}

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

func chkError(err error) {

  if err != nil {

    log.Fatal(err);

  }

}

func main() {

  rect := new(Rect);

  //注册rpc服务

  rpc.Register(rect);

  //获取tcpaddr

  tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");

  chkError(err);

  //监听端口

  tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);

  chkError(err2);

  //死循环处理连接请求

  for {

    conn, err3 := tcplisten.Accept();

    if err3 != nil {

      continue;

    }

    //使用goroutine单独处理rpc连接请求

    go rpc.ServeConn(conn);

  }

}

客户端:

package main;

import (

  "net/rpc"

  "fmt"

  "log"

)

type Params struct {

  Width, Height int;

}

func main() {

  //连接远程rpc服务

  //这里使用Dial,http方式使用DialHTTP,其他代码都一样

  rpc, err := rpc.Dial("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //调用远程方法

  //注意第三个参数是指针类型

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

}

三、JSON RPC 方式

jsonrpc方式是数据编码采用了json,而不是gob编码。

服务端:

package main;

import (

  "net"

  "log"

  "net/rpc"

  "net/rpc/jsonrpc"

)

//注意字段必须是导出

type Params struct {

  Width, Height int;

}

type Rect struct{}

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

func chkError(err error) {

  if err != nil {

    log.Fatal(err);

  }

}

func main() {

  rect := new(Rect);

  //注册rpc服务

  rpc.Register(rect);

  //获取tcpaddr

  tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");

  chkError(err);

  //监听端口

  tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);

  chkError(err2);

  for {

    conn, err3 := tcplisten.Accept();

    if err3 != nil {

      continue;

    }

    //使用goroutine单独处理rpc连接请求

    //这里使用jsonrpc进行处理

    go jsonrpc.ServeConn(conn);

  }

}

客户端:

 package main;

import (

  "fmt"

  "log"

  "net/rpc/jsonrpc"

)

type Params struct {

  Width, Height int;

}

func main() {

  //连接远程rpc服务

  //这里使用jsonrpc.Dial

  rpc, err := jsonrpc.Dial("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //调用远程方法

  //注意第三个参数是指针类型

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • golang两种调用rpc的方法

    本文实例讲述了golang两种调用rpc的方法.分享给大家供大家参考,具体如下: golang的rpc有两种方法进行调用,一种是rpc例子中给的: 复制代码 代码如下: package main import (         "net/rpc"         "net/http"         "log"         "net"         "time" ) type Args struct

  • go语言net包rpc远程调用的使用示例

    rpc 包提供了一个方法来通过网络或者其他的I/O连接进入对象的外部方法. 一个server注册一个对象, 标记它成为可见对象类型名字的服务.注册后,对象的外部方法就可以远程调用了.一个server可以注册多个 不同类型的对象,但是却不可以注册多个相同类型的对象. 只有满足这些标准的方法才会被远程调用视为可见:其他的方法都会被忽略: - 方法是外部可见的. - 方法有两个参数,参数的类型都是外部可见的. - 方法的第二个参数是一个指针. - 方法有返回类型错误 一.基于http的RPC 服务端:

  • Go语言net包RPC远程调用三种方式http与json-rpc及tcp

    目录 一.服务端 二.http客户端 三.TCP客户端 四.json客户端 五.运行结果 rpc有多种调用方式,http.json-rpc.tcp 一.服务端 在代码中,启动了三个服务 package main import ( "log" "net" "net/http" "net/rpc" "net/rpc/jsonrpc" "sync" ) //go对RPC的支持,支持三个级别:T

  • openstack中的rpc远程调用的方法

    众所周知,OpenStack的通信方式有两种,一种是基于HTTP协议的RESTFul API方式,另一种则是RPC调用.两种通信方式的应用场景有所不同,在OpenStack中,前者主要用于各组件之间的通信(如nova与glance的通信),而后者则用于同一组件中各个不同模块之间的通信(如nova组件中nova-compute与nova-scheduler的通信). nova中rpc调用非常多,用pycharm点点点跟函数的时候遇到rpc就会点不下去了,不解决直接就看不下去了那种多法 什么是 RP

  • 使用Spring Cloud Feign远程调用的方法示例

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Apache的Http Client.Netty的异步HTTP Client, Spring的RestTemplate.但是,用起来最方便.最优雅的还是要属Feign了. Feign简介 Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便. 它具有可插拔注释支持

  • 基于python实现rpc远程过程调用

    目录 基于python实现RPC的demo 前言 一.主要内容 二.实现步骤 1. 进程间的通信 2. 异步回调实现思路 总结 基于python实现RPC的demo 这是一个远程过程调用(RPC)的实现demo,可以实现不同的python进程之间通信和互相调用函数,简单易用,易于扩展.更多功能也可进一步完善,本文介绍了该实现的主要思路. 前言 计划手撸一个rpc甚久了,在间歇性push自己下终于完成的差不多了.写这个demo的原因,1)是为了学习与思考下这部分主体功能和实现思路,2)是调包时可以

  • PHP远程调用以及RPC框架

    前言 一个项目,从开始到版本更新,一直到最后的版本维护.功能在不断增多,对应的代码量也在不断增加,也就意味着项目变得更不可维护,这时候,我们需要用拆分的方式将一个项目打散,以便开发团队更好的对项目进行维护. 分模块 这个阶段,一般也是项目的初级阶段,由于人手不够,一个服务端的接口项目只有一个开发进行维护,根据开发的习惯,会把项目分成若干个模块进行开发,在一个项目下进行部署. 这样做的缺点在于项目会随着版本更新而变得不可维护. 分项目 随着每个模块功能的不断完善,代码变得更加臃肿.这时候需要对项目

  • Python中实现远程调用(RPC、RMI)简单例子

    远程调用使得调用远程服务器的对象.方法的方式就和调用本地对象.方法的方式差不多,因为我们通过网络编程把这些都隐藏起来了.远程调用是分布式系统的基础. 远程调用一般分为两种,远程过程调用(RPC)和远程方法调用(RMI). RPC RPC属于函数级别的远程调用,其多是通过HTTP传输数据,数据形式有XML.JSON.序列化数据等.在此,用python做一个xml-rpc的示例. 先给服务器端server.py: 复制代码 代码如下: from SimpleXMLRPCServer import S

  • python远程调用rpc模块xmlrpclib的方法

    RPC(Remote Procedure Call Protocol)是远程调用协议,它通过网络请求服务到远端服务器,服务器根据请求做出响应,将结果返回 它是一种C/S模式,客户端可以调用远程服务器上的参数(类似URL)并返回结果 利用rpc可以实现系统的分布式架构,可以将功能分解到多台服务器上进行实现,同时也将也可以将负载打散,分布到不同服务器上,整合计算资源 在openstack中就大量使用了rpc rpc多使用http传输请求,格式有xml,json等,这里是xml 模块: xmlrpcl

  • SpringBoot2.0 整合 Dubbo框架实现RPC服务远程调用方法

    一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层或模块,蓝色的表示与业务有交互,绿色的表示只对 Dubbo 内部交互. 2)图中背景方块 Consumer, Provider, Registry, Monitor 代表部署逻辑拓扑节点. 3)图中蓝色虚线为初始化时调用,红色虚线为运行时异步调用,红色实线为运行时同步调用. 4)图中只包含 RPC

  • SpringBoot整合Dubbo框架,实现RPC服务远程调用

    一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层或模块,蓝色的表示与业务有交互,绿色的表示只对 Dubbo 内部交互. 2)图中背景方块 Consumer, Provider, Registry, Monitor 代表部署逻辑拓扑节点. 3)图中蓝色虚线为初始化时调用,红色虚线为运行时异步调用,红色实线为运行时同步调用. 4)图中只包含 RPC

随机推荐