繁体   English   中英

core.async 重新连接 websocket

[英]core.async reconnecting websocket

core.async noob here,但尝试通过构建自动重新连接的 websocket 来学习。 这个想法是将套接字抽象出来,这样任何使用它的人都不必担心它是否已连接,只需将消息放在通道上即可。 如果套接字已连接,则立即从通道读取消息并发送。 如果套接字当前未连接,则它会反复尝试重新连接,并在建立连接后等待发送所有挂起的消息。

这是我到目前为止:

(ns frontend.socket
  (:require-macros [cljs.core.async.macros :as asyncm :refer [go]])
  (:require [cljs.core.async :as async :refer [<! >! chan timeout]]))

(def endpoint "ws://localhost:8080")
(def socket (atom nil))
(def open (chan))
(def in (chan))
(def out (chan))
(def error (chan))
(def close (chan))

(defn open? []
  (= (.-readyState @socket) (.-OPEN @socket)))

(defn event>chan
  "Given a core.async channel, returns a
  function which takes an event and feeds
  it into the formerly given channel."
  [channel]
  (fn [e]
    (go (>! channel e))))

(defn connect
  "Opens a websocket, stores it in the socket
  atom, and feeds the socket's events into
  the corresponding channels."
  []
  (let [s (js/WebSocket. endpoint)]
    (reset! socket s)
    (set! s.onopen    (event>chan open))
    (set! s.onmessage (event>chan in))
    (set! s.onerror   (event>chan error))
    (set! s.onclose   (event>chan close))))

(defn init
  "This is the entry point from outside this
  namespace. Eagerly connects and then, if
  ever disconnected, attempts to reconnect
  every second. Also takes messages from
  the out channel and sends them through
  the socket."
  []
  (go
    (while true
      (connect)
      (<! close)
      (<! (timeout 1000))))
  (go
    (while true
      (let [m (<! out)]
        (when (or (open?) (<! open))
          (.send @socket m))))))

重新连接逻辑似乎工作正常,但我遇到了一个问题,试图在套接字关闭后发送消息。 在最后几行中,我在发送消息之前检查套接字是否打开或等待它打开。 问题是,如果在套接字先前打开时没有发送消息,然后关闭,然后发送一条消息,那么仍然有一些东西坐在开放的通道上,因此无论如何都会发送消息。 因此,开放渠道可能会变得“陈旧”,就像它一样。

我想过每当套接字关闭时从开放通道中获取,但这只是扭转了问题:然后开放通道可能会在我确实需要它们时丢失值,并且在重新连接时不会发送消息。

我在这里做错了什么?

这是错误的方法,因为通道将等待被使用。 我需要使用 pub/sub 代替: https : //github.com/clojure/core.async/wiki/Pub-Sub/549da1843c7bbe6009e9904eed49f91000d8ce2c

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM