用php实现边执行边输出的效果

分类首页前端日期1年前访问460评论0

后端代码

public function test(){
        header('X-Accel-Buffering: no');
        ob_end_flush();
        ob_implicit_flush(1);;
         header("Cache-Control: no-cache");
        header("Content-Type: text/event-stream");
        for($i=0;$i<5;$i++)
        {
            echo 'data: '.$i.nl2br('测试');
            echo "\n\n";
            // 如果浏览器已关闭
            if ( connection_aborted() )
            {
                exit;  //如果希望关了浏览器后程序继续执行,把这行去掉即可
            }
            sleep(1);
        }
        
        echo 'data: [DONE]';
        echo "\n\n";
    }


前端代码

第一种:
async  loadNovel(prompt) {
		  // const resp = await fetch(url);
		  let resp = await fetch("https://wx.xxxxxx.com/api/v1/openai/chat", {
			  method: "POST",
			  headers: {
				  "Content-Type": "application/json"
			  },
			  body:JSON.stringify({
				prompt: prompt
			  }),
		  });
		  const reader = resp.body.getReader();
		  const decoder = new TextDecoder();
		  let remainChunk = new Uint8Array(0);
		  for (;;) {
			  
			const { value, done } = await reader.read();
			if (done) {
			  break;
			}
			const lastIndex = value.lastIndexOf(10);
			const chunk = value.slice(0, lastIndex + 1);
			const readChunk = new Uint8Array(remainChunk.length + chunk.length);
			readChunk.set(remainChunk);
			readChunk.set(chunk, remainChunk.length);
			remainChunk = value.slice(lastIndex + 1);
			const text = decoder.decode(readChunk);
			console.log(text);
		  }
		  const text = decoder.decode(remainChunk);
		  console.log(text);
	},

第二种:
 
loadNovel() {
var that = this;
	
	  var source = this.source = new EventSource(`/api/v1/openai/chat?cid=${this.cid}&prompt=${encodeURIComponent(chatMsg)}`);

      source.addEventListener("open", function () {
        console.log("connect");
      });

      //如果服务器响应报文中没有指明事件,默认触发message事件
      source.addEventListener("message", function (e) {
        console.log(`resp:(${e.data})`);

        if (e.data == "[DONE]") {
          
          return;
        }

        var content = e.data;
		
        if (content.includes("[ENTRY]")) {
          content = content.replaceAll("[ENTRY]", "\n");
        }

		
        conv["speeches"][0] += content
      });

      //发生错误,则会触发error事件
      source.addEventListener("error", function (e) {
		  console.log( e);
        console.log("error:" + e.data);
        source.close();
        that.source = undefined;
      });
}
第二种效果图: