python-快速流式传输数据到客户端
python-snappy streaming data in a loop to a client
我想使用 python snappy 将多个压缩数组从服务器发送到客户端,但在第一个数组之后我无法让它工作。这是正在发生的事情的片段:
(sock
只是它们通过的网络套接字)
服务器:
for i in range(n): #number of arrays to send
val = items[i][1] #this is the array
y = (json.dumps(val)).encode('utf-8')
b = io.BytesIO(y)
#snappy.stream_compress requires a file-like object as input, as far as I know.
with b as in_file:
with sock as out_file:
snappy.stream_compress(in_file, out_file)
客户:
for i in range(n): #same n as before
data = ''
b = io.BytesIO()
#snappy.stream_decompress requires a file-like object to write o, as far as I know
snappy.stream_decompress(sock, b)
data = b.getvalue().decode('utf-8')
val = json.loads(data)
val = json.loads(data)
仅适用于第一次迭代,但之后它停止工作。当我执行 print(data)
时,只有第一次迭代会打印任何内容。我已经验证服务器确实刷新并发送了所有数据,所以我认为我决定接收数据的方式有问题。
我找不到其他方法来做到这一点。我进行了搜索,唯一能找到的是 ,这让我找到了我目前拥有的东西。
有什么建议或意见吗?
with
没有按照你的想法去做,参考一下是documentation。它在块执行后调用 sock.__exit__()
,这不是您想要的。
# what you wrote
with b as in_file:
with sock as out_file:
snappy.stream_compress(in_file, out_file)
# what you meant
snappy.stream_compress(b, sock)
顺便说一句:
行 data = ''
已过时,因为它已被重新分配。
添加到@paul-scharnofske 的回答:
同样,在接收方:stream_decompress
直到文件末尾才退出,这意味着它将读取直到套接字关闭。因此,如果您发送单独的多个压缩块,它会在完成之前读取所有这些块,这似乎不是您想要的。最重要的是,您需要在每个块周围添加 "framing" 以便您在接收端知道一个结束和下一个开始的时间。一种方法...对于要发送的每个数组:
- 像现在一样使用 json 编码的输入创建一个
io.BytesIO
对象
- 为压缩输出创建一个second
io.BytesIO
对象
- 用两个
BytesIO
对象调用 stream_compress
(你可以 write
进入 BytesIO
除了从中读取)
- 获取输出对象的
len
- 发送编码为 32 位整数的长度,例如
struct.pack("!I", length)
- 发送输出对象
在接收方,反向处理。对于每个数组:
- 读取4个字节(长度)
- 创建一个
BytesIO
对象。准确接收 length
字节,将这些字节写入对象
- 创建第二个
BytesIO
对象
- 将接收到的对象作为输入传递,将第二个对象作为输出传递给
stream_decompress
- json-解码生成的输出对象
我想使用 python snappy 将多个压缩数组从服务器发送到客户端,但在第一个数组之后我无法让它工作。这是正在发生的事情的片段:
(sock
只是它们通过的网络套接字)
服务器:
for i in range(n): #number of arrays to send
val = items[i][1] #this is the array
y = (json.dumps(val)).encode('utf-8')
b = io.BytesIO(y)
#snappy.stream_compress requires a file-like object as input, as far as I know.
with b as in_file:
with sock as out_file:
snappy.stream_compress(in_file, out_file)
客户:
for i in range(n): #same n as before
data = ''
b = io.BytesIO()
#snappy.stream_decompress requires a file-like object to write o, as far as I know
snappy.stream_decompress(sock, b)
data = b.getvalue().decode('utf-8')
val = json.loads(data)
val = json.loads(data)
仅适用于第一次迭代,但之后它停止工作。当我执行 print(data)
时,只有第一次迭代会打印任何内容。我已经验证服务器确实刷新并发送了所有数据,所以我认为我决定接收数据的方式有问题。
我找不到其他方法来做到这一点。我进行了搜索,唯一能找到的是
有什么建议或意见吗?
with
没有按照你的想法去做,参考一下是documentation。它在块执行后调用 sock.__exit__()
,这不是您想要的。
# what you wrote
with b as in_file:
with sock as out_file:
snappy.stream_compress(in_file, out_file)
# what you meant
snappy.stream_compress(b, sock)
顺便说一句:
行 data = ''
已过时,因为它已被重新分配。
添加到@paul-scharnofske 的回答:
同样,在接收方:stream_decompress
直到文件末尾才退出,这意味着它将读取直到套接字关闭。因此,如果您发送单独的多个压缩块,它会在完成之前读取所有这些块,这似乎不是您想要的。最重要的是,您需要在每个块周围添加 "framing" 以便您在接收端知道一个结束和下一个开始的时间。一种方法...对于要发送的每个数组:
- 像现在一样使用 json 编码的输入创建一个
io.BytesIO
对象 - 为压缩输出创建一个second
io.BytesIO
对象 - 用两个
BytesIO
对象调用stream_compress
(你可以write
进入BytesIO
除了从中读取) - 获取输出对象的
len
- 发送编码为 32 位整数的长度,例如
struct.pack("!I", length)
- 发送输出对象
在接收方,反向处理。对于每个数组:
- 读取4个字节(长度)
- 创建一个
BytesIO
对象。准确接收length
字节,将这些字节写入对象 - 创建第二个
BytesIO
对象 - 将接收到的对象作为输入传递,将第二个对象作为输出传递给
stream_decompress
- json-解码生成的输出对象