首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在服务器->客户端方向没有发生泄气

在服务器->客户端方向没有发生泄气
EN

Stack Overflow用户
提问于 2021-04-06 16:09:02
回答 1查看 914关注 0票数 0

我已经在python中编写了我自己的websocket实现,以教会自己它们的内部工作。我打算在websocket上发送大量重复的JSON对象,所以我尝试实现permessage-deflate。压缩工作在client->server方向,但不工作在server -> client方向。

这是头交换:

请求

代码语言:javascript
复制
Host: awebsite.com:port
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
Upgrade: websocket
Origin: http://awebsite.com
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Sec-WebSocket-Key: JItmF32mfGXXKYyhcEoW/A==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

响应

代码语言:javascript
复制
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Accept: zYQKJ6gvwlTU/j2xw1Kf0BErg9c=

当我这样做时,我从客户端得到预期的压缩数据,它会按预期膨胀。

当我发送一条未压缩的消息时,我在客户端得到一个正常的响应(我发送"hello“和"hello”)。

当我试图使用这个简单的python函数来缩小消息时:

代码语言:javascript
复制
def deflate(self,data,B64_encode=False):
   data=zlib.compress(data)
   if B64_encode:
       return base64.b64encode(data[2:-4])
   else:
       return data[2:-4]

我收到一条关于字符不是utf-8的错误消息,当我对压缩消息进行base64编码时,我只得到base64编码的字符串。我还尝试通过websocket以二进制方式发送数据,并在另一端获取blob。我已经在网上搜索了一段时间了,还没听说过会发生这种事。我的猜测是我在错误的一步压缩数据。下面是我用来发送数据的函数。到目前为止,我一直在将压缩的消息输入到send()函数中,因为根据我所读到的,每条消息的压缩都发生在消息级别上,而所有其他数据都是未压缩的。

代码语言:javascript
复制
def send(self, string, TYPE="TEXT"):
                import struct
                conn = self.conn
                datatypes = {
                        "TEXT": 0x01,
                        "BINARY": 0x02,
                        "CLOSE": 0X08,
                        "PING": 0x09,
                        "PONG": 0x0A}
                b1 = 0x80
                b2 = 0
                message = ""
                if TYPE == "TEXT":
                        if type(string) == unicode:
                                b1 |= datatypes["TEXT"]
                                payload = string.encode("UTF8")
                        elif type(string) == str:
                                b1 |= datatypes["TEXT"]
                                payload = string
                                message += chr(b1)
                else:
                        b1 |= datatypes[TYPE]
                        payload = string
                        message += chr(b1)
                length = len(payload)
                if length < 126:
                        b2 |= length
                        message += chr(b2)
                elif length < (2 ** 16) - 1:
                        b2 |= 126
                        message += chr(b2)
                        l = struct.pack(">H", length)
                        message += l
                else:
                        l = struct.pack(">Q", length)
                        b2 |= 127
                        message += chr(b2)
                        message += l
                message += payload
                try:
                        conn.send(str(message))
                except socket.error:
                        traceback.print_exc()
                        conn.close()
                if TYPE == "CLOSE":
                        self.Die = True
                        conn.shutdown(2)
                        conn.close()
                        print self.myid,"Closed"
EN

回答 1

Stack Overflow用户

发布于 2021-04-08 04:15:22

经过多次调查,我发现我的问题是"RTFM“。在(a?) 马努阿人l on perMessage压缩的第三段中,它说

WebSocket客户端可能在WebSocket期间提供多个PMCEs。 开始握手。接收到这些报价的对等WebSocket服务器可以选择和接受首选的服务,也可以拒绝所有这些服务。PMCEs使用 RSV1帧头的WebSocket位,以指示 消息是否被压缩,因此端点可以选择不对 用不可压缩的内容压缩消息。

当我第一次设置它时,我不知道rsv位做了什么,默认情况下将它们设置为0。我的代码现在允许在我的程序中的send()函数中设置压缩。它很好地将我的消息从30200字节缩减到149个字节。

我修改的代码现在如下所示:

代码语言:javascript
复制
        def deflate2(self,data):
            data=zlib.compress(data)
            data=data[2:-4]
            return data

        def send(self, string, TYPE="TEXT",deflate=False):
                import struct
                if (deflate):
                    string=self.deflate(string)
                conn = self.conn
                datatypes = {
                        "TEXT": 0x01,
                        "BINARY": 0x02,
                        "CLOSE": 0X08,
                        "PING": 0x09,
                        "PONG": 0x0A}
                b1 = 0x80              #0b100000000
                if(deflate): b1=0xC0   #0b110000000 sets RSV1 to 1 for compression
                b2 = 0
                message = ""
                if TYPE == "TEXT":
                        if type(string) == unicode:
                                b1 |= datatypes["TEXT"]
                                payload = string.encode("UTF8")
                        elif type(string) == str:
                                b1 |= datatypes["TEXT"]
                                payload = string
                                message += chr(b1)
                else:
                        b1 |= datatypes[TYPE]
                        payload = string
                        message += chr(b1)
                length = len(payload)
                if length < 126:
                        b2 |= length
                        message += chr(b2)
                elif length < (2 ** 16) - 1:
                        b2 |= 126
                        message += chr(b2)
                        l = struct.pack(">H", length)
                        message += l
                else:
                        l = struct.pack(">Q", length)
                        b2 |= 127
                        message += chr(b2)
                        message += l
                message += payload
                try:
                        if self.debug:
                            for x in message: print("S>: ",x,hex(ord(x)),ord(x))
                        conn.send(str(message))
                except socket.error:
                        traceback.print_exc()
                        conn.close()
                if TYPE == "CLOSE":
                        self.Die = True
                        conn.shutdown(2)
                        conn.close()
                        print self.myid,"Closed"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66972354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档