2

我已经实现了一个非常简单的 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 客户端并让它显示 twitter 结果。但我对在 http 处理程序中调用 goroutines 持谨慎态度。有人指出我正确的方向吗?

4

1 回答 1

2

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.

于 2013-04-04T21:55:15.597 回答