play2.7x 中的websocket文档少得可怜、看来得适当完善一下子了、这里给大家记录一下一些使用过程吧。
使用
WebController.scala
Singleton
class SocketController @Inject()(cc: ControllerComponents)(implicit system: ActorSystem, ec: ExecutionContext, mat: Materializer)
extends AbstractController(cc) {
implicit val messageFlowTransformer = MessageFlowTransformer.jsonMessageFlowTransformer[JsValue, JsValue]
implicit val format = org.json4s.DefaultFormats
implicit val timeout: Timeout = 11.seconds
def socket = WebSocket.accept[JsValue, JsValue] { request =>
ActorFlow.actorRef { out =>
Props(classOf[WebSocketActor], out)
}
}
}
WebSocketActor.scala
class WebSocketActor(client: ActorRef) extends Actor with ActorLogging {
def receive = {
case msg:JsValue =>
//do something
client ! Json.object(
"code" -> "success"
)
}
}
routes配置
+ nocsrf
GET /socket controllers.SocketController.socket
连接地扯
ws://localhost:9000/socket
重点
解析方式
implicit val messageFlowTransformer = MessageFlowTransformer.jsonMessageFlowTransformer[JsValue, JsValue]
里面还有4种解析规则
jsonMessageFlowTransformer //输入输出都是json数据
byteArrayMessageFlowTransformer //输入输出都是二进制数据
byteStringMessageFlowTransformer //输入输出都是ByteStrings的进制数据
stringMessageFlowTransformer //普通字符串消息
如果不满足自己的需求(定义安排上)
比如我需要输入的消息是json、但输出的数据是gzip压缩后的数据格式
implicit val jsonMessageFlowTransformer1: MessageFlowTransformer[JsValue, JsValue] = {
def closeOnException[T](block: => T) =
try {
Left(block)
} catch {
case NonFatal(e) => Right(CloseMessage(Some(CloseCodes.Unacceptable), "Unable to parse json message"))
}
flow: Flow[JsValue, JsValue, _] => {
AkkaStreams.bypassWith[Message, JsValue, Message](Flow[Message].collect {
case BinaryMessage(data) =>
closeOnException(Json.parse(data.iterator.asInputStream))
case TextMessage(text) =>
closeOnException(Json.parse(text))
})(flow.map { json =>
//TODO 输出改造、只要数据是实现了Message的接口即可
BinaryMessage(ByteString.fromString(Json.stringify(json), "utf-8"))
})
}
}