首页 > 其他分享 >每日一抄 Go语言模拟远程调用

每日一抄 Go语言模拟远程调用

时间:2022-12-01 09:46:44浏览次数:34  
标签:调用 string 一抄 请求 ch Go 服务器 超时 客户端

package main

import (
	"errors"
	"fmt"
	"time"
)

//客户端请求和接收封装
/*
下面代码封装了向服务器请求数据,等待服务器返回数据,如果请求超时该函数还会处理超时逻辑
*/
//模拟RPC客户端的请求和接收消息封装
func RPCClient(ch chan string, req string) (string, error) {
	//向服务器发请求

	//模拟socket向服务器发送一个字符串信息,服务器接收后,结束阻塞进入下一行。
	ch <- req
	//等待服务器返回
	/*
		使用select开始做多路复用。注意select虽然在写法上和Switch一样,都可以拥有case和default。
		但是select关键字后不接任何语句,而是将要多路复用的多个通道语句写在case上如:case ack := <- ch:和case <-time.After(time.Second):
	*/
	select {
	//接收到服务器返回数据
	case ack := <-ch:
		return ack, nil

	/*
		使用了 time 包提供的函数 After(),从字面意思看就是多少时间之后,
		其参数是 time 包的一个常量,time.Second 表示 1 秒。
		time.After 返回一个通道,这个通道在指定时间后,通过通道返回当前时间。
	*/
	case <-time.After(time.Second): //超时
		//在超时时,返回超时错误。
		return "", errors.New("time out")
	}

}

//模拟rpc服务器端接收客户端请求和回应
func RPCSever(ch chan string) {
	//构造出一个无限循环,客户端处理完客户端的请求后,通过无限循环继续处理下一个客户端的请求
	for {
		//接收客户端请求,通过字符串通道接收一个客户端的请求
		data := <-ch
		//打印接收到的数据
		fmt.Println("server received:", data)
		//向客户端反馈已经收到
		ch <- "i heared you"
	}
}

func main() {
	ch := make(chan string)
	go RPCSever(ch)
	receive, err := RPCClient(ch, "i am client")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("client received:", receive)
}
package main

import (
	"errors"
	"fmt"
	"time"
)

/*
虽然客户端有超时处理机制,但是永远不会触发,因为服务器处理的速度非常快,也没有真正的延时或者是电脑宕机的情况
为了展示select中超时的处理,在服务器的逻辑中增加一条语句,故意让服务器延时处理一段时间造成客户端请求超时
*/
func RPCClient(ch chan string, req string) (string, error) {
	//发送消息
	ch <- req
	//等待响应
	select {
	case data := <-ch:
		return data, nil
	case <-time.After(time.Second):
		return "", errors.New("time out")
	}
}

func RPCServer(ch chan string) {
	//开一个循环来接收
	for {
		//接收数据
		data := <-ch
		fmt.Println("server received:", data)
		time.Sleep(time.Second * 2)
		//反馈给用户
		ch <- "i got u"
	}
}

func main() {
	ch := make(chan string)
	//开启服务端
	go RPCServer(ch)
	//客户端发信息
	receive, err := RPCClient(ch, "i am client")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("client received:", receive)

}

标签:调用,string,一抄,请求,ch,Go,服务器,超时,客户端
From: https://www.cnblogs.com/jianjiana/p/16939469.html

相关文章

  • golang流式编程
    https://blog.csdn.net/u012986012/article/details/126833564  借助一些设计模式、流式编程、函数编程的方法可以让我们的Golang代码更清晰优雅,本文中描述了在错误处......
  • Go-05 Golang中的运算符
    packagemainimport"fmt"/* Golang中的运算符 Golang内置的运算符: 1.算术运算符:+-*/% 2.关系运算符:!===>>=<<= 返回值是True或者False 3.逻辑运......
  • [15-445]Join Algorithms memo (Join 为什么要用小表做驱动表)
    NestedLoopJoin这一章节主要讲解join的算法,我想记录一些重点的地方。有趣的是关于NestedLoopjoin对驱动表为什么小表会更好这个问题,搜遍简中的blog都是一些错......
  • Installing golang-1.18 on openEuler
    一、Installinggolang-1.18onopenEulerhttps://golang.google.cn1下载mkdir/opt/software&&cd/opt/softwarewgethttps://golang.google.cn/dl/go1.18.linux......
  • Golang实现小型CMS内容管理功能(二):前端接入百度ueditor富文本编辑器
    当我们把接口都做好以后,我们需要去开发前端界面。添加文章功能里面,最重要的就是文章内容部分,需要配置上富文本编辑器,这样才能给我们的内容增加样式。 下载ueditor代码......
  • django-rest-framework(更新中)
    @目录(三十六)Web应用模式(三十七)API接口(三十八)Restful规范(三十九)drf安装和简单使用1、安装2、使用3、postman测试(四十)源码分析cbvAPIView源码分析补充:drf的Request类(三十六......
  • Google Chrome(谷歌浏览器)安装使用
    谷歌浏览器官网https://www.google.cn/chrome/ Chrome是由Google开发的一款简单便捷的网页浏览工具。谷歌浏览器(GoogleChrome)可以提帮助你快速、安全的搜索到自己需......
  • go redis v8 gin session
    今天使用到gin的模版功能,于是学习了一下登录session因为gin有自家开发好的sessionredis。所以在redis支持方面。已经有支持好的了但是看了一下golangredis方面,发现有......
  • SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) 被调用2次
    问题GAS技能输入绑定失效。直接原因在ListenServer的一端,ACharacter::SetupPlayerInputComponent在游戏开始后,被调用了2次,说明第1次输入绑定的InputComponent被移除(......
  • 重构后台的django项目目录、配置开发环境、添加环境变量
    重构项目目录celery_task:logs:项目运行时/开发时日志目录包luffapi:项目同名文件夹apps:项目所有应用的集合文件夹libs:第三方类库的保存目录[第三方组件、模块]-包......