簡體   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