Python gevent websocket 客户端收到回显协议缓冲区消息的错误"DecodeError: Truncated message"



我有一个简单的websocket服务器,它将所有消息回显到客户端。

import gevent
from geventwebsocket.resource import WebSocketApplication
from geventwebsocket.server import WebSocketServer
from geventwebsocket.resource import Resource
import ams_pb2
class AMSWebSocketServer(WebSocketApplication):
    def __init__(self, ws):
        super(AMSWebSocketServer, self).__init__(ws)
        pass
    def on_open(self):
        pass
    def on_message(self, message):
        print 'received message'
        print message
        if message is None:
            print 'message none'
            return
        print 'echo message back'
        self.ws.send(message)
    def on_close(self, reason):
        print "connection closed"
        gevent.sleep(0)

resource = Resource({'/': AMSWebSocketServer})

服务器是使用 gunicorn 命令生成的

gunicorn -k "geventwebsocket.gunicorn.workers.GeventWebSocketWorker" -b 127.0.0.1:9000 gunicorn_test:resource

我有一个测试客户端,它发送要回显的 websocket 消息

from ws4py.client.threadedclient import WebSocketClient
import ams_pb2

class DummySwitch(WebSocketClient):
    def closed(self, code, reason=None):
        pass
    def received_message(self, msg):
        if msg is None:
            print 'none'
            return
        print 'received message'
        ams_message = ams_pb2.AMSConfig()
        ams_message.ParseFromString(msg)
        print ams_message
        print msg

if __name__ == '__main__':
    end_point = 'ws://127.0.0.1:9000'
    client = DummySwitch(
        end_point,
        headers=[
        ]
    )
    client.connect()
    print 'sending message'
    AMSConfig = ams_pb2.AMSConfig()
    AMSConfig.CliConfig = True
    print AMSConfig
    msg = AMSConfig.SerializeToString()
    #msg = 'Hello'
    print msg
    client.send(msg)
    client.run_forever()

我的原型文件是: 包装 AMS;

message AMSConfig {
  optional bool CliConfig = 1;
}

每当我的客户端向服务器发送 protobuff 消息时,我都能看到它在服务器中被解析,但是当服务器将相同的消息回显到客户端时,客户端会因以下原因而失败:

文件"client_test.py",第 15 行,received_message ams_message。ParseFromString(msg( 文件 "/usr/lib/python2.6/site-packages/google/protobuf/message.py",第 186 行,在 ParseFromString 中 自我。MergeFromString(序列化( 文件 "/usr/lib/python2.6/site-packages/google/protobuf/internal/python_message.py",第 847 行,在 MergeFromString 中 提高message_mod。解码错误("截断的消息。解码错误:截断的消息。

因此,我

修改了代码以发送一个简单的字符串,我看到发送到服务器的"Hello"字符串正在回显,并且客户端能够打印消息。但是,客户端无法解析回显的 protobuff 消息。

我无法理解为什么字符串的回显有效,但对于协议缓冲区,它在我的示例中不起作用。

感谢您的帮助。

我在客户端遇到了同样的问题,但这可以通过在客户端代码中扩大接收缓冲区大小来解决。例如:

maxpkglen = 1024 * 1024 // original maxpkglen = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(req, (server, port))
rsp, server = s.recvfrom(maxpkglen)
s.close()

我在客户端程序中也遇到了这样的问题,因为我将接收缓冲区设置为硬数字 1024。 当我将接收缓冲区大小扩大到 10*1024 时,它就解决了。 也感谢@lulyon的提示。

您可能需要一个循环来读取对等代码中的所有数据!

我遇到了这个问题,但对我来说,答案是不要直接从received_message(self, msg)中使用msg变量,而是使用msg.data来实际获取与消息关联的数据并从中解析。

相关内容

  • 没有找到相关文章

最新更新