我有一个处理 get 请求的烧瓶端点,我有兴趣在响应中返回一个对象列表(序列化),但以“分块”的方式。我的意思是,当我向该端点发出 get 请求时,我希望能够迭代响应(就好像我正在获取二进制数据列表)并将每个“块”反序列化为一个对象。
我能够实现与我的需求类似的结果,但是使用字符串。例如:
服务器端:
from flask import stream_with_context, request, Response
from flask import Flask
app = Flask(__name__)
@app.route('/stream')
def streamed_get():
@stream_with_context
def generate():
yield 'Hello \n'
yield "there\n"
yield '!\n'
return Response(generate())
Run Code Online (Sandbox Code Playgroud)
客户端:
import requests
response = requests.get("http://127.0.0.1:5000/stream", stream=True)
for i in response.iter_lines():
print(i)
Run Code Online (Sandbox Code Playgroud)
这将打印:
Hello
there
!
Run Code Online (Sandbox Code Playgroud)
但这似乎很明显,因为我正在使用response.iter_lines().
因此,为了进一步实验,我尝试向服务器发送一个发布请求,如下所示:
客户端:
Hello
there
!
Run Code Online (Sandbox Code Playgroud)
服务器端:
def gen():
yield 'hi\n'
yield 'there'
requests.post("http://127.0.0.1:5000/stream_post", data=gen())
Run Code Online (Sandbox Code Playgroud)
在服务器控制台上打印:
('hi\n', 0)
('there', 1)
Run Code Online (Sandbox Code Playgroud)
例如,我不知道如何针对序列化对象执行类似的操作。我觉得我的知识存在根本差距,因为我似乎正在寻找一种返回块编码响应的方法?或者至少是某种带有其大小的响应,这样我就可以在客户端迭代它,如果这有意义的话。
我们正在构建一个应用程序,它可以实时记录用户的语音,并通过 HTTP 请求将记录的数据发送到服务器。当服务器实时处理数据时,它也会以分块的形式发回响应。简单来说,应用程序正在向服务器一块一块地发送数据,同时,它也从服务器一块一块地接收响应。
请不要告诉我这是不可能的,因为我在 iOS 中有一个工作示例,它使用 withURLSession使用uploadTask流对将数据实时发送到服务器,然后从此回调中逐块接收响应urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)。
下面是我的 Java 代码。我的发送工作正常,但仅在发送完成后才收到响应。
RequestBody body = new RequestBody()
{
@Override
public MediaType contentType()
{
return MediaType.get("application/octet-stream");
}
@Override
public void writeTo(BufferedSink sink) throws IOException
{
String filename = "/path/spoken.pcm";
try
{
InputStream inputStream = new DataInputStream(new FileInputStream(new File(filename)));
byte[] cacheBytes = new byte[320];
int length;
while((length = inputStream.read(cacheBytes, 0, cacheBytes.length)) != -1)
{
System.out.println("write thread name: " + Thread.currentThread());
sink.write(cacheBytes, …Run Code Online (Sandbox Code Playgroud) 这可能看起来有点奇怪..但我需要评估/解析通过HTTP使用HTTP发送的块.
值得注意的是,HTTP流可能永远不会结束.有没有什么方法可以解析块,因为我用CURL 得到它们?
或者我是否必须采用一些自制的fsockopen()解决方案?
我正在开发一个需要解析Chunked类型HTTP传输的客户端.我试着用下面的方法弄清楚错误,并且如果有人能够更快地捕捉到我的错误,我会很感激.总结一下这个问题:似乎客户端没有收到所有的块,从而搞砸了剩下的进程.提前致谢!
while(cflag){
pfile_chunk = malloc(CHUNK_SIZE+1);
memset(pfile_chunk, 0, CHUNK_SIZE);
cPtr = pfile_chunk;
cPtr2 = NULL;
k=0;
while(*(cPtr-1) != '\n'){
k++;
recv(sock, cPtr, 1, 0);
cPtr = pfile_chunk+k;
}
cPtr2 = strchr(pfile_chunk, '\r');
*cPtr2 = '\0';
sscanf(pfile_chunk, "%x", &l);
if(l == 0)
break;
printf("\nServer wants to deliver %ld bytes.\n", l);
pfile_chunk = realloc(pfile_chunk, l+1);
memset(pfile_chunk, 0, l);
recv(sock, pfile_chunk, l, 0);
fputs(pfile_chunk, f);
printf("GOT THIS, SIZE %ld:\n%s\n", strlen(pfile_chunk), pfile_chunk);
//get next \r\n bytes.
recv(sock, NULL, 2, 0);
}
Run Code Online (Sandbox Code Playgroud) 我正在努力使用Python和Requests访问流API.
API说的是:"我们已经启用了一个流端点,用于通过持久的HTTP套接字连接请求报价和交易数据.来自API的流数据包括发出Authenticated HTTP请求并保持HTTP套接字打开以持续接收数据".
我是如何尝试访问数据的:
s = requests.Session()
def streaming(symbols):
url = 'https://stream.tradeking.com/v1/market/quotes.json'
payload = {'symbols': ','.join(symbols)}
return s.get(url, params=payload, stream=True)
r = streaming(['AAPL', 'GOOG'])
Run Code Online (Sandbox Code Playgroud)
这里的请求文档显示了两个感兴趣的东西:使用生成器/迭代器与分块数据一起使用,在数据字段中传递.对于流数据,它建议使用如下代码:
for line in r.iter_lines():
print(line)
Run Code Online (Sandbox Code Playgroud)
似乎没有效果,虽然我不知道在生成器功能中放什么,因为这个例子不清楚.使用r.iter_lines(),我得到输出:"b'{"status":"connected"} {"status":disconnected"}'"
我可以访问标头,响应是HTTP 200,但无法获取有效数据,或者找到有关如何在python中访问流式HTTP数据的明确示例.任何帮助,将不胜感激.API建议使用Jetty for Java来保持流的开放,但我不确定如何在Python中执行此操作.
标题:{'connection':'keep-alive','content-type':'application/json','x-powered-by':'Express','transfer-encoding':'chunked'}
我刚刚实现了一个HTTP/1.1客户端来解析分块传输编码.但是,它适用于某些网站但不适用于其他网站.我假设我需要读取chunkSize + 2包括\r\n每个块数据的字节,我是对的吗?
这是我的代码:
while(chunked)//if detecting chunked in the header before, this is true
{
//getLine is a function can read a line separated by \r\n
//sockfd is a socket created before and file position is at the start of HTTP body (after that blank line between header and body)
line = getLine(sockfd);
printf("%s", line);//print the chunk size line in hex
int chunkSize = strtol(line, NULL, 16);
if(chunkSize == 0)
{
printf("##### Read chunk size of …Run Code Online (Sandbox Code Playgroud) 我有一台服务器,它可以在大约 15 秒内传输处理数据。标题如下:
Content-Type:text/plain; charset=utf-8
Transfer-Encoding:chunked
Run Code Online (Sandbox Code Playgroud)
通过 telnet,我可以确认数据在 15 秒内连续发送。在浏览器中,整个页面会挂起,直到收到整个请求,然后立即呈现所有内容。
有时,对于较长的请求,它会挂起一段时间,然后在数据到达时开始将数据流式传输到屏幕,但我还没有推断出发生这种情况的阈值。
我是否可以发送一些标头或其他魔法,以使浏览器在内容可用时立即呈现内容?
我正在尝试实现我的 Node js 服务以使用 http 流(传输编码:分块)发送回响应。
我使用“response.on('data', func(chunk))”来接收从服务发回的每个块,并且它现在正在工作。
我的问题是,“response.on('data', func(chunk))”是否保证回调中的块与服务发送的块完全相同?(或者它可以组合多个服务发送的块并仅调用回调一次,或者将单个服务发送的块分割成多个块并多次调用回调?)
谢谢迈克尔
我读了一些关于Comet tech的文章.他们都提到长期HTTP响应应该是Transfer-Encoding:chunked.我想知道为什么它应该被分块编码.如果响应没有分块编码,客户端javascript仍然可以读取并解析响应的文本,对吗?
是否有任何特殊原因可以对Comet响应进行分块编码?
我最近开始在我的网站上使用gzip,它在除Opera之外的所有浏览器上都起到了一种魅力作用,它给出了一个错误,即由于数据损坏而无法解压缩内容.从我可以从测试和谷歌搜索中收集到的,使用gzip和chunked传输编码可能是一个问题.请求像css文件这样的小文件时没有错误这一事实也指向了那个方向.
这是一个已知问题还是还有其他一些我没想过的问题?
有人还提到它可能与发送Content-Length标头有关.
以下是我的代码中最相关部分的简化版本:
$contents = ob_get_contents();
ob_end_clean();
header('Content-Encoding: '.$encoding);
print("\x1f\x8b\x08\x00\x00\x00\x00\x00");
$size = strlen($contents);
$contents = gzcompress($contents, 9);
$contents = substr($contents, 0, $size);
print($contents);
exit();
Run Code Online (Sandbox Code Playgroud)