2024 Clojure状态调查!上分享你的想法。

欢迎!请参阅关于页面,了解更多关于这个网站的信息。

0投票
IO

我想读取一个json HTTP流并无限期地使用其中的json元素。

我写了下面的代码,但它会关闭流,并且只返回30个结果 - 我怎么才能无限期地使用HTTP流呢?

谢谢你的帮助!

(ns core
  (:require [clj-http.client :as http]
            [cheshire.core :as json]
            [clojure.java.io :as io]
            [clojure.core.async :as async]))

(def gh-url "https://api.github.com/events")
(def chan (async/chan 100))

(async/go
  (loop [r (async/<! chan)]
    (when (not-empty r) (println (:type r)))
    (recur (async/<! chan))))

(defn read-gh-stream [url]
  (with-open [stream (-> url (http/get {:as :stream}) :body)]
    (let [lines (-> stream io/reader (json/parse-stream true))]
      (doseq [l lines]
        (async/go
          (async/>! chan l))))))

1 答案

+1投票

GitHub API每次HTTP调用将只返回30个事件,不会像发生时那样保持向您推送事件。如果想要下一批30个事件,您必须向GitHub API发出另一个请求。请参阅以下文档:https://developer.github.com/v3/activity/events/

谢谢回复!我将尝试使用Twitter持久HTTP流。

我所编写的代码能确保正确吗?还是说`do-seq`会关闭流?

PS:我还在尝试通过流将日志文件消费到`core.async`,但文件连接总是在某个时候关闭。
by
编辑 by
`with-open`会在它的身体(doseq)结束后关闭流。您每次都必须重新运行`read-gh-stream`。
by
如果`lines`是懒加载的,我相信`doseq`会持续处理流,尽管`parse-stream`文档说

如果顶层对象是一个数组,它将进行懒加载解析
by
谢谢,我明白了。

我仍然在挣扎于读取一个(不断更新的)日志文件,并将每一行发送到一个通道。我似乎找不到一个示例来说明如何这样做。
...