Skip to content

Latest commit

 

History

History
159 lines (118 loc) · 6.41 KB

File metadata and controls

159 lines (118 loc) · 6.41 KB

8.2 WebSockets

Los WebSockets son una característica importante de HTML5. Esto implementa sockets basados en navegadores, lo que permite a los navegadores tener comunicación en dos vías con los servidores. La mayoría de navegadores populares como Firefox, Chrome y Safari proveen soporte para WebSockets.

Las personas utilizan "roll polling" para los servicios de mensajes instantaneos antes que los WebSockets nacieran, lo que permitía alos clientes enviar peticiones HTTP periódicamente. El servidor entonces retornaba la información mas reciente a los clientes. La desventaja de este método es que requiere que los clientes mantengan enviando muchas conexiones al servidor, lo que consume mucho ancho de banda.

Los WebSockets una un tipo especial de encabezado que reduce el número de apretones de manos requeridos entre el servidor y el cliente, a solo uno, para establecer la conexión. Esta conexión permanecerá activa por todo su tiempo de vida, y puedes usar JavaScript para enviar o recibir información de esta conexión, como en el caso de un socket TCP convencional. Esto resuelve muchos de los dolores de cabeza de las aplicaciones web en tiempo real y le trae las siguientes ventajas al protocolo HTTP:

  • Solo una conexión TCP para un solo cliente web.
  • Los servidores de WebSockets pueden enviar información a los clientes.
  • Los encabezados mas livianos reducen la carga de transmisión de red.

Las URLs de los WebSockets comienzan con un ws:// o un wss://. La siguiente figura muestra el proceso de comunicación de un websocket. Un encabezado particular es enviado al servidor como parte del apretón de manos y la conexión es establecida. Entonces, servidores y cliente son capaces de recibir y enviar información a través del WebSocket

Figura 8.2 Principio de los websockets

Principios de los websockets

El protocolo de websockets es muy fácil. Después de completar el apretón de manos inicial, una conexión es establecida. La comunicación subsecuenta comenzará con un "\x00" y terminará con un "\xFF". Este prefijo y sufijo será visible a los clientes, porque el websocket romperá los datos entre ambos finales, produciendo los datos puros.

Las conexiones por websockets son pedidas por los navegadores y respondidas por los servidores. Después la conexión es establecida. Este proceso se llama "apretón de manos".

Considera las siguientes peticiones y respuestas

Figura 8.3 Peticiones y respuestas de un websocket

"Sec-WebSocket-key" es generada aleatoreamente, como puedes haberlo adivinado, y es codificada a base 64. Los servidores encesitan concatenar esta llave a una cadena después de aceptar una petición:

	258EAFA5-E914-47DA-95CA-C5AB0DC85B11

Supón que tenemos f7cb4ezEAl6C3wRaU6JORA==, Entonces enviamos:

	f7cb4ezEAl6C3wRaU6JORA==258EAFA5-E914-47DA-95CA-C5AB0DC85B11

Usa sha1 para computar el valor binario y luego base 64 para codificarlo. Entonces tendremos:

	rE91AJhfC+6JdVcVXOGJEADEJdQ=

Usa esto como valor en el encabezado de respuesta Sec-WebSocket-Accept.

WebSocket en Go

La librería estándar de Go no provee soporte para WebSockets. Sin embargo el paquete websocket que es un subpaquete de go.net lo es, y es oficialmente mantenido mantenido y soportado.

Usa go get para instalar este paquete:

	go get golang.org/x/net/websocket

Los WebSockets tienen lados de cliente y servidor. Veamos un ejemplo simple de un usuario ingresa alguna información en el lado del cliente y la envía al lado del servidor a través de un WebSocket, seguido por el servidor reenviando la información al cliente.

Lado del cliente:

	<html>
	<head></head>
	<body>
		<script type="text/javascript">
			var sock = null;
			var wsuri = "ws://127.0.0.1:1234";

			window.onload = function() {

				console.log("onload");

				sock = new WebSocket(wsuri);

				sock.onopen = function() {
					console.log("connected to " + wsuri);
				}

				sock.onclose = function(e) {
					console.log("connection closed (" + e.code + ")");
				}

				sock.onmessage = function(e) {
					console.log("message received: " + e.data);
				}
			};

			function send() {
				var msg = document.getElementById('message').value;
				sock.send(msg);
			};
		</script>
		<h1>WebSocket Echo Test</h1>
		<form>
			<p>
				Message: <input id="message" type="text" value="Hello, world!">
			</p>
		</form>
		<button onclick="send();">Send Message</button>
	</body>
	</html>

Como puedes ver, es muy facil utilizar las funciones Javascript del lado del cliente para establecer la conección. El evento onopen es activado después de terminar exitosamente el proceso del apretón de manos. Esto le dice al cliente que la conexión ha sido creada exitosamente. El cliente trata de abrir una conexions usualmente ata estos cuatro eventos:

  • 1)onopen: activado cuando la conexión es establecida.
  • 2)onmessage: activado después de recibir un mensaje.
  • 3)onerror: activado cuando un error ha ocurrido.
  • 4)onclose: activuado cuando la conexión ha sido cerrada.

Código del servidor:

	package main

	import (
		"golang.org/x/net/websocket"
		"fmt"
		"log"
		"net/http"
	)

	func Echo(ws *websocket.Conn) {
		var err error

		for {
			var reply string

			if err = websocket.Message.Receive(ws, &reply); err != nil {
				fmt.Println("Can't receive")
				break
			}

			fmt.Println("Received back from client: " + reply)

			msg := "Received:  " + reply
			fmt.Println("Sending to client: " + msg)

			if err = websocket.Message.Send(ws, msg); err != nil {
				fmt.Println("Can't send")
				break
			}
		}
	}

	func main() {
		http.Handle("/", websocket.Handler(Echo))

		if err := http.ListenAndServe(":1234", nil); err != nil {
			log.Fatal("ListenAndServe:", err)
		}
	}

Cuando un cliente envía la información, el cliente la recive (Receive) y usa un Send para enviar la respuesta.

Figura 8.4 Servidor WebSocket recibiendo información.

A través de el ejemplo de arriba, podemos ver que la implemenación de un cliente y servior WebSocket es muy conveniente. Podemos usar el paquete net directamente en Go. Con el rápido desarrollo de HTML5, pienso que los WebSockets tendrán un rol mucho mas importante en las aplicaciones web modernas; deberíamos ser capaces al menos de estar familiarizados con ellos.

Enlaces