Estou tendo problemas no Scala Play para conectar Conncurrent.broadcast
com EventSource()
para criar um bate-papo SSE funcional.
Este código abaixo não está funcionando.Tudo o que vejo são mensagens de depuração quando os usuários estão se conectando ao feed e isso é tudo. Nenhum dado está sendo enviado para os navegadores. E tenho certeza de que os dados foram enviados com sucesso para o servidor e enviados para chatChannel. O que há de errado? Como posso depurar isso?
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")
}
Este código de depuração simples abaixo está funcionando e vejo os dados enviados do navegador, por meio chatChannel
, no console, então esse lado está funcionando bem.
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
}
E isso também está funcionando, e vejo strings aleatórias sendo enviadas ao navegador. Então a parte JS também está 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")
}
E de alguma forma, quando eu conecto essas duas partes, as mensagens não são transmitidas para o navegador.
Respostas:
1 para resposta № 1Uau ! Eu estava pronto para desistir, mas descobri a origem do problema.
No routes
arquivo, você usa o roteador de dependência injetada:
GET / @controllers.Application.index
POST /message @controllers.Application.postMessage
GET /feed @controllers.Application.chatFeed
Usando o roteador estático (sem @
e o roteador padrão) funciona no seu exemplo:
GET / @controllers.Application.index
POST /message controllers.Application.postMessage
GET /feed controllers.Application.chatFeed
De jogar doc:
O Play suporta a geração de dois tipos de roteadores,um é uma dependência roteador injetado, o outro é um roteador estático. O padrão é o roteador estático, mas se você criou um novo aplicativo Play usando o Jogue os modelos do ativador de sementes, seu projeto incluirá o seguinte configuração em build.sbt dizendo-lhe para usar o roteador injetado:
routesGenerator: = InjectedRoutesGenerator
Os exemplos de código na documentação do Play pressupõemque você está usando o gerador de rotas injetadas. Se você não estiver usando isso, você pode adaptar trivialmente os exemplos de código para o gerador de rotas estáticas, prefixando a parte de invocação do controlador da rota com um símbolo @, ou declarando cada um de seus controladores como um objeto em vez de uma aula.
Eu ainda não entendi muito bem a última frase já que o controlador não parece usar o gerador de rotas injetadas e, portanto, ter um @
deve usar o roteador estático