2013-03-28 8 views
5

Sto tentando di inviare una richiesta di posta a Pusher api, ma ho problemi a restituire il tipo giusto, ho una mancata corrispondenza di tipo; trovato: scala.concurrent.Future [play.api.libs.ws.Response] richiesto: play.api.libs.ws.Responsedisallineamento di tipo; trovato: scala.concurrent.Future [play.api.libs.ws.Response] richiesto: play.api.libs.ws.Response

def trigger(channel:String, event:String, message:String): ws.Response = { 
val domain = "api.pusherapp.com" 
val url = "/apps/"+appId+"/channels/"+channel+"/events"; 
val body = message 

val params = List( 
    ("auth_key", key), 
    ("auth_timestamp", (new Date().getTime()/1000) toInt), 
    ("auth_version", "1.0"), 
    ("name", event), 
    ("body_md5", md5(body)) 
).sortWith((a,b) => a._1 < b._1).map(o => o._1+"="+URLEncoder.encode(o._2.toString)).mkString("&"); 

    val signature = sha256(List("POST", url, params).mkString("\n"), secret.get); 
    val signatureEncoded = URLEncoder.encode(signature, "UTF-8"); 
    implicit val timeout = Timeout(5 seconds) 
    WS.url("http://"+domain+url+"?"+params+"&auth_signature="+signatureEncoded).post(body 
} 

risposta

4

La richiesta stai facendo con post è asincrono. Quella chiamata ritorna immediatamente, ma non restituisce un oggetto Response. Invece, restituisce un oggetto Future[Response], che conterrà l'oggetto Response una volta completata la richiesta http in modo asincrono.

Se si desidera bloccare l'esecuzione fino a quando la richiesta è stata completata, fare:

val f = Ws.url(...).post(...) 
Await.result(f) 

vedere di più su Futures here.

+0

Nel 99% dei casi non si dovrebbe attendere un Async. Tutti gli strumenti necessari per lavorare con il futuro sono disponibili nel framework. –

+0

Questa non è la soluzione che stai cercando ... –

+0

grazie Marius e Julien, hai ragione, questo causa una risposta di blocco – flubba

3

basta aggiungere un map:

WS.url("http://"+domain+url+"?"+params+"&auth_signature="+signatureEncoded).post(body).map(_) 
+0

grazie per la risposta, si può spiegare il motivo per cui questo funziona? Voglio dire, come viene estratto il valore dal futuro? – flubba

3

Supponendo che non si voglia creare un'app di blocco, il metodo dovrebbe restituire anche un Future[ws.Response]. Lascia che il tuo futuro bolla al Controller dove restituisci uno AsyncResult usando Async { ... } e lascia che Play gestisca il resto.

controller

def webServiceResult = Action { implicit request => 
    Async { 
    // ... your logic 
    trigger(channel, event, message).map { response => 
     // Do something with the response, e.g. convert to Json 
    } 
    } 
} 
+0

Non ho trovato Async {} nella api 2.1: http://www.playframework.com/ documentation/api/2.1.0/scala/index.html # package – flubba

+0

quale libreria devo importare per usare Async? Com'è diverso da AsyncResult? Attualmente importare questi due, che potrebbe essere correlato: 'importazione scala.concurrent._ play.api.libs.concurrent.Execution.Implicits._' importazione grazie – flubba

+0

E 'qui https://github.com/ play framework/PLAY20/blob/master/quadro/src/play/src/main/Scala/play/api/MVC/Results.scala # L669. Importa semplicemente 'play.api.mvc._' –