protoactor-go
protoactor-go copied to clipboard
Error while trying to read a message in Go client sent by C# server
Hello, I'm trying to make a remote chat between an C# Server and Go Client, but I'm getting this error:
INFO [REMOTE] EndpointReader failed to read error="rpc error: code = Internal desc = grpc: failed to unmarshal the received message proto: cannot parse invalid wire-format data"
It happens when I send a message to my Go client, even using Proto.actor built-in messages I still got this exception, what could be wrong ? I'm pretty sure that there's nothing wrong with the proto message, since I've serialized it to an .bat (in the C# server) then opened and unmarshaled it on my Go client with sucess.
Is there something that I've to add in my Go Client to unmarshal protobuffer messages from C# ? I'm new to Proto.Actor so I wonder if I'm missing something to communicate actors from different languages.
Hi,
The error originates in grpc\stream.go\RecvMsg.
I am not sure why it happens, but I noticed another minor issue with the version of grpc we use (1.46.2):
The named return value "err" is shadowed by err := recv
which implies the defer func does not detect/handle the error.
It is probably not related but I thought it is worth noting.
func (ss *serverStream) RecvMsg(m interface{}) (err error) {
defer func() {
if ss.trInfo != nil {
ss.mu.Lock()
if ss.trInfo.tr != nil {
if err == nil {
ss.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true)
} else if err != io.EOF {
ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
ss.trInfo.tr.SetError()
}
}
ss.mu.Unlock()
}
if err != nil && err != io.EOF {
st, _ := status.FromError(toRPCErr(err))
ss.t.WriteStatus(ss.s, st)
// Non-user specified status was sent out. This should be an error
// case (as a server side Cancel maybe).
//
// This is not handled specifically now. User will return a final
// status from the service handler, we will log that error instead.
// This behavior is similar to an interceptor.
}
if channelz.IsOn() && err == nil {
ss.t.IncrMsgRecv()
}
}()
var payInfo *payloadInfo
if ss.statsHandler != nil || ss.binlog != nil {
payInfo = &payloadInfo{}
}
if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, payInfo, ss.decomp); err != nil {
if err == io.EOF {
if ss.binlog != nil {
ss.binlog.Log(&binarylog.ClientHalfClose{})
}
return err
}
if err == io.ErrUnexpectedEOF {
err = status.Errorf(codes.Internal, io.ErrUnexpectedEOF.Error())
}
return toRPCErr(err)
}
if ss.statsHandler != nil {
ss.statsHandler.HandleRPC(ss.s.Context(), &stats.InPayload{
RecvTime: time.Now(),
Payload: m,
// TODO truncate large payload.
Data: payInfo.uncompressedBytes,
WireLength: payInfo.wireLength + headerLen,
Length: len(payInfo.uncompressedBytes),
})
}
if ss.binlog != nil {
ss.binlog.Log(&binarylog.ClientMessage{
Message: payInfo.uncompressedBytes,
})
}
return nil
}
Hi, this is not currently supported. The Go version has not been ported to the latest network protocol as used by the C# version.
Hi, this is not currently supported. The Go version has not been ported to the latest network protocol as used by the C# version.
Can we expect an updated Go version? If yes, Can you tell us when can we expect it. If no, Can you suggest any work around( an alternate)
I think it would be ethical and responsable to the project to not mention that its cross platform. I spent months thinking that its cross platform only to run into this and find that it is not true. I listened to Roger on podcast talking about it being cross platform. It is not true that it is cross platform, at least not yet.