Replicating Twitter Firehose

blov · · 738 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I want to build something very similar to the Twitter Firehose with their streaming API.</p> <p>I want to have one or more API clients connect in and to be able to send down a JSON (compressed/uncompressed) payload.</p> <p>I have already acheived this using straightforward TCP4 connections but the Twitter way with HTTP seems a little more elegant. Also by replicating Twitter there are a ton of examples in lots of languages that people could use to connect in.</p> <p>Question is...where do you start with this in Go? It seems a little backwards to keep a persistent HTTP connection open and for the server to send down to the client.</p> <p>Any advice/guidance appreciated!!</p> <hr/>**评论:**<br/><br/>mm_5687: <pre><blockquote> <p>It seems a little backwards to keep a persistent HTTP connection open and for the server to send down to the client.</p> </blockquote> <p>That&#39;s exactly how it works though.</p> <p>It&#39;s a chunked http connection, there&#39;s not much more to it.</p></pre>lesmond: <pre><p>Ah ok, so it&#39;s just a chunked connection. So you&#39;d use the standard HTTP server and just set the headers and send those down to the client on connection?</p></pre>mm_5687: <pre><p>I don&#39;t even think you need to manually add the headers, Go handles that for you: <a href="https://golang.org/pkg/net/http/#Request.Write" rel="nofollow">https://golang.org/pkg/net/http/#Request.Write</a></p></pre>lesmond: <pre><p>So I have this example that I just put together but the connection closes but I essentially want to keep the connection open until a write happens (or a timeout).</p> <pre><code>func startHTTP(pathPrefix string) { log.Println(&#34;Starting HTTPS Server&#34;) http.HandleFunc(&#34;/&#34;, func(w http.ResponseWriter, r *http.Request) { // Wait here until a write happens to w }) log.Print(&#34;HTTPS listening on :5556&#34;) log.Fatal(http.ListenAndServeTLS(&#34;:5556&#34;, pathPrefix+&#34;.crt&#34;, pathPrefix+&#34;.key&#34;, nil)) } </code></pre></pre>tv64738: <pre><p>Typed quickly straight into reddit but something like this:</p> <pre><code>import &#34;github.com/tv42/topic&#34; type MyApp struct { msgs *topic.Topic } func NewApp() *MyApp { app := &amp;MyApp{ msgs: topic.New(), } // simulate activity; this silly example leaks a goroutine go func() { for { time.Sleep(100*time.Millisecond) app.msgs.Broadcast &lt;- &#34;hello, world&#34; } }() return app } func (a *MyApp) ServeHTTP(w http.ResponseWriter, req *http.Request) { ctx := req.Context() enc := json.NewEncoder(w) ch := make(chan interface{}, 100) a.msgs.Register(ch) defer a.msgs.Unregister(ch) for { select { case msg, ok := &lt;-ch: if !ok { log.Printf(&#34;kicking slow client&#34;) return } if err := enc.Encode(msg); err != nil { log.Printf(&#34;cannot marshal json: %v&#34;, err) return } if f, ok := w.(http.Flusher); ok { f.Flush() } case &lt;-ctx.Done(): // client canceled request return } } } </code></pre></pre>Redundancy_: <pre><p>Out of curiosity, why not go with websockets?</p></pre>lesmond: <pre><p>Good point but no need for all the extra overhead IMHO. </p></pre>Redundancy_: <pre><p>I thought that websockets were generally more efficient than long-polling connections, and have built in support in a number of languages.</p></pre>girishramnani1234: <pre><p>You also checkout <a href="http://www.nchan.io" rel="nofollow">nchan</a>. It supports more than persistent http connections.</p></pre>Redundancy_: <pre><p>Forbidden on http and bad cert on https?</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

738 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传