首页 新闻 会员 周边 捐助

golang的无缓存channel通信

0
悬赏园豆:20 [已解决问题] 解决于 2023-10-06 16:06

看书时有这样两段代码,有点疑惑下面是代码
server.go

package ipc

import (
	"encoding/json"
	"fmt"
)

type Request struct {
	Method string
	Params string
}

type Response struct {
	Code string
	Body string
}

type Server interface {
	Name() string
	Handle(method, params string) *Response
}
type IpcServer struct {
	Server
}

func NewIpcServer(server Server) *IpcServer {
	return &IpcServer{Server: server}
}

func (server *IpcServer) Connect() chan string {
	session := make(chan string)
	go func(c chan string) {
		for {
			request := <-c
			if request == "CLOSE" { // 关闭该连接
				break
			}

			var req Request
			err := json.Unmarshal([]byte(request), &req)
			if err != nil {
				fmt.Println("Invalid request format:", request)
			}
			resp := server.Handle(req.Method, req.Params)
			b, _ := json.Marshal(resp)
			c <- string(b) // 返回结果
		}
		fmt.Println("Session closed.")
	}(session)
	fmt.Println("A new session has been created successfully.")
	return session
}

client.go

package ipc

import (
	"encoding/json"
)

type IpcClient struct {
	conn chan string
}

func NewIpcClient(server *IpcServer) *IpcClient {
	c := server.Connect()
	return &IpcClient{c}
}
func (client *IpcClient) Call(method, params string) (resp *Response, err error) {
	req := &Request{method, params}
	var b []byte
	b, err = json.Marshal(req)

	if err != nil {
		return
	}
	client.conn <- string(b)
	str := <-client.conn // 等待返回值
	var resp1 Response
	err = json.Unmarshal([]byte(str), &resp1)
	resp = &resp1
	return
}
func (client *IpcClient) Close() {
	client.conn <- "CLOSE"
}

我的疑问是在 NewIpcClient()的时候创建了一个channel并开启了一个协程,call执行到client.conn <- string(b)的时候 开启的协程一定开始执行了吗,channel处于等待状态?
c <- string(b) // 返回结果执行完成的时候,call方法会不会刚好只执行到client.conn <- string(b)就让出执行时间了,没有执行到str := <-client.conn // 等待返回值。然后for继续在执行,然后就改返回的response读取到了,继续for循环执行。
或者换种说法,上面代码的写法一定会保证按照server端等待客户端输入,然后返回给客户端,然后server端继续等待客户端。无论代码执行到什么位置,让出执行时间。一定会的话,怎么做到的?

15年的夏天的主页 15年的夏天 | 初学一级 | 园豆:47
提问于:2023-09-08 17:33
< >
分享
最佳答案
0

client.conn <- string(b)的时候 开启的协程一定开始执行了吗,channel处于等待状态?
协程开没开始都没关系,但是channel已经建立起来了。
session := make(chan string) 是创建channel的,创建之后,处理这个channel的协程没有开始的话,channel就在阻塞中。

str := <-client.conn // 等待返回值
这一步会一直阻塞,直到client.conn这个channel有值了,也就是sever的代码中的c <- string(b) // 返回结果 执行之后才会接着执行。

其实整体来看,上面代码中的channel的缓冲只有一个元素,完全可以当成同步的代码来看。
server接收了一个请求后,直至处理完,不能再接收其他请求了。

收获园豆:20
wang_yb | 老鸟四级 |园豆:4893 | 2023-09-09 22:13
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册