如何使用 play framework websocket 创建新的聊天室?
How to create new chat room with play framework websocket?
我在 play framework 2.6.x 中尝试了使用 websocket 的聊天示例。它工作正常。现在对于真正的应用程序,我需要根据用户请求创建多个聊天室。用户将能够使用 id 或其他内容访问不同的聊天室。我认为这可能与为每个房间创建新流程有关。相关代码在这里:
private val (chatSink, chatSource) = {
val source = MergeHub.source[WSMessage]
.log("source")
.map { msg =>
try {
val json = Json.parse(msg)
inputSanitizer.sanText((json \ "msg").as[String])
} catch {
case e: Exception => println(">>" + msg)
"Malfunction client"
}
}
.recoverWithRetries(-1, { case _: Exception ⇒ Source.empty })
val sink = BroadcastHub.sink[WSMessage]
source.toMat(sink)(Keep.both).run()
}
private val userFlow: Flow[WSMessage, WSMessage, _] = {
Flow.fromSinkAndSource(chatSink, chatSource)
}
但我真的不知道如何使用 id 创建新流并在以后访问它。谁能帮我解决这个问题?
我终于明白了。 Post 这里的解决方案,以防有人遇到类似问题。
我的解决方案是使用 AsyncCacheApi
将 Flow
与密钥一起存储在缓存中。必要时生成一个新的 Flow
而不是只创建一个 Sink 和 Source:
val chatRoom = cache.get[Flow[WSMessage, WSMessage, _]](s"id=$id")
chatRoom.map{room=>
val flow = if(room.nonEmpty) room.get else createNewFlow
cache.set(s"id=$id", flow)
Right(flow)
}
def createNewFlow: Flow[WSMessage, WSMessage, _] = {
val (chatSink, chatSource) = {
val source = MergeHub.source[WSMessage]
.map { msg =>
try {
inputSanitizer.sanitize(msg)
} catch {
case e: Exception => println(">>" + msg)
"Malfunction client"
}
}
.recoverWithRetries(-1, { case _: Exception ⇒ Source.empty })
val sink = BroadcastHub.sink[WSMessage]
source.toMat(sink)(Keep.both).run()
}
Flow.fromSinkAndSource(chatSink, chatSource)
}
我在 play framework 2.6.x 中尝试了使用 websocket 的聊天示例。它工作正常。现在对于真正的应用程序,我需要根据用户请求创建多个聊天室。用户将能够使用 id 或其他内容访问不同的聊天室。我认为这可能与为每个房间创建新流程有关。相关代码在这里:
private val (chatSink, chatSource) = {
val source = MergeHub.source[WSMessage]
.log("source")
.map { msg =>
try {
val json = Json.parse(msg)
inputSanitizer.sanText((json \ "msg").as[String])
} catch {
case e: Exception => println(">>" + msg)
"Malfunction client"
}
}
.recoverWithRetries(-1, { case _: Exception ⇒ Source.empty })
val sink = BroadcastHub.sink[WSMessage]
source.toMat(sink)(Keep.both).run()
}
private val userFlow: Flow[WSMessage, WSMessage, _] = {
Flow.fromSinkAndSource(chatSink, chatSource)
}
但我真的不知道如何使用 id 创建新流并在以后访问它。谁能帮我解决这个问题?
我终于明白了。 Post 这里的解决方案,以防有人遇到类似问题。
我的解决方案是使用 AsyncCacheApi
将 Flow
与密钥一起存储在缓存中。必要时生成一个新的 Flow
而不是只创建一个 Sink 和 Source:
val chatRoom = cache.get[Flow[WSMessage, WSMessage, _]](s"id=$id")
chatRoom.map{room=>
val flow = if(room.nonEmpty) room.get else createNewFlow
cache.set(s"id=$id", flow)
Right(flow)
}
def createNewFlow: Flow[WSMessage, WSMessage, _] = {
val (chatSink, chatSource) = {
val source = MergeHub.source[WSMessage]
.map { msg =>
try {
inputSanitizer.sanitize(msg)
} catch {
case e: Exception => println(">>" + msg)
"Malfunction client"
}
}
.recoverWithRetries(-1, { case _: Exception ⇒ Source.empty })
val sink = BroadcastHub.sink[WSMessage]
source.toMat(sink)(Keep.both).run()
}
Flow.fromSinkAndSource(chatSink, chatSource)
}