我试图在共享的go模块中创建共享的原型定义,但我运气不佳。具体来说:
-我想要一个包含共享定义的模块原型中的原型文件。
-模块原型中的其他原型文件将引用共享定义。
-模块原型-使用将引用模块原型(通过go.mod)
-模块原型-使用go代码将导入和使用模块原型中的定义
-两个模块都存储在github.com
我无法使各种包名称对齐。不管我用什么,总会有失败的。目前,模块protos没有任何错误,但模块protos使用失败。
模块原型在https://github.com/rob-woerner/protos
模块原型-使用在https://github.com/rob-woerner/protos-use
我还没有找到一个解决这种情况的例子。如果我只是到处复制共享的proto定义,我就可以让它工作。最近的错误是:
go mod tidy$go:finding module for package github。com/rob-woerner/protos/messages
go:查找包github的模块。com/rob-woerner/protos/common
github。com/rob-woerner/protos-use/code-imports-github。com/rob-woerner/protos/common:模块github。通信/rob woerner/protos@latest找到(XXX),但不包含包github。com/rob-woerner/protos/common
github。com/rob-woerner/protos-use/code-imports-github。com/rob-woerner/protos/messages:模块github。通信/rob woerner/protos@latest找到(XXX),但不包含包github。com/rob-woerner/protos/messages
但是我强调,我得到了很多不同的错误,这取决于我在十几个需要包名称的地方使用了什么包名称。
如果有人知道一个工作示例,或者如果不支持,我将不胜感激。
为了简洁起见,代码段被省略了
模块协议:
去mod
生成文件
协议:
模块原型使用:
go.mod
代码:
模块原型:开始。mod:module protos(模块协议)go 1.16需要google。戈朗。组织/协议v1.27.1
协议/通用。协议:
包通用
option go\u package=“github.com/rob-woerner/protos”
枚举MyState{LOGGED\u OUT=0;}
messages.proto:
导入"common.proto";
包消息;
选项go_package="github.com/rob-woerner/protos";
消息MyRequest{通用。我的状态=1;}
生成文件:
协议:
模块原型-使用:
go.mod:
模块github.com/rob-woerner/protos-use
go 1.16
需要(
代码/项目。转到:
程序包代码
导入(
这对于protobufs来说很有挑战性,而且文档记录也很差。
我感觉到复杂性的一部分是protobuf维护人员正试图解决可能使用的无数运行时和包。
如果我正确理解了你的问题,根据你所拥有的,原型使用
正在挣扎,因为code/product.go
应该:
import (
"github.com/rob-woerner/protos/pb/common" // /pb/
...
)
我有一个工作机制,我会尝试应用到你的机制。我认为,对通用软件包的引用不是您的问题,而是总体结构和模块与软件包的对比:
在foo/protos中,我有。根目录中的proto文件(但这只是一种约定,不需要):
syntax = "proto3";
package baz;
option go_package = "github.com/foo/protos;baz";
service Some {...}
注意<代码>;baz描述生成代码的最终Go包名称(baz)。它不需要与repo名称(
protos)匹配,我不希望这样,因为(见下文),我将生成的代码放在非根目录中(
/some/baz)
然后:
MODULE="github.com/foo/protos"
protoc \
--include_imports \
--include_source_info \
--proto_path=. \
--descriptor_set_out=foo.pb \
--go_out=./some/baz \
--go_opt=module=${MODULE} \
--go-grpc_out=./some/baz \
--go-grpc_opt=module=${MODULE} \
./*.proto
注意,这将为我们提供一个包名为github。com/foo/protos/some/baz
这将产生:
.
├── example.proto
├── some
│ └── baz
│ ├── example_grpc.pb.go
│ └── example.pb.go
├── go.mod
├── go.sum
└── protoc-3.17.3-linux-x86_64
然后,从条形图/应用程序,我有:
<代码>开始。mod(模式):
module github.com/bar/app
go 1.16
require (
github.com/foo/protos v0.0.1
...
)
在该模块中,我将导入别名为:
package main
import (
...
pb "github.com/foo/protos/some/baz"
)
func main() {
...
pb.RegisterSomeServer(grpcServer, ...)
注释响应注释线程
常见信息和消息要么在一个包中,要么在两个包中。
让我们做两件事:
<代码>通用。协议:
syntax = "proto3";
package common;
option go_package = "github.com/rob-woerner/protos/common;common";
enum MyState { LOGGED_OUT = 0; }
<代码>消息。协议:
syntax = "proto3";
package messages;
import "common.proto";
option go_package = "github.com/rob-woerner/protos/messages;messages";
message MyRequest { common.MyState state = 1; }
注意因为我们想要2个包,所以我们需要给原型(!)唯一的
包
,go_package
名称。/原型/公共;公共
。虽然我们可以有。/原型/公共;房地美
,但问题是路径必须是唯一的才能给出唯一的包。
然后:
MODULE="github.com/rob-woerner/protos"
protoc \
--proto_path=. \
--go_out=./some \
--go_opt=module=${MODULE} \
--go-grpc_out=./some \
--go-grpc_opt=module=${MODULE}
请注意,此处使用some仅仅是为了确保生成的代码最终由repo(=模块)根下的某个包(
some)聚合。如果希望将包直接放在模块根目录下,可以删除一些。
产量:
some
├── common
│ └── common.pb.go
└── messages
└── messages.pb.go
注意
一些
成为根包github.com/rob-woerner/protos/some
和common.pb.go
在子包github.com/rob-woerner/protos/some/common
所以,我们现在可以:
<代码>主。转到
:
package main
import (
"github.com/rob-woerner/protos/some/common"
"github.com/rob-woerner/protos/some/messages"
)
func main() {
rqst := messages.MyRequest{
state: common.MyState_LOGGED_OUT,
}
// do something with `rqst`
}
如果您希望
通用
和消息
在同一个包中,那么您可以:
package protos;
option go_package = "github.com/rob-woerner/protos;protos`;
以及:
message MyRequest { MyState state = 1; } // Now in same package
然后:
MODULE="github.com/rob-woerner/protos"
protoc \
--proto_path=. \
--go_out=./protos \
--go_opt=module=${MODULE} \
--go-grpc_out=./protos \
--go-grpc_opt=module=${MODULE}
注意,在这种情况下,我们需要输出=/protos
以便将生成的文件放入正确的包中(protos
<代码>主。转到:
package main
import (
pb "github.com/rob-woerner/protos"
)
func main() {
rqst := pb.MyRequest{
state: pb.MyState_LOGGED_OUT,
}
// do something with `rqst`
}
唷!我说这很有挑战性;-)
我指定了许多独立的gRPC服务,这些服务将全部托管在同一个服务器进程之外。每个服务都在其自己的protobuf文件中定义。然后通过gRPC工具运行这些工具,为我提供目标语言(在我的情况下是c语言),然后我可以在其中实现我的服务器和客户端。 这些单独的API中的每一个都使用了许多公共元素,如错误响应枚举、空消息类型(这似乎在gRPC WellKnownTypes中可用;但我也看不到如何包含这些元素,
VS Code 把 NodeJS 和 Mono 的调试功能抽象出来了,大家就可以通过自定义 Debugger Adapter 和 VSCode Debug Protocol 从而实现自己的调试器。现在 VS Code 插件中心 里,Go、PHP、Python、Ruby 的 Debugger 做的都比较成熟了 参见 https://code.visualstudio.com/Docs/extensi
在底层,Chrome 开发者工具是用 HTML,JavaScript 和 CSS 写的 Web 应用程序。在 Javascript 运行时,它提供一个特殊的绑定,这允许它与 chrome 网页进行交互并且容许装载它们。交互协议包括被发送到页面的命令,和该页面生成的事件。尽管 Chrome 开发者工具是该协议的主要客户,其中包括远程调试(remote debugging),但有很多办法可以让第三方能
如何定制协议 实际上制定自己的协议是比较简单的事情。简单的协议一般包含两部分: 区分数据边界的标识 数据格式定义 一个例子 协议定义 这里假设区分数据边界的标识为换行符”\n”(注意请求数据本身内部不能包含换行符),数据格式为Json,例如下面是一个符合这个规则的请求包。 {"type":"message","content":"hello"} 注意上面的请求数据末尾有一个换行字符(在PHP中