haskell 是否可以动态重新配置ConduitT步骤?

nqwrtyyt  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(125)

我有一个servant服务器,它实现了一个用于授权的Web Socket票证系统。我使用servant-websocketsa Conduit endpoint。我定义了一个输入消息:

data WSInput
  = Auth {token :: String}
  | InMessage {inValue :: Value}
  deriving (Show, Generic)

并且由于票证只会持续几秒钟,因此我的管道管道只会检查Auth消息中的第一条入站消息。出站消息如下所示:

data WSOutput
  = PoisonPill
  | AuthOK
  | OutMessage {outValue :: Value}
  deriving (Show, Generic)

管道可能类似于:

wsConduit =
      mapMC checkTokenExists
        .| takeWhileC
          ( \case
              PoisonPill -> False
              otherwise -> True
          )

管道只是身份验证后的回应。checkTokenExists只是第一条消息所需要的,实际上它阻塞了所有的InMessage,所以我不能把它留在那里。
我可以在checkTokenExists中有一些状态,让InMessage在授权后通过,但对我来说,似乎最好的方法是用filterC完全取代mapMC checkTokenExists,只是让应用程序消息进入。
如何根据流入的单个元素动态更改管道流的形状?

krugob8w

krugob8w1#

“根据输入改变程序的形状”= Monad。因此,ConduitT是一个Monad,具有操作awaityield。只需说出你的意思:

checkTokenExists :: MonadIO m => WSInput -> m Bool

-- should be along the lines of
wsConduit = do
  auth <- checkTokenExists <$> await
  if auth then forever $ await >>= yield
          else yield PoisonPill

相关问题