每日一抄 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)

}
posted @   蹇爱黄  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
点击右上角即可分享
微信分享提示