在go http处理程序中使用goroutine和channel使得ResponseWriter被阻止

时间:2017-03-23 14:52:36

标签: go channel goroutine

package main

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

var ch chan bool

func testTimer1() {
    go func() {
        log.Println("test timer 1")
        ch <- true
    }()

}

func timer1() {
    timer1 := time.NewTicker(2 * time.Second)
    select {
    case <-timer1.C:
        testTimer1()
    }

}

func myhandler(w http.ResponseWriter, r *http.Request) {
    for {
        go timer1()

        a := <-ch
        log.Println("get a: ", a)
        fmt.Fprintf(w, "hello world!!!!", a)
    }

    log.Println("test for break")
}

func main() {
    ch = make(chan bool)
    http.HandleFunc("/", myhandler)
    http.ListenAndServe(":8080", nil)
}

我写了上面的代码,把一个频道放到“myhandler”中,频道就是了

时给出一个bool数据

计时器任务已执行。

然后我从频道获取数据并将“hello world”写入http writer

但是我发现客户端无法收到“你好世界”,作家被封锁!!!!!

任何人都知道这个吗?

查看我的cmd上运行的图片: enter image description here

enter image description here

2 个答案:

答案 0 :(得分:1)

[J1,J2] = rectifyStereoImages(I1,I2,calibrationSession.CameraParameters); 循环是一个无限循环,因此打印到for不是&#34;预定&#34;即将发生。如果您想要类似于彗星的接近(或长轮询网址),您可以尝试this method

ResponseWriter中的代号也泄漏了。根据{{​​3}}:

  

停止代码以释放相关资源。

每次拨打timer1()时,您都会创建一个新的自动收报机,而且自动收报机永远不会关闭,所以每个新的自动收报机都会加起来。

答案 1 :(得分:1)

简短回答

避免缓冲

客户端

将curl与--no-buffer set

一起使用
curl http://localhost:8080 --no-buffer

服务器端

fmt.Fprint

后刷新一次
w.(http.Flusher).Flush()

长答案

实现HTTP流时最大的问题是了解缓冲的效果。缓冲是将读取或写入累积到临时固定的存储空间中的做法。缓冲的优点包括减少读或写呼叫开销。例如,您可以一次写入4096KB,而不是写入1KB 4096次。这意味着您的程序可以创建一个写缓冲区,其中包含4096KB的临时数据(可以与磁盘块大小对齐),一旦达到空间限制,缓冲区就会刷新到磁盘。

此处上面提到的HTTP组件包括两个组件Server(go server)和Client(Curl)。这些组件中的每一个都可以拥有可调整和不同的缓冲样式和限制。

一个不相关的问题,在程序中给出它还有一个问题,即不停止计时器总是停止自动收报机释放相关资源。

这是一个带有一些更正的实现

<强>代码

package main

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

var ch chan bool

func testTimer1() {
    go func() {
        log.Println("test timer 1")
        ch <- true
    }()

}

func timer1() {
    timer1 := time.NewTicker(2 * time.Second)
    defer timer1.Stop()
    <-timer1.C
    testTimer1()
}

func myhandler(w http.ResponseWriter, r *http.Request) {
    for {
        go timer1()

        a := <-ch
        log.Println("get a: ", a)
        fmt.Fprintf(w, "hello world!!!! - %v", a)
        w.(http.Flusher).Flush()
    }
}

func main() {
    ch = make(chan bool)
    http.HandleFunc("/", myhandler)
    http.ListenAndServe(":8080", nil)
}

卷曲

curl http://localhost:8080 --no-buffer