2016-07-05 12 views
3

Mit Wiedergabe 2.5.3 ich diesen Filter eingerichtet haben:Wie füge ich Filter für WebSocket-Anfragen im Play-Framework

@Singleton 
class Filters @Inject() (
    env: Environment, 
    postRequestLoggingFilter: PostRequestLoggingFilter) extends HttpFilters { 
    override val filters = { 
     Seq(postRequestLoggingFilter) 
    } 
} 

Dies funktioniert gut für normale HTTP-Web-Anfragen, aber löst nicht für eine WebSocket Route (ws: //) wie:

class Controller3 @Inject() (implicit system: ActorSystem, materializer: Materializer) extends play.api.mvc.Controller { 
    def socket = WebSocket.acceptOrResult[String, String] { request => 
     ... 

wie kann ich diese Route Typ in meinem Filter enthalten oder gibt es einen anderen Mechanismus für diese Art der Anfrage abfängt?

Antwort

2

Nachdem wir einige Zeit damit verbracht haben, die Funktionsweise des Filtersystems zu untersuchen, eignet es sich nicht gut für WebSocket-Anfragen.

Das Problem ist, dass Filter arbeiten mit einer Methode apply ein

nextFilter: RequestHeader => Future[Result] 

nehmen, wo als WebSocket Funktionen übernehmen eine

f: RequestHeader => Future[Either[Result, Flow[In, Out, _]]] 

das WebSocket führen durch das Filtersystem So vorbei wirklich funktioniert nicht .

Aber für meinen Fall interessierte mich in erster Linie der Logging-Filter. Um dieses Problem zu umgehen ich eine benutzerdefinierte Version von acceptOrResult wie folgt erstellt:

def acceptOrResult[TIn, TOut](f: RequestHeader => Future[Either[Result, Flow[TIn, TOut, _]]])(implicit transformer: MessageFlowTransformer[TIn, TOut], materializer: Materializer, ec: ExecutionContext): WebSocket = { 
    WebSocket { request => 
     f(request).map { fResult => 
      PostRequestLoggingFilter.apply(request,fResult.left.getOrElse(Ok)) 
      fResult.right.map(transformer.transform) 
     } 
    } 
} 

Ich brauchte die Logik aus den PostRequestLoggingFilter in es Begleitobjekt der Anwendung Methode zu brechen, so dass die oben funktionieren könnte.

Wenn die WebSocket Anfrage ist Left, haben wir eine Result; Wenn es Right ist, dann passiere ich einfach ein Ok Ergebnis. Dies kann auf andere Filter angewendet werden, solange Sie nichts dagegen haben, dass die WebSocket-Anfrage nach ausgeführt wird.