私はしばらくの間 clojure を使用してきましたが、twitter-api ( https://github.com/adamwynne/twitter-api ) が基づいている async io に慣れていません。
特定のキーワード セットに一致するすべてのツイートを収集したいと考えています。たとえば、「Mary rose」(現在英国で流行しているもの)に一致するものすべてです。ストリーミング呼び出しを行うためのドキュメントには、次のようなことをするように書かれています:
(ns mynamespace
(:use
[twitter.oauth]
[twitter.callbacks]
[twitter.callbacks.handlers]
[twitter.api.streaming])
(:require
[clojure.data.json :as json]
[http.async.client :as ac]
[clojure.java.io :as io])
(:import
(twitter.callbacks.protocols AsyncStreamingCallback)))
(def my-creds (make-oauth-creds *app-consumer-key*
*app-consumer-secret*
*user-access-token*
*user-access-token-secret*))
; supply a callback that only prints the text of the status
(def ^:dynamic
*custom-streaming-callback*
(AsyncStreamingCallback. (comp println #(:text %) json/read-json #(str %2))
(comp println response-return-everything)
exception-print))
(statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*)
私が次のようなことをした場合:
(def mary (statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*))
http 応答のマップを取得します。
(keys mary)
;; (:id :url :raw-url :status :headers :body :done :error)
体の部分は、継続的に更新されるビットだと思います。
(class @(:body mary))
;; java.io.ByteArrayOutputStream
ストリームをファイルに保存するためにこれを試しました:
(with-open [r @(:body (statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*))
w (io/writer "mary.txt")]
(dosync (.write w (str r "\n"))))
これは、最初のつぶやきを mary.txt ファイルに書き込みますが、その後接続を閉じます。おそらく、r へのバインドの前に @ を使用しているためです (ただし、@ を r の前に置くとチョークします。代わりに非同期化します。
@(dosync (:body (statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*)))
繰り返しますが、接続が閉じられる前に最初のツイートしか取得しません。
接続を開いたままにし、無期限にツイートを受信し続けるにはどうすればよいですか?