2017-04-22 1 views
0

Je suis nouveau sur Play Framework et Scala. J'essayais d'écrire le téléchargement de fichiers en utilisant des websockets en jeu. J'ai compris que cela peut être fait en utilisant ByteString. Mais le problème auquel je suis confronté est que je ne suis pas capable de garder les messages de réponse comme String.Websocket pour gérer ByteString et String in Play 2.5

def upload = WebSocket.accept[ByteString, String] { request => 
    ActorFlow.actorRef(out => UploadActor.props(out)) 
} 

L'exception me fais est la suivante,

play.sbt.PlayExceptions$CompilationException: Compilation error[could not find implicit value for parameter transformer: play.api.mvc.WebSocket.MessageFlowTransformer[akka.util.ByteString,String]] 
    at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) 
    at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) 
    at scala.Option.map(Option.scala:145) 
    at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:49) 
    at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:44) 
    at scala.Option.map(Option.scala:145) 
    at play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:44) 
    at play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:40) 
    at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) 
    at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) 

L'acteur de gérer la websocket se présente comme suit,

class UploadActor(out: ActorRef) extends Actor{ 
    out ! "Hello" 

    def receive = { 
    case msg: ByteString => { 
     val p = new PrintWriter(new File("/tmp/newFile.mp4")) 
     p.print(msg.asByteBuffer) 
     p.flush() 
     out ! "file received" 
    } 
    case msg: String => out ! ("Got it "+ msg) 
    } 
} 

Répondre

1

play framework soutien WebSocket repose sur les flux Akka et représente donc une flux de messages WebSocket générique en tant que Flow de type Message à Message. Toute autre combinaison de paramètres d'entrée et de sortie doit être fournie implicitement en tant que MessageFlowTransformer[In, Out].

Maintenant, quelques transformateurs sont fournis par Playframework - par ex. Pour obtenir la liste complète, consultez le source code.

Si vous voulez ByteString à String, vous devez fournir votre propre transformateur dans la portée. Il ressemblerait à ce qui suit:

implicit val byteStringToStringMessageFlowTransformer: MessageFlowTransformer[ByteString, String] = { 
     new MessageFlowTransformer[ByteString, String] { 
     def transform(flow: Flow[ByteString, String, _]) = { 
      AkkaStreams.bypassWith[Message, ByteString, Message](Flow[Message] collect { 
      case BinaryMessage(data) => Left(data) 
      case TextMessage(_) => 
       Right(CloseMessage(
       Some(CloseCodes.Unacceptable), 
       "This WebSocket only supports binary frames")) 
      })(flow map TextMessage.apply) 
     } 
     } 
    } 

Plus d'informations dans le docs.

+0

J'ai placé le code donné dans le contrôleur, mais c'est toujours la même exception. – vinnu313