swoole+fetch实现http流式请求响应

swoole+fetch实现http流式请求响应

大家都知道chatgpt在响应的时候是一个字一个字的输出,这就是流式输出,不过chatgpt使用的eventsource服务端通知技术,具体代码及流程可以参考我的另一篇笔记 https://blog.bfw.wiki/biji_16829157431913890049.html

今天来我们换一种方式,采用http长连接来实现流式输出。

一、http长连接与短连接

我们想看http的长连接与短连接的请求响应图。

<a href='/tag/swoole.html'>swoole</a>+fetch实现http流式请求响应

HTTP 短连接(也称非持久连接)是指客户端和服务器每进行一次 HTTP 请求/响应之后就会关闭连接,下次请求需要重新建立连接。这种连接方式的优点是能够减少服务器的负载,因为连接短暂,服务器可以更快地处理请求并释放资源,但缺点是每次建立连接都需要消耗时间和资源,可能会影响网络传输速度。HTTP 长连接(也称持久连接)是指客户端和服务器之间建立一次连接后,可以进行多次 HTTP 请求/响应,直到客户端或服务器关闭连接。这种连接方式的优点是能够减少连接建立和关闭的开销,提高网络传输效率,但缺点是在连接期间,服务器需要一直维护连接资源,可能会占用服务器资源,导致服务器负载过高。HTTP 长连接可以进一步扩展为 HTTP 流,也称为服务器推送,即服务器可以在不被请求的情况下向客户端推送数据。HTTP 流通常用于实时通信应用程序、推送通知等场景,能够提高性能和用户体验。总之,HTTP 短连接适用于请求响应次数较少、请求间隔较长的场景,HTTP 长连接适用于请求响应次数较多、请求间隔较短或需要推送数据的场景。根据具体的应用场景和需求,可以选择不同类型的连接方式来优化网络传输效率和性能。

好了我们来通过swoole实现http长连接的服务端流式通知.

二、实现代码

php服务端

<?php
$http = new swoole_http_server("0.0.0.0", 8091);

$http->on('request', function ($request, $response) {
    $response->header("Access-Control-Allow-Origin", "*");
    $response->header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
    $response->header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
    $response->header('Content-Type', 'text/plain');
    $response->write("msg\n");
    for ($i = 0; $i < 1000; $i++) {
        sleep(1);
        $response->write("msg{$i}\n");
    }


});

$http->start();

前端html代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum=1.0,minimum=1.0,user-scalable=0" />
    <title>BFW NEW PAGE</title>
</head>
<body>
<script type="module">
const resp  =  await fetch("http://web.debug.only.bfw.wiki:8091/", {
   method: "POST",
   headers: {},
   body: JSON.stringify({})
});
		
const reader = resp.body.getReader();
const textDecoder = new TextDecoder();
while (1){
    const { done, value} = await reader.read();
    if (done){
        break;
    }
    const str = textDecoder.decode(value);
    console.log(str);
}
</script>
</body>
</html>
		

{{collectdata}}

网友评论0