Scala Play:Concurent.broadcast 无法使用 EventSource
Scala Play: Concurent.broadcast not working with EventSource
我在 Scala Play 中遇到问题,无法将 Conncurrent.broadcast
与 EventSource()
连接以创建有效的 SSE 聊天。
下面的代码无效。当用户连接到提要时,我所看到的只是调试消息,仅此而已。没有数据被发送到浏览器。
而且我确定数据已成功发送到服务器并推送到 chatChannel。怎么了?我该如何调试呢?
val (chatOut, chatChannel) = Concurrent.broadcast[JsValue]
def postMessage = Action(parse.json) { req =>
chatChannel.push(req.body)
Ok
}
def chatFeed = Action { req =>
println("User connected to chat: " + req.remoteAddress)
Ok.chunked(chatOut
&> EventSource()
).as("text/event-stream")
}
下面这个简单的调试代码正在运行,我在控制台中看到浏览器通过 chatChannel
发送的数据,所以这边工作正常。
val (chatOut, chatChannel) = Concurrent.broadcast[JsValue]
val chatDebug = Iteratee.foreach[JsValue](m => println("Debug: " + m.toString))
chatOut |>>> chatDebug
def postMessage = Action(parse.json) { req =>
chatChannel.push(req.body)
Ok
}
这也有效,我看到随机字符串被发送到浏览器。所以JS部分也OK。
def chatFeed = Action { req =>
val producer = Enumerator.generateM[String](Promise.timeout(Some(Random.nextString(5)),3 second))
Ok.chunked(producer &> EventSource()).as("text/event-stream")
}
不知何故,当我连接这两个部分时,消息不会广播到浏览器。
哇!我准备放弃了,但我找到了问题的根源。
在 routes
文件中,您使用依赖注入路由器:
GET / @controllers.Application.index
POST /message @controllers.Application.postMessage
GET /feed @controllers.Application.chatFeed
使用静态路由器(没有 @
和默认路由器)适用于您的示例:
GET / @controllers.Application.index
POST /message controllers.Application.postMessage
GET /feed controllers.Application.chatFeed
来自play doc:
Play supports generating two types of routers, one is a dependency
injected router, the other is a static router. The default is the
static router, but if you created a new Play application using the
Play seed Activator templates, your project will include the following
configuration in build.sbt telling it to use the injected router:
routesGenerator := InjectedRoutesGenerator
The code samples in Play’s documentation assumes that you are using
the injected routes generator. If you are not using this, you can
trivially adapt the code samples for the static routes generator,
either by prefixing the controller invocation part of the route with
an @ symbol, or by declaring each of your controllers as an object
rather than a class.
我还是不太明白最后一句话,因为控制器似乎没有使用注入路由生成器,因此 @
应该使用静态路由器
我在 Scala Play 中遇到问题,无法将 Conncurrent.broadcast
与 EventSource()
连接以创建有效的 SSE 聊天。
下面的代码无效。当用户连接到提要时,我所看到的只是调试消息,仅此而已。没有数据被发送到浏览器。 而且我确定数据已成功发送到服务器并推送到 chatChannel。怎么了?我该如何调试呢?
val (chatOut, chatChannel) = Concurrent.broadcast[JsValue]
def postMessage = Action(parse.json) { req =>
chatChannel.push(req.body)
Ok
}
def chatFeed = Action { req =>
println("User connected to chat: " + req.remoteAddress)
Ok.chunked(chatOut
&> EventSource()
).as("text/event-stream")
}
下面这个简单的调试代码正在运行,我在控制台中看到浏览器通过 chatChannel
发送的数据,所以这边工作正常。
val (chatOut, chatChannel) = Concurrent.broadcast[JsValue]
val chatDebug = Iteratee.foreach[JsValue](m => println("Debug: " + m.toString))
chatOut |>>> chatDebug
def postMessage = Action(parse.json) { req =>
chatChannel.push(req.body)
Ok
}
这也有效,我看到随机字符串被发送到浏览器。所以JS部分也OK。
def chatFeed = Action { req =>
val producer = Enumerator.generateM[String](Promise.timeout(Some(Random.nextString(5)),3 second))
Ok.chunked(producer &> EventSource()).as("text/event-stream")
}
不知何故,当我连接这两个部分时,消息不会广播到浏览器。
哇!我准备放弃了,但我找到了问题的根源。
在 routes
文件中,您使用依赖注入路由器:
GET / @controllers.Application.index
POST /message @controllers.Application.postMessage
GET /feed @controllers.Application.chatFeed
使用静态路由器(没有 @
和默认路由器)适用于您的示例:
GET / @controllers.Application.index
POST /message controllers.Application.postMessage
GET /feed controllers.Application.chatFeed
来自play doc:
Play supports generating two types of routers, one is a dependency injected router, the other is a static router. The default is the static router, but if you created a new Play application using the Play seed Activator templates, your project will include the following configuration in build.sbt telling it to use the injected router:
routesGenerator := InjectedRoutesGenerator
The code samples in Play’s documentation assumes that you are using the injected routes generator. If you are not using this, you can trivially adapt the code samples for the static routes generator, either by prefixing the controller invocation part of the route with an @ symbol, or by declaring each of your controllers as an object rather than a class.
我还是不太明白最后一句话,因为控制器似乎没有使用注入路由生成器,因此 @
应该使用静态路由器