这是关于将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
Producer
和Consumer
将在Main
中连接(WebSocket连接也将在那里进行),但尚未编写,因为上面的函数甚至不会进行类型检查。
请问如何进行类型检查?它不会进行类型检查的事实可能意味着上面的代码中存在根本性的误解,如果是这样的话,用一个工作解决方案的代码示例来解释将非常有帮助。
相关:这个关于卤素和WebSockets的答案包含非常相似的代码
这个代码片段有几个问题。首先,这里有一个可用的版本:
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
- 你错过了
produce
的使用,这是将emit
带入范围的原因,也是你如何制作生产者的原因。 - 生产者必须使用
Aff
,而不是Eff
。 -
emit
接受Either
,Left
表示应该产生一个值,Right
表示应该关闭生产者。
看看produce
的文档,希望你提到的误解会变得清楚!