サーバントの Server-Sent Event (SSE) エンドポイントを定義するにはどうすればよいですか? ドキュメントはこのケースをカバーしていないようです。
サーバントがリアルタイムのユースケース向けに設計されていない場合、どの Haskell サーバーフレームワークが SSE をサポートしていますか?
servant
を使用し、コンビネータを使用して、通常のアプリケーションとそのために存在するすべてのライブラリWAI
にいつでも浸ることができます。したがって、 fromを使用して、エンドポイントのハンドラーのタイプであるを作成できます。何かのようなもの:WAI
Raw
Network.Wai.EventSource
wai-extra
Application
Raw
type MyApi = "normalapi" :> NormalApi
:<|> "sse" :> Raw
myServer :: Server MyAPI
myServer = normalServer :<|> eventSourceAppChan myChan
ええ、サーバントでのサーバー送信イベントについてはわかりませんが、 Yesodのようなより包括的な Web フレームワークはそれをサポートしています。
パッケージyesod-eventsourceを見てください。
Yesod には非常に優れたクックブックがあるので、そこに非常に優れた例を見つけることができます。
サーヴァントは、定型文を少し加えるだけでこれをうまく処理できます。この場合、新しいコンテンツ タイプ ( EventStream
) と、タイプを SSE 形式にレンダリングするためのサポート クラスが必要です。
{-# LANGUAGE NoImplicitPrelude #-}
module Spencer.Web.Rest.ServerSentEvents where
import RIO
import qualified RIO.ByteString.Lazy as BL
import Servant
import qualified Network.HTTP.Media as M
-- imitate the Servant JSON and OctetStream implementations
data EventStream deriving Typeable
instance Accept EventStream where
contentType _ = "text" M.// "event-stream"
instance ToSSE a => MimeRender EventStream a where
mimeRender _ = toSSE
-- imitate the ToJSON type class
class ToSSE a where
toSSE :: a -> BL.ByteString
-- my custom type with simple SSE render
data Hello = Hello
instance ToSSE Hello where
toSSE _ = "data: hello!\n\n"
-- my simple SSE server
type MyApi = "sse" :> StreamGet NoFraming EventStream (SourceIO Hello)
myServer :: Server MyAPI
myServer = source [Hello, Hello, Hello]
ブラウザの結果:
data: hello!
data: hello!
data: hello!