Comunicaciones

Infraestructura para comunicaciones:

  1. Peticiones: http, https
  2. Conexión vía Sockets TCP
  3. Consumo de servicios SOAP, WCF y REST
  4. Obtención de datos a través de frameworks como WCF RIA Service, WCF data Service

Todas las comunicaciones son ASÍNCRONAS.

HTTP GET

Para poder realizar peticiones con éste protocolo se utilizan 2 opciones:

  1. La clase WebClient
  2. La clase HttpWebRequest y HttpWebResponse

WebClient

Nos permite enviar y recibir datos a un Uri. Sus métodos no bloquean el hilo de ejecución.

Los miembros más destacables:

  • DownloadStringAsync: método que descarga el Uri especificado en forma de string (http get)
  • OpenReadAsync: método que abre una Uri en forma de Stream para su lectura (http get)
  • CancelAsync: método que cancela una operación asíncrona.
  • BaseAddres: propiedad donde se establece un Uri base para las peticiones que se realicen con la clase WebClient
  • DownloadProgressChanged: evento que se dispara cuando la carga ha cambiado su progreso.

Normalmente cada método xxxAsync tendrá su correspondiente evento xxxCompleted, el cual se dispara cuando la ejecución de dicho método asíncrono haya finalizado. Por lo tanto deberemos crear un manejador para los eventos «Completed«.

Ejemplo con DownloadStringAsync.

Primero hacemos el manejador del Completed:

WebClient client = new WebClient();
client.DownloadStringCompleted += (s,a) => {
  // comprobamos que no haya errores ni se haya cancelado la operación
  if (a.Error == null && !a.Cancelled) {
    var result = a.result;
    textBlock1.Text = result;
  }
};

client.DownloadStringAsync(new Uri("readme.txt",UriKind.Relative));

Ejemplo con OpenReadAsync, donde abrimos un Stream de lectura a una imagen JPG:

WebClient client = new WebClient ();
client.OpenReadCompleted += (s,a) => {
  if (a.Error == null && !a.Cancelled) {
    using (Stream stream = a.result) {
      BitmapImage bmp = new BitmapImage();
      bmp.SetSource(stream);
      image1.Source = bmp;
    }
  }
};
client.OpenReadAsync(new Uri("foto.jpg",UriKind.Relative));

Ejemplo DownloadProgressChanged

WebClient client = new WebClient();
client.DownloadProgressChanged += (s,a) => {
  progressbar1.Value = a.ProgressPercentage;
  txtBytesrecibidos.text = a.BytesReceived.ToString();
  txtBytesTotales.Text = a.TotalBytesToReceive.ToString();
}

HttpWebRequest y HttpWebResponse

También se puede realizar una petición GET con HttpWebRequest. Veamos como se descagaría una imagen JPG con esta clase.

BitmapImage bmp= new BitmapImage();
Httpwebrequest request = HttpWebRequest.CreateHttp(new Uri("http://localhost:16563/ClientBin/foto.jpg",UriKind.Absolute));
request.Method = "GET";
request.AllowReadStreamBuffering = true;
request.BeginGetResponse((callback) => {
  var response = request.EndGetResponse(callback) as HttpWebResponse;
  var stream = response.GetResponseStream();
  Dispatcher.BeginInvoke(()=> {
    bmp.SetSource(stream);
    image1.Source=bmp;
  });
},null);

HTTP POST

Con la clase WebClient tenemos las siguientes propiedades y métodos:

  • UploadStringAsync: método, sube una cadena hacia el Uri especificado en el parámetro.
  • OpenWriteAsync: método, abre un Stream de escritura en el Uri especificado en el parámetro.
  • CancelAsync: método, cancela una operación asíncrona.
  • BaseAddress: propiedad, establece un Uri base para las peticiones que se realicen con la clase webClient
  • UploadProgressChanged: evento, se dispara cuando el proceso de subida de datos ha cambiado su progreso.

UploadStringAsync

public void ProcessRequest(HttpContext context) {
  string cadena = string.Empty;
  using (StreamReader reader = new StreamReader(context.request.InputStream)) {
    cadena = reader.ReadToEnd();
    reader.Close();
  }
  context.Response.ContentType = "text/plain";
  context.Response.Write("Se ha recibido la cadena: "+ cadena);
}

 

WebClient client = new WebClient();
client.UploadstringCompleted += (s,a) => {
  if (a.Error == null && !a.Cancelled) {
    MessageBox.Show(a.Result);
  }
};
client.UploadStringAsync(new Uri("/handler.ashx",UriKind.Relative), textBox1.Text);

OpenWriteAsync

Nos permmite abrir un stream para escritura en el Uri indicado en el parámetro. Cuando el método ha finalizado de abrir el stream para escritura, se disparará el evento OpenWriteCompleted.

WebClient client = new webClient();
client.OpenWriteCompleted += (s,a) => {
  if (a.Error == null && !a.Cancelled) {
    using (Stream stream = a.Result) {
      using (StreamWriter writer = new StreamWriter(stream)) {
        writer.WriteLine(textBox1.text);
        writer.Close();
      }
      stream.Close();
    }
  }
};
client.OpenWriteAsync(new Uri("/handler.ashx",UriKind.Relative));