rest asynchronous f# windows-phone

rest - La POST asincrónica falla en WP7 y F#



asynchronous windows-phone (1)

Deberías poner los bytes en el antes de enviar y usar la salida de entrada de BufferStream

Cuando lo let! read = from.AsyncRead buf let! read = from.AsyncRead buf en F #, bloquea y no regresa hasta que el socket TCP está muerto. ¿Por qué? ¿Y cómo lo arreglo?

Su código:

module StreamUtil open System.IO /// copy from ''from'' stream to ''toStream'' let (|>>) (from : Stream) (toStream : Stream) = let buf = Array.zeroCreate<byte> 1024 let rec doBlock () = async { let! read = from.AsyncRead buf if read <= 0 then toStream.Flush() return () else do! toStream.AsyncWrite(buf, 0, read) return! doBlock () } doBlock ()

Se llama desde este código:

use fs = new FileStream(targPath, FileMode.CreateNew, FileAccess.ReadWrite) do! req.InputStream |>> fs

y se solicitó a través de HTTP con este código del emulador de Windows Phone 7.1:

public void Send() { var b = new UriBuilder(_imageService.BaseUrl) {Path = "/images"}; var req = WebRequest.CreateHttp(b.Uri); req.ContentType = "image/jpeg"; req.Method = "POST"; var imgLen = SelectedImage.ImageStream.Length; req.Headers[HttpRequestHeader.ContentLength] = imgLen.ToString(CultureInfo.InvariantCulture); req.Accept = "application/json"; req.BeginGetRequestStream(RequestReady, new ReqState(req, imgLen)); } void RequestReady(IAsyncResult ar) { var state = (ReqState)ar.AsyncState; var req = state.Request; var reqStream = req.EndGetRequestStream(ar); SmartDispatcher.BeginInvoke(() => { using (var sw = new StreamWriter(reqStream)) using (var br = new BinaryReader(SelectedVoucher.ImageStream)) { var readBytes = br.ReadBytes(state.ImgLen); // tried both 2 sw.Write(readBytes); //sw.Write(Convert.ToBase64String(readBytes)); sw.Flush(); sw.Close(); } req.BeginGetResponse(ResponseReady, req); }); } // WHY IS IT YOU ARE NOT CALLED??? void ResponseReady(IAsyncResult ar) { try { var request = (HttpWebRequest)ar.AsyncState; var response = request.EndGetResponse(ar); SmartDispatcher.BeginInvoke(() => { var rdr = new StreamReader(response.GetResponseStream()); var msg = rdr.ReadToEnd(); var imageLocation = response.Headers["Location"]; Debug.WriteLine(msg); Debug.WriteLine(imageLocation); }); } catch (WebException ex) { Debug.WriteLine(ex.ToString()); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } }

Sin éxito. La devolución de llamada ResponseReady nunca se alcanza.

Mientras tanto, este código funciona excelente:

open System open System.Net.Http // WebAPI nuget let sync aw = Async.RunSynchronously aw let postC<''a> (c : HttpClient) (r : Uri) (cont : HttpContent) = let response = sync <| Async.AwaitTask( c.PostAsync(r, cont) ) let struc:''a = sync <| deserialize<''a> response response, struc let withContent<''a> (fVerb : (HttpClient -> Uri -> HttpContent -> _ * ''a))= let c = new HttpClient() fVerb c [<Test>] let ``POST /images 201 + Location header`` () = let post = withContent<MyImage> postC let bytes = IO.File.ReadAllBytes("sample.jpg") let hash = SHA1.Create().ComputeHash(bytes) |> Convert.ToBase64String let pic = new ByteArrayContent(bytes) pic.Headers.Add("Content-Type", "image/jpeg") pic.Headers.Add("X-SHA1-Hash", hash) let resp, ri = (resource "/images", pic) ||> post resp.StatusCode =? Code.Created ri.sha1 =? hash mustHaveHeaders resp

No pude hacer que Fiddler2 trabaje con WP7.

EDIT: Bienvenido a un yak. Me he mudado a pastos más verdes yo mismo;)