cod*_*dez 5 scala websocket playframework
我有播放 websockets 动作:
def socket = WebSocket.acceptWithActor[String, Array[Byte]] { request => out =>
Props(new WebSocketInActor(out))
}
Run Code Online (Sandbox Code Playgroud)
通常我需要向浏览器发送大型原始数据数组。但有时我需要发送一些小的字符串数据。在浏览器中,我可以检测到是文本格式的数据还是原始 ArrayBuffer。如果我创建发送字符串的actor,我可以发送字符串消息,如果我创建使用Array[Byte]发送的actor,我可以发送原始数组。这两种情况我都不需要更改客户端代码。那么,如何强制 Play 对一个 out 演员使用两种发送方法?
啊,这些答案是在你在 SO 上发布问题后得出的。查看参考和源代码,我发现有mixedFrame FrameFromatter:https://github.com/playframework/playframework/blob/2.4.x/framework/src/play/src/main/scala/play/api/mvc/ WebSocket.scala#L75
因此,您只需说您将使用 Either[String, Array[Byte]] 进行响应,如果您想发送字符串,请使用 Left(somestring) 或使用 Right[somearray]。
class WebSocketInActor(out: ActorRef) extends Actor {
override def preStart() = {
println("User connected")
val s = "Hello"
out ! Left(s)
out ! Right(s.getBytes("utf8"))
}
override def postStop() = {
println("User discconnected")
}
def receive = {
case msg: String => {
}
case _ =>
}
}
def socket = WebSocket.acceptWithActor[String, Either[String, Array[Byte]]] { request => out =>
Props(new WebSocketInActor(out))
}
Run Code Online (Sandbox Code Playgroud)
更新:
或者您可以更进一步,创建您自己的帧格式化程序
sealed trait WSMessage
case class StringMessage(s: String) extends WSMessage
case class BinaryMessage(a: Array[Byte]) extends WSMessage
case class JsonMessage(js: JsValue) extends WSMessage
implicit object myFrameFormatter extends BasicFrameFormatter[WSMessage] {
private val textFrameClass = classOf[TextFrame]
private val binaryFrameClass = classOf[BinaryFrame]
def toFrame(message: WSMessage): BasicFrame = message match {
case StringMessage(s) => TextFrame(s)
case BinaryMessage(a) => BinaryFrame(a)
case JsonMessage(js) => TextFrame(Json.stringify(js))
}
def fromFrame(frame: BasicFrame): WSMessage = frame match {
case TextFrame(s) => StringMessage(s)
case BinaryFrame(a) => BinaryMessage(a)
}
def fromFrameDefined(clazz: Class[_]): Boolean = clazz match {
case `textFrameClass` => true
case `binaryFrameClass` => true
case _ => false // shouldn't be reachable
}
}
class WebSocketInActor(out: ActorRef) extends Actor {
override def preStart() = {
println("User connected")
val s = "Hello"
val a:Array[Byte] = Array(100, 50, 30).map(_.toByte)
out ! StringMessage(s)
out ! JsonMessage(Json.obj("txt" -> s, "array" -> a))
out ! BinaryMessage(a)
}
override def postStop() = {
println("User discconnected")
}
def receive = {
case msg: String => {
}
case _ =>
}
}
def socket = WebSocket.acceptWithActor[String, WSMessage] { request => out =>
Props(new WebSocketInActor(out))
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
492 次 |
| 最近记录: |