最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Golang實現(xiàn)流式輸出

 更新時間:2025年03月10日 10:54:16   作者:佚名涙  
這篇文章主要為大家詳細介紹了使用Golang實現(xiàn)流式輸出的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

流式輸出的深度剖析

之前一直在調(diào)用openai的key,只是照著文檔進行流式調(diào)用,也只知其確是流式與api有所不同,而未成體系深究其實現(xiàn)原理。

就以openai的官方流式輸出為切入。

概述

流式輸出(Streaming Output)是 HTTP 響應中的一種模式,服務器可以在生成部分內(nèi)容時立即將這些內(nèi)容發(fā)送給客戶端,而無需等待整個響應內(nèi)容生成完成。這種方式常用于實時交互、高延遲操作或長時間任務中,比如 OpenAI 的 GPT 模型生成流式對話。

package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"time"
)

// 定義必要的數(shù)據(jù)結(jié)構(gòu)
type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

type RequestBody struct {
	Model       string    `json:"model"`
	Messages    []Message `json:"messages"`
	Temperature float64   `json:"temperature"`
	Stream      bool      `json:"stream"`
}

type Choice struct {
	Delta struct {
		Content string `json:"content"`
	} `json:"delta"`
}

type ResponseBody struct {
	Choices []Choice `json:"choices"`
}

const (
	apiURL      = "https://api.example.com/v1/chat/completions" // 替換為實際的 API 地址
	authToken   = "your-auth-token"                             // 替換為實際的 Token
	model       = "gpt-3.5-turbo"
	temperature = 0.7
)

func StreamHandler(w http.ResponseWriter, r *http.Request) {
	// 從查詢參數(shù)獲取輸入內(nèi)容
	content := r.URL.Query().Get("content")
	if content == "" {
		http.Error(w, "Missing 'content' parameter", http.StatusBadRequest)
		return
	}

	// 構(gòu)造請求體
	message := Message{
		Role:    "user",
		Content: content,
	}
	requestBody := RequestBody{
		Model:       model,
		Messages:    []Message{message},
		Temperature: temperature,
		Stream:      true,
	}
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		http.Error(w, "Failed to marshal request body", http.StatusInternalServerError)
		return
	}

	// 創(chuàng)建 HTTP 請求
	req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
	if err != nil {
		http.Error(w, "Failed to create request", http.StatusInternalServerError)
		return
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+authToken)

	// 設置 HTTP 客戶端
	client := &http.Client{Timeout: time.Second * 50}
	resp, err := client.Do(req)
	if err != nil {
		http.Error(w, "Failed to get response", http.StatusInternalServerError)
		return
	}
	defer resp.Body.Close()

	// 設置響應頭,開啟流式輸出
	w.Header().Set("Content-Type", "text/event-stream; charset=utf-8")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")

	// 確保 ResponseWriter 支持 Flusher
	flusher, ok := w.(http.Flusher)
	if !ok {
		http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
		return
	}

	// 處理流式響應
	scanner := bufio.NewScanner(resp.Body)
	for scanner.Scan() {
		line := scanner.Text()

		// 處理以 "data: " 開頭的行
		if strings.HasPrefix(line, "data: ") {
			line = strings.TrimPrefix(line, "data: ")
		}
		if line == "[DONE]" {
			break
		}
		if line == "" {
			continue
		}

		// 解析響應內(nèi)容
		var chunk ResponseBody
		if err := json.Unmarshal([]byte(line), &chunk); err != nil {
			continue
		}

		// 將響應數(shù)據(jù)逐步發(fā)送給客戶端
		for _, choice := range chunk.Choices {
			content := choice.Delta.Content
			_, err := w.Write([]byte(content))
			if err != nil {
				http.Error(w, "Failed to write response", http.StatusInternalServerError)
				return
			}
			flusher.Flush() // 刷新緩沖區(qū)
		}
	}

	if err := scanner.Err(); err != nil {
		http.Error(w, "Scanner error", http.StatusInternalServerError)
		return
	}
}

func main() {
	http.HandleFunc("/stream", StreamHandler)
	fmt.Println("Server started at :8080")
	http.ListenAndServe(":8080", nil)
}

核心流程

接收到用戶輸入后,將其作為 content 參數(shù)發(fā)送給目標 API。

開啟流式輸出模式,設置 Stream: true。

使用 http.Flusher 將從遠程接口接收到的內(nèi)容逐步發(fā)送給客戶端。

關(guān)鍵點

1.流式響應頭設置

w.Header().Set("Content-Type", "text/event-stream; charset=utf-8")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")

實時輸出: 通過 w.Write 輸出內(nèi)容后調(diào)用 flusher.Flush() 確保數(shù)據(jù)實時發(fā)送。

啟動服務后,通過瀏覽器訪問類似以下 URL:

http://localhost:8080/stream?content=Hello%20world

客戶端會逐步接收內(nèi)容,類似命令行實時打印。

1. HTTP 協(xié)議中的流式響應

流式輸出利用 HTTP 協(xié)議的特性,不關(guān)閉連接,逐步將數(shù)據(jù)發(fā)送給客戶端。典型流式響應會設置如下 HTTP Header:

Content-Type: text/event-stream表示這是一個事件流(Event Stream),用于向客戶端連續(xù)發(fā)送數(shù)據(jù)片段。

Cache-Control: no-cache防止響應被緩存,以確??蛻舳私邮盏綄崟r內(nèi)容。

Connection: keep-alive 保持連接處于活躍狀態(tài),支持多次數(shù)據(jù)傳輸。

2. 流式輸出的工作原理

客戶端發(fā)起請求,服務器在接收到請求后開始響應。

服務器不一次性生成完整的響應內(nèi)容,而是將生成的部分數(shù)據(jù)逐段發(fā)送。

客戶端收到數(shù)據(jù)后立即處理,而無需等待完整響應結(jié)束。

在數(shù)據(jù)發(fā)送完成后,服務器可以選擇關(guān)閉連接或保持連接以發(fā)送后續(xù)數(shù)據(jù)。

流式輸出的常見應用場景

實時聊天:聊天模型逐詞/逐句生成時,可以實時傳輸數(shù)據(jù)。

日志監(jiān)控:將服務器的實時日志逐行推送到前端。

流式文件傳輸:如大文件或視頻流傳輸。

實時進度更新:如任務進度條更新。

到此這篇關(guān)于使用Golang實現(xiàn)流式輸出的文章就介紹到這了,更多相關(guān)Golang流式輸出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言實現(xiàn)基于websocket瀏覽器通知功能

    Go語言實現(xiàn)基于websocket瀏覽器通知功能

    這篇文章主要介紹了Go語言實現(xiàn)基于websocket瀏覽器通知功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Go中的函數(shù)選項模式(Functional Options Pattern)詳解

    Go中的函數(shù)選項模式(Functional Options Pattern)詳解

    在 Go 語言中,函數(shù)選項模式是一種優(yōu)雅的設計模式,用于處理函數(shù)的可選參數(shù),本文將對其進行講解,準備好了嗎,快跟隨著本文一探究竟吧
    2023-06-06
  • Go語言中定時器cron的基本使用教程

    Go語言中定時器cron的基本使用教程

    這篇文章主要給大家介紹了關(guān)于Go語言中定時器cron使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-01-01
  • 一文搞懂Golang文件操作增刪改查功能(基礎篇)

    一文搞懂Golang文件操作增刪改查功能(基礎篇)

    這篇文章主要介紹了一文搞懂Golang文件操作增刪改查功能(基礎篇),Golang 可以認為是服務器開發(fā)語言發(fā)展的趨勢之一,特別是在流媒體服務器開發(fā)中,已經(jīng)占有一席之地,今天我們不聊特別深奧的機制和內(nèi)容,就來聊一聊 Golang 對于文件的基本操作
    2021-04-04
  • golang編程入門之http請求天氣實例

    golang編程入門之http請求天氣實例

    這篇文章主要介紹了golang編程入門之http請求天氣實例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • Go語言指針用法詳解

    Go語言指針用法詳解

    Go指針和C指針在許多方面非常相似,但其中也有一些不同。本文詳細講解了Go語言指針的用法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 基于Go語言開發(fā)一個JSON格式校驗工具

    基于Go語言開發(fā)一個JSON格式校驗工具

    在日常開發(fā)中,經(jīng)常會遇到需要校驗 JSON 格式是否正確的場景,如果 JSON 格式不正確,系統(tǒng)往往會報錯甚至崩潰,因此開發(fā)一個 命令行 JSON 格式校驗工具 非常實用,所以本文給大家介紹了如何基于Go語言開發(fā)一個JSON格式校驗工具,需要的朋友可以參考下
    2025-09-09
  • 教你一招完美解決vscode安裝go插件失敗問題

    教你一招完美解決vscode安裝go插件失敗問題

    VSCode是我們開發(fā)go程序的常用工具,但是安裝VSCode成功后,創(chuàng)建一個.go文件居然提示錯誤了,所以下面下面這篇文章主要給大家介紹了如何通過一招完美解決vscode安裝go插件失敗問題的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • 在Golang中實現(xiàn)定時任務的幾種高效方法

    在Golang中實現(xiàn)定時任務的幾種高效方法

    本文將詳細介紹在Golang中實現(xiàn)定時任務的幾種高效方法,包括time包中的Ticker和Timer、第三方庫cron的使用,以及基于channel和goroutine的自定義實現(xiàn),我們將通過實際代碼示例和性能分析,幫助開發(fā)者選擇最適合自己場景的定時任務解決方案,需要的朋友可以參考下
    2025-06-06
  • Golang Map value不可尋址使用指針類型代替示例詳解

    Golang Map value不可尋址使用指針類型代替示例詳解

    這篇文章主要為大家介紹了Golang Map value不可尋址使用指針類型代替示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11

最新評論

曲麻莱县| 开封市| 会东县| 巴东县| 庄浪县| 永和县| 汪清县| 阜阳市| 高碑店市| 敖汉旗| 平定县| 丰原市| 丹东市| 垣曲县| 手游| 且末县| 西安市| 洛阳市| 呼玛县| 贵州省| 封开县| 额济纳旗| 彰化市| 永兴县| 如皋市| 迁安市| 潜山县| 伊宁市| 讷河市| 宣威市| 墨江| 溧阳市| 屯门区| 台湾省| 阿尔山市| 洪江市| 印江| 营口市| 于田县| 青海省| 广平县|