I use grpc server as micro server, httpbroker as broker, when I try publish a message, but some error occurs: {"id":"go.micro.client","code":500,"detail":"Unsupported Content-Type: application/grpc+proto","status":"Internal Server Error"}
mycode:
func main() {
reg := etcdv3.NewRegistry(func(op *registry.Options) {
op.Addrs = []string{
"http://127.0.0.1:2379",
}
})
service := micro.NewService(
micro.Server(grpc.NewServer()),
micro.Client(grpc.NewClient()),
micro.Name("HelloGreeter1"),
micro.Registry(reg),
)
service.Init()
ctx := context.Background()
cmsg := "message : Hello World"
err = service.Client().Publish(ctx, service.Client().NewMessage("testTopic", cmsg))
if err != nil {
fmt.Println(err.Error())
}
// blocking, cmsg can be sent, because Publish method is async
select {
}
}
debug find:
/client/grpc/grpc.go 489line
func (g *grpcClient) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error {
md, ok := metadata.FromContext(ctx)
if !ok {
md = make(map[string]string)
}
md["Content-Type"] = p.ContentType()
cf, err := g.newCodec(p.ContentType()) // here
}
/client/grpc/grpc.go 262line
func (g *grpcClient) newCodec(contentType string) (codec.NewCodec, error) {
if c, ok := g.opts.Codecs[contentType]; ok {
return c, nil
}
// here, I think should use defaultGRPCCodecs
if cf, ok := defaultRPCCodecs[contentType]; ok {
return cf, nil
}
return nil, fmt.Errorf("Unsupported Content-Type: %s", contentType)
}
I had the same problem, is this bug?
me too. that problem how to solve?
In version 1.8, the method NewMessage uses the variable "ContentType" to default to the client's "ContentType" support override but does not pass an overrideable parameter when calling NewMessage in the Publish method. "ContentType" can only use the client's "ContentType". The problem has occurred.
The method NewMessage in version 1.5 uses a fixed "ContentType" value of "application/octet-stream"
func (p *publisher) Publish(ctx context.Context, msg interface{}, opts ...client.PublishOption) error {
return p.c.Publish(ctx, p.c.NewMessage(p.topic, msg), opts...)
}
go-micro/client/grpc/grpc.go
func (g *grpcClient) NewMessage(topic string, msg interface{}, opts ...client.MessageOption) client.Message {
return newGRPCEvent(topic, msg, g.opts.ContentType, opts...)
}
The solution directly calls the Publish method in the client to solve this problem by specifying a specific "ContentType" with the third parameter.
go-micro/publisher.go
ev := &proto.Event{
Id: uuid.NewUUID().String(),
Timestamp: time.Now().Unix(),
Message: fmt.Sprintf("Messaging you all day on %s", "example.topic.pubsub.1"),
}
_ = service.Client().Publish(context.Background(), service.Client().NewMessage("example.topic.pubsub.1", ev, func(options *client.MessageOptions) {options.ContentType = "application/octet-stream"}))
me too.
This is the appropriate fix https://github.com/micro/go-micro/pull/679
Now merged.
Most helpful comment
In version 1.8, the method NewMessage uses the variable "ContentType" to default to the client's "ContentType" support override but does not pass an overrideable parameter when calling NewMessage in the Publish method. "ContentType" can only use the client's "ContentType". The problem has occurred.
The method NewMessage in version 1.5 uses a fixed "ContentType" value of "application/octet-stream"
go-micro/client/grpc/grpc.go
The solution directly calls the Publish method in the client to solve this problem by specifying a specific "ContentType" with the third parameter.
go-micro/publisher.go