在http处理程序中使用goroutines和channel

时间:2013-04-04 19:29:44

标签: http go channels

我实现了一个非常简单的Twitter客户端阅读器:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "time"
)

type twitterResult struct {
    Results []struct {
        Text     string `json:"text"`
        Ids      string `json:"id_str"`
        Name     string `json:"from_user_name"`
        Username string `json:"from_user"`
        UserId   string `json:"from_user_id_str"`
    }
}

var (
  twitterUrl = "http://search.twitter.com/search.json?q=%23UCL"
  pauseDuration = 5 * time.Second
)

func retrieveTweets(c chan<- *twitterResult) {
    for {
        resp, err := http.Get(twitterUrl)
        if err != nil {
            log.Fatal(err)
        }

        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        r := new(twitterResult) //or &twitterResult{} which returns *twitterResult
        err = json.Unmarshal(body, &r)
        if err != nil {
            log.Fatal(err)
        }
        c <- r
        time.Sleep(pauseDuration)
    }

}

func displayTweets(c chan *twitterResult) {
    tweets := <-c
    for _, v := range tweets.Results {
        fmt.Printf("%v:%v\n", v.Username, v.Text)
    }

}

func main() {
    c := make(chan *twitterResult)
    go retrieveTweets(c)
    for {
        displayTweets(c)
    }

}

我想现在为它构建一个简单的Web客户端,并让它显示推特结果。但是我对在http处理程序中调用goroutines持谨慎态度。有人指出我正确的方向吗?

1 个答案:

答案 0 :(得分:2)

您在HTTP请求的上下文中受到goroutine的限制,因为该HTTP请求需要响应,而不是“等到以后”​​。以下是几个选项:

  1. 使用websockets。我从来没有在Go中实现过websocket,所以我没有任何经验,但这确实是让客户端等待数据并在显示时显示它的最佳方式。This blog post似乎有一个很好的教程。 (您也可以使用COMET框架来实现类似的功能。)

  2. 不要使用goroutine,而是使用AJAX请求来保持客户端的异步性(完全是一个单词)。这看起来就像是客户端加载你的页面,这会向你的服务器发出一堆AJAX请求,你可以在多个线程中处理这些请求,这样理论上它们可以在同一时间内完成。请注意,您可以生成goroutine以响应特定请求,但应该期望该goroutine完全响应该请求。

  3. 使用goroutines向Twitter API发出所有请求,但等待所有请求完成并将它们全部混合在一起,然后再完成请求并做出响应。这可以让您的所有Twitter API请求同时发生并节省您在后端的时间,但您的客户端仍然必须等待该时间(最慢的API请求),然后才向用户显示任何内容。

  4. 如果是我和我匆忙,我会选择2并将繁重的工作留给客户,而只是使用服务器作为Twitter API的代理。但是选项1将是更好的解决方案,特别是如果您不太担心浏览器兼容性。