Purescript 铝热剂和 websockets
Purescript thermite and websockets
我正在尝试使用 purescript-thermite 构建一个使用 websockets 的应用程序。这个想法是应用程序使用 websockets 连接到某个服务器并实时更新 HTML 页面。但是,我找不到将其连接到铝热剂工作流程的方法。
我有一个由 render
和 performAction
组成的 spec
。 render
可以访问 dispatch
函数。但是,我需要在渲染元素之前启动 websockets(我可能会把它放到 main
中),但是在消息到达时我需要从外部 dispatch
向组件发送一个事件.最好的方法是什么?
期望您呈现您的组件,获取驱动函数的句柄,然后设置您的 websocket 连接并使用驱动函数提供更新。
但是,如果您出于某种原因需要首先设置 websocket 连接,那么您将需要使用一些技巧,可能涉及 Ref
以在设置完成后保持驱动程序功能。这样,您需要手动验证在 Ref
更新之前您没有尝试调用驱动程序函数。
一个更高级的解决方案可能是以协同程序的形式包装您的 websocket 协议(参见 purescript-coroutines),并在类型中显式表示任何设置阶段:
type Connection =
Aff MyEffects { initialData :: InitialData
, updateStream :: Producer (Aff MyEffects) UpdateMessage
}
此处,InitialData
代表您在设置时收到的数据,可能会传递给组件,UpdateMessage
代表您从服务器增量更新,这将传递给驱动程序功能。然后,您可以将所有这些连接起来 main
.
我不确定这是否不是 'right' 方式,但它确实有效。为了访问 websocket 连接,我必须将其放入状态。为了初始化它,我将它放入 componentWillMount 函数中。所以初始化看起来像这样:
type State = {
conn :: Maybe Connection
}
main :: Eff (...) Unit
main = do
let rspec = T.createReactSpec spec initialState
let component = React.createClass $ rspec.spec {componentWillMount=mountInit rspec.dispatcher}
mountInit :: forall props eff.
(ReactThis props State -> Action ->
Eff (... | eff) Unit)
-> ReactThis props State
-> Eff (... | eff) Unit
mountInit dispatch this = do
let handlers = {
connected: log "Service connected"
, disconnected: log "Disconnected"
, handle: \msg -> dispatch this (WebsockMsg msg)
}
conn <- createConnection "ws://localhost:3000/websock/webclient" handlers
void $ transformState this (\s -> s{conn= Just conn})
我正在尝试使用 purescript-thermite 构建一个使用 websockets 的应用程序。这个想法是应用程序使用 websockets 连接到某个服务器并实时更新 HTML 页面。但是,我找不到将其连接到铝热剂工作流程的方法。
我有一个由 render
和 performAction
组成的 spec
。 render
可以访问 dispatch
函数。但是,我需要在渲染元素之前启动 websockets(我可能会把它放到 main
中),但是在消息到达时我需要从外部 dispatch
向组件发送一个事件.最好的方法是什么?
期望您呈现您的组件,获取驱动函数的句柄,然后设置您的 websocket 连接并使用驱动函数提供更新。
但是,如果您出于某种原因需要首先设置 websocket 连接,那么您将需要使用一些技巧,可能涉及 Ref
以在设置完成后保持驱动程序功能。这样,您需要手动验证在 Ref
更新之前您没有尝试调用驱动程序函数。
一个更高级的解决方案可能是以协同程序的形式包装您的 websocket 协议(参见 purescript-coroutines),并在类型中显式表示任何设置阶段:
type Connection =
Aff MyEffects { initialData :: InitialData
, updateStream :: Producer (Aff MyEffects) UpdateMessage
}
此处,InitialData
代表您在设置时收到的数据,可能会传递给组件,UpdateMessage
代表您从服务器增量更新,这将传递给驱动程序功能。然后,您可以将所有这些连接起来 main
.
我不确定这是否不是 'right' 方式,但它确实有效。为了访问 websocket 连接,我必须将其放入状态。为了初始化它,我将它放入 componentWillMount 函数中。所以初始化看起来像这样:
type State = {
conn :: Maybe Connection
}
main :: Eff (...) Unit
main = do
let rspec = T.createReactSpec spec initialState
let component = React.createClass $ rspec.spec {componentWillMount=mountInit rspec.dispatcher}
mountInit :: forall props eff.
(ReactThis props State -> Action ->
Eff (... | eff) Unit)
-> ReactThis props State
-> Eff (... | eff) Unit
mountInit dispatch this = do
let handlers = {
connected: log "Service connected"
, disconnected: log "Disconnected"
, handle: \msg -> dispatch this (WebsockMsg msg)
}
conn <- createConnection "ws://localhost:3000/websock/webclient" handlers
void $ transformState this (\s -> s{conn= Just conn})