我和Elm和WebRTC一起玩,所以我做了一个监听端口,接收来自js的一些消息:
type alias Message =
{ channel : String
, data : String
}
port listen : (Message -> msg) -> Sub msg现在,我希望能够将消息划分到我的应用程序的不同部分。例如,聊天使用“聊天”通道,而游戏逻辑使用“游戏”。
是否有可能创建一个listenTo String订阅来过滤具有正确通道的消息(只返回数据)?或者是另一种方式?
更新:
我现在拥有的是这样的东西:
在我的main.elm中,我有一个如下所示的更新。它可以接收消息(来自rtc)本身,并发送消息给它聊天。(我后来也添加了一个"ForGame“)
type Msg = Received WebRTC.Message | ForChat Chat.Msg
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Received message ->
let
_ = Debug.log ("Received message on \"" ++ message.channel ++ "\": " ++ message.data)
in
( model
, Cmd.none
)
ForChat msg ->
let
(chatModel, chatCmd) = Chat.update msg model.chat
in
({ model | chat = chatModel}, Cmd.map ForChat chatCmd)然后,我有将所有订阅组合在一起的订阅:
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ WebRTC.listen Received
, Sub.map ForChat <| Chat.subscriptions model.chat
]在Chat.elm中,我有一个类似的结构,有一个处理它的消息的更新。聊天的订阅侦听来自WebRTC的所有消息,但只过滤那些有频道聊天的消息:
subscriptions : Model -> Sub Msg
subscriptions model = WebRTC.listen forChatMessages
forChatMessages : WebRTC.Message -> Msg
forChatMessages webrtcMessage =
if webrtcMessage.channel == "chat"
then
let
message = decodeMessage webrtcMessage.data
in
case message of
Ok msg -> Receive msg
Err error -> Debug.log ("Received unreadable message on chat channel \"" ++ toString webrtcMessage.data ++ "\" with error \"" ++ error ++ "\"") Ignore
else
Ignore(忽略是用于聊天的Msg,它不做任何case msg of Ignore -> (model, Cmd.none)。decodeMessage使用解码器来解码消息decodeMessage : String -> Result String Message。)
我对此非常满意,因为这样聊天的所有逻辑都在Chat.elm中。因此,main.elm不需要知道聊天使用的是什么频道。Chat只是遵循标准结构(Msg、更新、查看、订阅)和main转发所有内容。
唯一不太好的地方是,在Chat.elm中,我有forChatMessages函数。用于:subscriptions model = WebRTC.listen forChatMessages.我想让它更易于再利用,这样它就会变成这样:
subscriptions model = WebRTC.listen for "chat" decodeMessage Receive Ignore然后,它将被游戏重用:
subscriptions model = WebRTC.listen for "game" decodeGameInfo UpdateInfo Ignore更新2:
我设法将forChatMessages函数概括为:
for : String -> (String -> Result String d) -> (d -> msg) -> msg -> Message -> msg
for channel decoder good bad webrtcMessage =
if
webrtcMessage.channel == channel
then
let
decoded = decoder webrtcMessage.data
in
case decoded of
Ok data -> good data
Err error -> Debug.log ("Failed decoding message on " ++ channel ++ "channel \"" ++ toString webrtcMessage.data ++ "\" with error \"" ++ error ++ "\"") bad
else
bad所以我想我自己找到了解决办法。除非有人对此有意见。也许有一种更清洁/更好/更好的方法来做同样的事情?
发布于 2017-01-06 13:16:44
我自己找到了一个解决方案,并把它添加到了原来的问题中。
为了清晰起见,这是一个简短的版本:
在我的main.elm:
type Msg = Received WebRTC.Message | ForChat Chat.Msg
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Received message ->
let
_ = Debug.log ("Received message on \"" ++ message.channel ++ "\": " ++ message.data)
in
( model
, Cmd.none
)
ForChat msg ->
let
(chatModel, chatCmd) = Chat.update msg model.chat
in
({ model | chat = chatModel}, Cmd.map ForChat chatCmd)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ WebRTC.listen Received
, Sub.map ForChat <| Chat.subscriptions model.chat
]在Chat.elm中:
subscriptions : Model -> Sub Msg
subscriptions model = WebRTC.listen <| for "game" decodeGameInfo UpdateInfo Ignore在WebRTC.elm中:
type alias Message =
{ channel : String
, data : String
}
port listen : (Message -> msg) -> Sub msg
for : String -> (String -> Result String d) -> (d -> msg) -> msg -> Message -> msg
for channel decoder good bad webrtcMessage =
if
webrtcMessage.channel == channel
then
let
decoded = decoder webrtcMessage.data
in
case decoded of
Ok data -> good data
Err error -> Debug.log ("Failed decoding message on " ++ channel ++ "channel \"" ++ toString webrtcMessage.data ++ "\" with error \"" ++ error ++ "\"") bad
else
bad发布于 2016-12-31 20:12:03
假设您有以下Msg定义:
type Msg
= Listen Message
| GameChannel String
| ChatChannel String然后,update函数可以对channel值进行操作,并使用正确的通道再次调用update,忽略除"game"和"chat"以外的所有channel值。
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Listen message ->
case message.channel of
"game" ->
update (GameChannel message.data) model
"chat" ->
update (ChatChannel message.data) model
_ ->
model ! []
GameChannel data ->
...
ChatChannel data ->
...您的订阅功能如下所示:
subscriptions : Model -> Sub Msg
subscriptions model =
listen Listenhttps://stackoverflow.com/questions/41409662
复制相似问题