我实现了一个非常简单的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持谨慎态度。有人指出我正确的方向吗?
答案 0 :(得分:2)
您在HTTP请求的上下文中受到goroutine的限制,因为该HTTP请求需要响应,而不是“等到以后”。以下是几个选项:
使用websockets。我从来没有在Go中实现过websocket,所以我没有任何经验,但这确实是让客户端等待数据并在显示时显示它的最佳方式。This blog post似乎有一个很好的教程。 (您也可以使用COMET框架来实现类似的功能。)
不要使用goroutine,而是使用AJAX请求来保持客户端的异步性(完全是一个单词)。这看起来就像是客户端加载你的页面,这会向你的服务器发出一堆AJAX请求,你可以在多个线程中处理这些请求,这样理论上它们可以在同一时间内完成。请注意,您可以生成goroutine以响应特定请求,但应该期望该goroutine完全响应该请求。
使用goroutines向Twitter API发出所有请求,但等待所有请求完成并将它们全部混合在一起,然后再完成请求并做出响应。这可以让您的所有Twitter API请求同时发生并节省您在后端的时间,但您的客户端仍然必须等待该时间(最慢的API请求),然后才向用户显示任何内容。
如果是我和我匆忙,我会选择2并将繁重的工作留给客户,而只是使用服务器作为Twitter API的代理。但是选项1将是更好的解决方案,特别是如果您不太担心浏览器兼容性。