首页 > 解决方案 > Play Framework - 在 Web 套接字响应头中编辑 Sec-WebSocket-Protocol

问题描述

编辑从服务器发送到客户端的 Web 套接字头响应。

我正在使用 playframework 创建一个 websocket 服务器应用程序。现在来自服务器的 websocket 响应由 Play 处理。以下是响应标头,

Request Header:
  (UpgradeToWebSocket,),
  (Host,localhost:8083), 
  (Connection,Upgrade), 
  (Upgrade,websocket),
  (Sec-WebSocket-Version,13), 
  (Accept-Encoding,gzip, deflate, br), 
  (Accept-Language,en-US,en;q=0.9),
  (Sec-WebSocket-Key,ZvfzpVo3EX4DFA4BRcgRIA==)

def chatSystem(): WebSocket = WebSocket.acceptOrResult[String, String] { request =>
    Future.successful{
      AuthenticationService.doBasicAuthentication(request.headers) match {
        case Results.Ok => Right(ActorFlow.actorRef { out => ChatServiceActor.props(out) })
        case _ => Left(Unauthorized)
      }
    }
 }

我想验证Sec-WebSocket-Protocol是否存在于请求标头中,或者如果它不存在,则在服务器响应中添加相同的值。

标签: scalawebsocketplayframeworkakka

解决方案


我使用了以下代码:

// Defined at http://tools.ietf.org/html/rfc6455#section-4.2.2
val MagicGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

def websocketAcceptForKey(key: String): String = {
  val sha1 = MessageDigest.getInstance("sha1")
  val salted = key + MagicGuid
  val hash = sha1.digest(salted.asciiBytes)
  val acceptKey: String = Base64.rfc2045().encodeToString(hash, false)
  acceptKey
}

像下面这样使用它:

val wsKey: Optional[HttpHeader] = request.getHeader("Sec-WebSocket-Key")
val wsAccept = if (wsKey.isPresent) Some(RawHeader("Sec-WebSocket-Accept", websocketAcceptForKey(wsKey.get.value()))) else None

推荐阅读