当前位置: 技术文章>> 100道Go语言面试题之-在Go中,如何实现HTTP长轮询(Long Polling)?

文章标题:100道Go语言面试题之-在Go中,如何实现HTTP长轮询(Long Polling)?
  • 文章分类: 后端
  • 7697 阅读

在Go语言中实现HTTP长轮询(Long Polling)主要涉及到在服务器端保持HTTP连接开启直到有数据可供发送,或者直到达到某个超时时间。长轮询常用于需要实时数据更新的Web应用中,如聊天应用、实时通知系统等。以下是使用Go标准库net/http实现HTTP长轮询的基本步骤:

1. 服务器端设置

服务器端需要能够检测数据变化,并在数据可用时发送数据给客户端,或者等待直到超时。

package main

import (
    "fmt"
    "net/http"
    "sync"
    "time"
)

// 假设这是你的数据源,这里用channel模拟
var dataChan = make(chan string, 1)

// 模拟数据更新
func simulateDataUpdate() {
    time.Sleep(5 * time.Second) // 假设5秒后数据更新
    dataChan <- "New data available"
}

func longPollingHandler(w http.ResponseWriter, r *http.Request) {
    // 设置超时时间
    timeout := 30 * time.Second
    timer := time.NewTimer(timeout)

    // 清理函数,用于在函数退出时关闭writer
    defer func() {
        if !timer.Stop() {
            <-timer.C
        }
        if f, ok := w.(http.Flusher); ok {
            f.Flush()
        }
    }()

    // 设置HTTP头,使浏览器保持连接
    w.Header().Set("Content-Type", "text/event-stream")
    w.Header().Set("Cache-Control", "no-cache")
    w.Header().Set("Connection", "keep-alive")

    // 等待数据或超时
    select {
    case data := <-dataChan:
        fmt.Fprintf(w, "data: %s\n\n", data)
        return
    case <-timer.C:
        // 如果没有数据,发送超时信息或重试逻辑
        fmt.Fprintf(w, "event: timeout\n\n")
    }
}

func main() {
    go simulateDataUpdate() // 模拟数据更新

    http.HandleFunc("/longpoll", longPollingHandler)
    fmt.Println("Server is listening on :8080")
    http.ListenAndServe(":8080", nil)
}

2. 客户端设置

客户端需要发起HTTP请求,并持续监听服务器响应。在JavaScript中,可以使用EventSource API来简化长轮询的实现。

<!DOCTYPE html>
<html>
<body>

<script>
var evtSource = new EventSource("/longpoll");
evtSource.onmessage = function(e) {
    console.log(e.data);
    // 处理接收到的数据
};

evtSource.onerror = function(e) {
    console.error("EventSource failed:", e);
    // 重新连接
    evtSource.close();
    evtSource = new EventSource("/longpoll");
};
</script>

</body>
</html>

注意事项

  • 资源消耗:长轮询会占用服务器资源,因为每个连接都需要保持打开状态直到数据到达或超时。
  • 超时与重连:客户端需要处理超时并重新发起请求。
  • 负载均衡与代理:在部署时,需要确保负载均衡器和代理服务器支持长连接。
  • 安全性:确保你的长轮询端点受到适当的保护,防止未授权访问。

以上就是在Go语言中实现HTTP长轮询的基本方法。

推荐文章