dsgw8802
2017-06-21 13:00
浏览 117
已采纳

Golang HTTP服务器等待数据发送到客户端

I am creating a streaming API similar to the Twitter firehose/streaming API.

As far as I can gather this is based on HTTP connections that are kept open and when the backend gets data it then writes to the chucked HTTP connection. It seems that any code I write closes the HTTP connection as soon as anything connects.

Is there a way to keep this open at all?

func startHTTP(pathPrefix string) {
    log.Println("Starting HTTPS Server")
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // Wait here until a write happens to w
        // Or we timeout, we can reset this timeout after each write
    })

    log.Print("HTTPS listening on :5556")
    log.Fatal(http.ListenAndServeTLS(":5556", pathPrefix+".crt", pathPrefix+".key", nil))
}

图片转代码服务由CSDN问答提供 功能建议

我正在创建类似于Twitter firehose / streaming API的流API。 < 据我所知,这是基于保持开放状态的HTTP连接的,当后端获取数据时,它会写入被阻止的HTTP连接。 看来,我编写的任何代码都会在任何东西连接后立即关闭HTTP连接。

有没有办法使它保持打开状态?

   func startHTTP(pathPrefix string){
 log.Println(“ Starting HTTPS Server”)
 http.HandleFunc(“ /”,func(w http.ResponseWriter,r * http.Request){
 // 在这里等待,直到发生写操作w 
 //否则我们超时,我们可以在每次写操作后重置此超时
})
 
 log.Print(“ HTTPS监听:5556”)
 log.Fatal(  http.ListenAndServeTLS(“:5556”,pathPrefix +“。crt”,pathPrefix +“。key”,nil))
} 
   
 
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dpe77294 2017-06-21 18:20
    已采纳

    When you want to send HTTP response to client not immediately but after some event, it's called long polling.

    Here's simple example of long polling with request cancellation on client disconnect:

    package main
    
    import (
        "context"
        "fmt"
        "net/http"
        "time"
    )
    
    func longOperation(ctx context.Context, ch chan<- string) {
        // Simulate long operation.
        // Change it to more than 10 seconds to get server timeout.
        select {
        case <-time.After(time.Second * 3):
            ch <- "Successful result."
        case <-ctx.Done():
            close(ch)
        }
    }
    
    func handler(w http.ResponseWriter, _ *http.Request) {
        notifier, ok := w.(http.CloseNotifier)
        if !ok {
            panic("Expected http.ResponseWriter to be an http.CloseNotifier")
        }
    
        ctx, cancel := context.WithCancel(context.Background())
        ch := make(chan string)
        go longOperation(ctx, ch)
    
        select {
        case result := <-ch:
            fmt.Fprint(w, result)
            cancel()
            return
        case <-time.After(time.Second * 10):
            fmt.Fprint(w, "Server is busy.")
        case <-notifier.CloseNotify():
            fmt.Println("Client has disconnected.")
        }
        cancel()
        <-ch
    }
    
    func main() {
        http.HandleFunc("/", handler)
        http.ListenAndServe("localhost:8080", nil)
    }
    

    URLs:

    1. Golang : anonymous struct and empty struct.
    2. Send a chunked HTTP response from a Go server.
    3. Go Concurrency Patterns: Context.

    Gists:

    1. Golang long polling example.
    2. Golang long polling example with request cancellation.
    已采纳该答案
    打赏 评论

相关推荐 更多相似问题