gpt4 book ai didi

go - 如何在使用 GRPC 时提供文件服务

转载 作者:行者123 更新时间:2023-12-02 20:10:30 25 4
gpt4 key购买 nike

有没有什么方法可以在 Go 中使用 GRPC 提供文件服务,例如 gin-gonic's variant :

router.Static("/static", "/var/www")

最佳答案

你不能完全那样做。
但是您可以使用原始 bytes 类型并将文件字节放入该字段中。

此外(正如评论中所指出的)对于大文件,您应该使用流式传输而不是一元调用。 (大多数 GRPC 实现的每条消息的限制为 4MB)。

原型(prototype)示例:

syntax = "proto3";

message Response {
bytes fileChunk = 1;
}
message Request {
string fileName = 1;
}

service TestService {
rpc Download(Request) returns (stream Response);
}

服务器实现示例:

func (srv *Server) Download(req *pbgo.Request, responseStream pbgo.TestService_DownloadServer) error {
bufferSize := 64 *1024 //64KiB, tweak this as desired
file, err := os.Open(req.GetFileName())
if err != nil {
fmt.Println(err)
return err
}
defer file.Close()
buff := make([]byte, bufferSize)
for {
bytesRead, err := file.Read(buff)
if err != nil {
if err != io.EOF {
fmt.Println(err)
}
break
}
resp := &pbgo.Response{
FileChunk: buff[:bytesRead],
}
err = responseStream.Send(resp)
if err != nil {
log.Println("error while sending chunk:", err)
return err
}
}
return nil
}

客户会这样调用它:

conn, err := grpc.Dial("localhost:9090", grpc.WithInsecure())
if err != nil {
log.Fatal("client could connect to grpc service:", err)
}
c := pbgo.NewTestServiceClient(conn)
fileStreamResponse, err := c.Download(context.TODO(), &pbgo.Request{
FileName: "test.txt",
})
if err != nil {
log.Println("error downloading:", err)
return
}
for {
chunkResponse, err := fileStreamResponse.Recv()
if err == io.EOF {
log.Println("received all chunks")
break
}
if err != nil {
log.Println("err receiving chunk:", err)
break
}
log.Printf("got new chunk with data: %s \n", chunkResponse.FileChunk)
}

如果您需要能够提供任意文件,则需要处理允许提供哪些文件(假设有人请求文件 /etc/passwd 或其他文件)。
不确定这里的用例到底是什么。

关于go - 如何在使用 GRPC 时提供文件服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58566016/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com