【问题标题】:Mixing Coroutines and Websockets in PureScript在 PureScript 中混合协程和 Websocket
【发布时间】:2016-09-25 06:07:24
【问题描述】:

这是关于将 WebSocket 的输入和输出连接到协程的尝试。

以下函数接受 Connection,然后在收到消息时将其设置为 emit 协程值。

module Main where

import Prelude
import Control.Coroutine (emit, Producer, Consumer, await)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Control.Monad.Eff.Var (($=))
import Control.Monad.Reader.Trans (lift)
import Control.Monad.Rec.Class (forever)
import WebSocket (WEBSOCKET, Connection(..), newWebSocket, URL(..), runMessage, runMessageEvent)

wsProducer :: Connection → Producer String (Eff _) Unit
wsProducer (Connection s) = s.onmessage $= emit <<< runMessage <<< runMessageEvent

ProducerConsumer 将连接到 Main(WebSocket 连接也将在那里建立),但尚未编写,因为上面的函数甚至不会类型检查。

请问如何进行类型检查?它不会进行类型检查的事实可能意味着上面的代码存在根本性的误解,如果是这样,用一个工作解决方案的代码示例进行解释将非常有帮助。

相关:this answer about Halogen and WebSockets 包含非常相似的代码。

【问题讨论】:

    标签: websocket purescript


    【解决方案1】:

    这个 sn-p 有几个问题。首先,这是一个可行的版本:

    module Main where
    
    import Prelude
    
    import Control.Coroutine (Producer)
    import Control.Coroutine.Aff (produce)
    import Control.Monad.Aff (Aff)
    import Control.Monad.Aff.AVar (AVAR)
    import Control.Monad.Eff.Var (($=))
    
    import Data.Either (Either(..))
    
    import WebSocket (WEBSOCKET, Connection(..), runMessageEvent, runMessage)
    
    wsProducer :: forall eff. Connection → Producer String (Aff (avar :: AVAR, ws :: WEBSOCKET | eff)) Unit
    wsProducer (Connection s) =
      produce \emit ->
        s.onmessage $= emit <<< Left <<< runMessage <<< runMessageEvent
    
    1. 您错过了 produce 的使用,这是将 emit 纳入范围的原因,也是您制作制作人的方式。
    2. 生产者必须使用Aff,而不是Eff
    3. emit 接受 Either - Left 值表示应生成值,Right 表示应关闭生产者。

    看看at the docs for produce,希望你提到的误会能澄清!

    【讨论】:

    • 我想知道我是否应该使用produce。我正在关注purescript-coroutines documentation,请参阅nats 函数,它使用emit 但不使用produce。在文档中完全不清楚在什么情况下应该使用什么,当有副作用时应该使用produce
    • 这段代码有效(我基本上得到了解释),非常感谢。恐怕我没有足够的代表。赞成您的答案,但我已将其标记为已接受的答案。
    • 啊,对,是的 - produce-aff-coroutines 的一部分,当您与某种有效的制作人合作时。 -coroutines 只处理一般情况,对底层 monad 没有意见。如果您在您所指的文档中注明,mProducer 中完全未指定(除了Monad 约束),因为它是纯粹的 - 它只是引入Eff 的消费者,由于在那里使用log。在这种情况下,我们必须做一些有效的事情才能使Producer 均匀,因此需要像produce 这样的东西。
    • produce itself doesn't consist of much code,所以理论上你可以在需要时自己重新实现它(它是一些 AVar 用法之上的薄层),但这有点棘手,而且相当常见的用例,这也是它作为自己的库存在的原因。
    • 伟大的@gb.,感谢您的澄清。我希望这一切也对其他人有所帮助。
    猜你喜欢
    • 2017-06-20
    • 1970-01-01
    • 2015-04-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    相关资源
    最近更新 更多