dongluo3962 2015-02-09 21:37
浏览 111
已采纳

带有通道的Golang handlefunc

I think this question has been asked before (and probably more than once) but I can't find it...

Im learning Go, and I wanted to extend the classical web server example by sending a channel to the "handler".

I have this standard thing:

func hello(w http.ResponseWriter, r *http.Request) {
   io.WriteString(w, "Hello world!")
}

func main() {
    http.HandleFunc("/", hello)
    http.ListenAndServe(":8000", nil)
}

And now I would like the "hello" function to be able to write stuff on a channel, for someone to consume... The way I have done with "normal" functions is to create a channel:

c := make(chan string) 

and pass c in the call to the function. Something like:

dosomething(c)

But... how would I go about doing that if I want "hello" to get access to the channel c?

  • 写回答

2条回答 默认 最新

  • dongwei2610 2015-02-10 01:06
    关注

    There are two other ways to do this (other than exporting your channels as in the previous answer).

    The first is to use a function to return another handler function. When the function is returned, it will create a closure around the channel.

    func makeHello(logger chan string) func(http.ResponseWriter, *http.Request) {
        return func(w http.ResponseWriter, r *http.Request) {
            logger <- r.Host
            io.WriteString(w, "Hello world!")
        }
    }
    

    The second is to use a struct which holds the channel as a member and use pointer receiver methods to handle the request...

    type DataPasser struct {
        logs chan string
    }
    
    func (p *DataPasser) handleHello(w http.ResponseWriter, r *http.Request) {
        p.logs <- r.URL.String()
        io.WriteString(w, "Hello world")
    }
    

    This is a full working example (just hit /1 and /2 to see the two examples)

    package main
    
    import (
        "fmt"
        "io"
        "net/http"
    )
    
    func main() {
        // METHOD 1
        logs := make(chan string)
        go logLogs(logs)
        handleHello := makeHello(logs)
    
        // METHOD 2
        passer := &DataPasser{logs: make(chan string)}
        go passer.log()
    
        http.HandleFunc("/1", handleHello)
        http.HandleFunc("/2", passer.handleHello)
        http.ListenAndServe(":9999", nil)
    }
    
    // METHOD 1
    
    func makeHello(logger chan string) func(http.ResponseWriter, *http.Request) {
        return func(w http.ResponseWriter, r *http.Request) {
            logger <- r.Host
            io.WriteString(w, "Hello world!")
        }
    }
    
    func logLogs(logger chan string) {
        for item := range logger {
            fmt.Println("1. Item", item)
        }
    }
    
    // METHOD 2
    
    type DataPasser struct {
        logs chan string
    }
    
    func (p *DataPasser) handleHello(w http.ResponseWriter, r *http.Request) {
        p.logs <- r.URL.String()
        io.WriteString(w, "Hello world")
    }
    
    func (p *DataPasser) log() {
        for item := range p.logs {
            fmt.Println("2. Item", item)
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算