如何对嵌套Python Protobuf进行编码



我被这个问题困扰了一段时间,把剩下的头发都拔了出来。

将非嵌套Protobuf从Python发送到Java,将Java发送到PythonWebSockets的问题。我的问题是通过WebSocket发送嵌套版本。我相信我的问题是Python编码端。

感谢您的指导。

.proto文件

message Response {
  // Reflect back to caller
  required string service_name = 1;
  // Reflect back to caller
  required string method_name = 2;
  // Who is responding
  required string client_id = 3;
  // Status Code
  required StatusCd status_cd = 4;
  // RPC response proto
  optional bytes response_proto = 5;
  // Was callback invoked
  optional bool callback = 6 [default = false];
  // Error, if any
  optional string error = 7;
  //optional string response_desc = 6;
}
message HeartbeatResult {
    required string service = 1;
    required string timestamp = 2;
    required float status_cd = 3;
    required string status_summary = 4;
}

心跳结果应该在reponse_toto字段中发送响应协议。我可以用Java到Java,但用Python到Java不起作用。

我已经包含了python代码的两个变体。两者都不起作用。

   def GetHeartbeat(self):
    print "GetHeartbeat called"
    import time
    ts = time.time()
    import datetime
    st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
    heartbeatResult = rpc_pb2.HeartbeatResult()
    heartbeatResult.service = "ALERT_SERVICE"
    heartbeatResult.timestamp = st
    heartbeatResult.status_cd = rpc_pb2.OK
    heartbeatResult.status_summary = "OK"
    response = rpc_pb2.Response()
    response.service_name = ""
    response.method_name = "SendHeartbeatResult"
    response.client_id = "ALERT_SERVICE"
    response.status_cd = rpc_pb2.OK 
    response.response_proto = str(heartbeatResult).encode('utf-8')
    self.sendMessage(response.SerializeToString())
    print "GetHeartbeat finished"
   def GetHeartbeat2(self):
    print "GetHeartbeat called"
    import time
    ts = time.time()
    import datetime
    st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
    heartbeatResult = rpc_pb2.HeartbeatResult()
    heartbeatResult.service = "ALERT_SERVICE"
    heartbeatResult.timestamp = st
    heartbeatResult.status_cd = rpc_pb2.OK
    heartbeatResult.status_summary = "OK"
    response = rpc_pb2.Response()
    response.service_name = ""
    response.method_name = "SendHeartbeatResult"
    response.client_id = "ALERT_SERVICE"
    response.status_cd = rpc_pb2.OK 
    response.response_proto = heartbeatResult.SerializeToString()
    self.sendMessage(response.SerializeToString())
    print "GetHeartbeat finished"

Java服务器端的错误有:

(GetHeartbeat) Protocol message end-group tag did not match expected tag
and
(GetHeartbeat2)
Message: [org.java_websocket.exceptions.InvalidDataException: java.nio.charset.MalformedInputException: Input length = 1
    at org.java_websocket.util.Charsetfunctions.stringUtf8(Charsetfunctions.java:80)
    at org.java_websocket.WebSocketImpl.deliverMessage(WebSocketImpl.java:561)
    at org.java_websocket.WebSocketImpl.decodeFrames(WebSocketImpl.java:328)
    at org.java_websocket.WebSocketImpl.decode(WebSocketImpl.java:149)
    at org.java_websocket.server.WebSocketServer$WebSocketWorker.run(WebSocketServer.java:593)
Caused by: java.nio.charset.MalformedInputException: Input length = 1
    at java.nio.charset.CoderResult.throwException(CoderResult.java:277)
    at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:798)
    at org.java_websocket.util.Charsetfunctions.stringUtf8(Charsetfunctions.java:77)

解决方案

也在protobuf集团上发布了这个问题

Christopher Head和Ilia Mirkin为谷歌集团提供了意见

https://groups.google.com/forum/#!主题/protobuf/Cp7zWiWok9I

response.response_proto = base64.b64encode(heartbeatResult.SerializeToString())
self.sendMessage(response.SerializeToString())

仅供参考,伊利亚还建议对整个消息进行base64编码,但目前看来这是可行的。

相关内容

  • 没有找到相关文章

最新更新