Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Websocket Clojure Sente:Sente在页面加载并销毁视图后向客户端发送后续消息_Websocket_Clojure_Reagent - Fatal编程技术网

Websocket Clojure Sente:Sente在页面加载并销毁视图后向客户端发送后续消息

Websocket Clojure Sente:Sente在页面加载并销毁视图后向客户端发送后续消息,websocket,clojure,reagent,Websocket,Clojure,Reagent,我很不明白为什么sente在页面最初加载8秒后会自动向客户端发送消息。更奇怪的是,如果我在这之前通过websocket快速向服务器发送消息,那么一切都会稳定下来,视图也不会崩溃 作为参考,前端是clojurescript with试剂,它是一个luminus项目。作为进一步的参考,它几乎就是“使用clojure进行web开发”第5章中的示例应用程序 我可以说是服务器将消息推送到客户端造成了问题,我只是对Sente了解不够,无法理解它为什么会这样做 以下是我认为相关的代码: 服务器端: (defn

我很不明白为什么sente在页面最初加载8秒后会自动向客户端发送消息。更奇怪的是,如果我在这之前通过websocket快速向服务器发送消息,那么一切都会稳定下来,视图也不会崩溃

作为参考,前端是clojurescript with试剂,它是一个luminus项目。作为进一步的参考,它几乎就是“使用clojure进行web开发”第5章中的示例应用程序

我可以说是服务器将消息推送到客户端造成了问题,我只是对Sente了解不够,无法理解它为什么会这样做

以下是我认为相关的代码:

服务器端:

(defn save-message! [message]
  (if-let [errors (validate-message message)]
    {:errors errors}
    (do
      (db/save-message! message)
      message)))

(defn handle-message! [{:keys [id client-id ?data]}]
  (when (= id :guestbook/add-message)
    (let [response (-> ?data
                       (assoc :timestamp (java.util.Date.))
                       save-message!)]
      (if (:errors response)
        (chsk-send! client-id [:guestbook/error response])
        (doseq [uid (:any @connected-uids)]
          (chsk-send! uid [:guestbook/add-message response]))))))
客户端(带试剂):

问题是,当sente自己发送消息时,没有数据来更新消息(或者至少这是我的最佳猜测),因此atom的字段变为null,而试剂(react.js)抛出尝试从vdom进行区分和修补

如果有人知道sente在做什么,我们将不胜感激。当您使用Immutant的异步套接字支持,并且自己做大量工作(序列化/反序列化、处理连接等)时,这种完全相同的设置可以很好地工作



作为后续行动,我通过过滤非零消息解决了这个问题:

(defn response-handler [messages fields errors]
  (fn [{[_ message] :?data}]
    (if-let [response-errors (:errors message)]
      (reset! errors response-errors)
      (when (not= message nil)
        (reset! errors nil)
        (reset! fields nil)
        (swap! messages conj message)))))

尽管如此,这是一种绷带解决方案,如果没有立即使用套接字,知道为什么Sente在页面加载后向我抛出一条消息会很好;websocket框架应有一个子选项卡

Sente自己发送一些事件,如果我没记错的话,事件名称(作为事件向量第一个元素的关键字)位于
chsk
名称空间中。我认为,无论如何,您应该在事件名称上使用某种分派,而不是假设只有一种事件会到达


在re-frame的上下文中,我一直在过滤不需要的事件,并将其余的发送到re-frame事件循环。我想你可以在鲁米努斯做类似的事情。在服务器端,我在类似的设置中使用了多种方法。

意外消息可能是周期性的套接字ping。我认为您是正确的。在“make channel socket client!”函数中,作为第二个参数传递的配置映射有一个keep-alive,如果您自己没有配置它,它默认为20秒的间隔。我没有正确地处理这些ping,所以这就是我要做的。关于开发工具,我想你是指chrome?Firefox过去有一个非常好的websocket检查器,但目前正在为Firefox 60+进行更新。
(defn response-handler [messages fields errors]
  (fn [{[_ message] :?data}]
    (if-let [response-errors (:errors message)]
      (reset! errors response-errors)
      (when (not= message nil)
        (reset! errors nil)
        (reset! fields nil)
        (swap! messages conj message)))))