douzhuo3233 2013-04-04 19:29
浏览 42

在http处理程序中使用goroutine和通道

I've implemented a very simple twitter client reader:

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
", v.Username, v.Text)
    }

}

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

}

I want to build a simple web client for it now and have it display the twitter results. But i'm cautious about calling goroutines in a http handler. Anybody point me in the right direction?

  • 写回答

1条回答 默认 最新

  • dongshi1215 2013-04-04 21:55
    关注

    You're sort of limited with goroutines within the context of an HTTP request because that HTTP request expects a response, not a "wait until later". Here are a couple options:

    1. Use websockets. I've never implemented a websocket in Go, so I don't have any experience there, but this is really the best way to have the client wait for data and display it as it comes in. This blog post seems to have a good tutorial. (You could also use a COMET framework to achieve something similar here.)

    2. Don't use goroutines, but rather AJAX requests to keep the asynchronousness (totally a word) on the client. What that would look like is the client loading your page, which makes a bunch of AJAX requests to your server, which you can handle in multiple threads so they could theoretically all finish around the same time. Note that you can spawn a goroutine to respond to a specific request, but that goroutine should be expected to respond to that request fully.

    3. Use goroutines to make all your requests to the Twitter API, but wait for them all to finish and lump them all together before completing the request and making the response. This lets all your Twitter API requests happen simultaneously and saves you time on the backend, but your client still has to wait for that time (the slowest API request) before showing anything to the user.

    If it were me and I were in a hurry, I'd go with option 2 and leave the heavy lifting to the client, while just using the server as basically a proxy to the Twitter API. But option 1 would be a better solution, especially if you're not too worried about browser compatibility.

    评论

报告相同问题?

悬赏问题

  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?