1 IMPLEMENTAÇÃO E ANÁLISE DA UTILIZAÇÃO DE WEBSOCKETS EM SISTEMAS COMPUTACIONAIS Thiago Daniel R. Varela Orientador: Stanley Loh Universidade Luterana do Brasil (ULBRA) – Ciência da Computação Canoas – RS – Brasil thiagodrv AT gmail.com, loh AT ulbra.br RESUMO As transformações sofridas pela web, que a tornaram uma plataforma para aplicações distribuídas e altamente dinâmicas, obrigaram o surgimento de alternativas ao padrão de simples requisição/resposta do HTTP. A mais amplamente utilizada nos dias de hoje é um conjunto de tecnologias que, quando empregadas simultaneamente e com este propósito, recebem o nome de AJAX. Entretanto, mesmo esta solução representa apenas um passo na evolução da web, pois apresenta limitações já que, em última análise, ainda se baseia no modelo de requisição/resposta. Neste contexto, surge o Websocket, um novo padrão que possibilita comunicações de duas vias reais e de maneira eficiente, através de um protocolo de encapsulamento simples, de modo a proporcionar a interatividade e dinamismo que a web atual exige além da eficiência na utilização dos recursos computacionais, que é uma necessidade diante do número cada vez mais crescente de usuários. Este artigo propõe a implementação de bibliotecas implementado o protocolo, de maneira que possam ser utilizadas para a construção de novas aplicações utilizando a tecnologia de Websockets. Palavras-chave: websocket, web, http, ajax, interatividade, web dinâmica 1 INTRODUÇÃO A web sofreu grandes mudanças em seu padrão de utilização desde que foi criada, especialmente na última década. Inicialmente utilizada para transferir simples páginas estáticas compostas principalmente por texto, hoje a web serve de plataforma para sistemas com alta interatividade e cada vez mais dinâmicos. O modelo de comunicação baseado em Requisição/Resposta, sobre o qual a web foi construída, passou a mostrar-se inadequado para este novo paradigma. Em resposta a estas necessidades, surgiram diversas técnicas com o objetivo de simular uma comunicação bidirecional através deste modelo de requisição/resposta, utilizando para isso alguma variação de técnicas de polling. Entretanto, por possuírem natureza não disruptiva, estas soluções não puderam resolver a causa do problema, apenas trabalharam para contorná-lo criando mecanismos que operassem sobre a tecnologia já existente e em utilização, o que faz com que estas soluções percam em eficiência e limitem a evolução para sistemas mais interativos e mais dinâmicos. É neste cenário que surge a proposta do Websocket, um mecanismo para comunicação bidirecional que tenta tornar simples e eficiente esta interação, resolvendo o problema em sua causa mas ao mesmo tempo buscando funcionar juntamente com a estrutura atual. 2 MOTIVAÇÃO Apesar de ser um padrão relativamente novo e ainda em especificação, o Websocket já possui um número razoável de implementações funcionais, por exemplo nos navegadores Chrome e diversos outros
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
1
IMPLEMENTAÇÃO E ANÁLISE DA UTILIZAÇÃO DE
WEBSOCKETS EM SISTEMAS
COMPUTACIONAIS
Thiago Daniel R. Varela
Orientador: Stanley Loh
Universidade Luterana do Brasil (ULBRA) – Ciência da Computação
Canoas – RS – Brasil
thiagodrv AT gmail.com, loh AT ulbra.br
RESUMO
As transformações sofridas pela web, que a tornaram uma plataforma para aplicações distribuídas e
altamente dinâmicas, obrigaram o surgimento de alternativas ao padrão de simples requisição/resposta do HTTP.
A mais amplamente utilizada nos dias de hoje é um conjunto de tecnologias que, quando empregadas
simultaneamente e com este propósito, recebem o nome de AJAX. Entretanto, mesmo esta solução representa
apenas um passo na evolução da web, pois apresenta limitações já que, em última análise, ainda se baseia no
modelo de requisição/resposta. Neste contexto, surge o Websocket, um novo padrão que possibilita
comunicações de duas vias reais e de maneira eficiente, através de um protocolo de encapsulamento simples, de
modo a proporcionar a interatividade e dinamismo que a web atual exige além da eficiência na utilização dos
recursos computacionais, que é uma necessidade diante do número cada vez mais crescente de usuários. Este
artigo propõe a implementação de bibliotecas implementado o protocolo, de maneira que possam ser utilizadas
para a construção de novas aplicações utilizando a tecnologia de Websockets.
Palavras-chave: websocket, web, http, ajax, interatividade, web dinâmica
1 INTRODUÇÃO
A web sofreu grandes mudanças em seu padrão de utilização desde que foi criada, especialmente
na última década. Inicialmente utilizada para transferir simples páginas estáticas compostas
principalmente por texto, hoje a web serve de plataforma para sistemas com alta interatividade e cada vez
mais dinâmicos. O modelo de comunicação baseado em Requisição/Resposta, sobre o qual a web foi
construída, passou a mostrar-se inadequado para este novo paradigma.
Em resposta a estas necessidades, surgiram diversas técnicas com o objetivo de simular uma
comunicação bidirecional através deste modelo de requisição/resposta, utilizando para isso alguma
variação de técnicas de polling.
Entretanto, por possuírem natureza não disruptiva, estas soluções não puderam resolver a causa
do problema, apenas trabalharam para contorná-lo criando mecanismos que operassem sobre a tecnologia
já existente e em utilização, o que faz com que estas soluções percam em eficiência e limitem a evolução
para sistemas mais interativos e mais dinâmicos.
É neste cenário que surge a proposta do Websocket, um mecanismo para comunicação
bidirecional que tenta tornar simples e eficiente esta interação, resolvendo o problema em sua causa mas
ao mesmo tempo buscando funcionar juntamente com a estrutura atual.
2 MOTIVAÇÃO
Apesar de ser um padrão relativamente novo e ainda em especificação, o Websocket já possui um
número razoável de implementações funcionais, por exemplo nos navegadores Chrome e diversos outros
2
baseados em WebKit. Entretanto, uma segunda utilidade para protocolos Web são os chamados
Webservices, que nada mais é do que a utilização de protocolos e padrões Web para a comunicação entre
dois ou mais sistemas ou programas, ao invés de ser uma interação sistema-usuário (como é na Web).
Este ramo de aplicação ainda carece de implementações práticas do protocolo Websocket, que poderia
trazer grandes benefícios em diversas aplicações com o seu modelo de comunicação bidirecional de
conexão única.
3 OBJETIVOS
Os objetivos que desejam-se atingir com este trabalho são, primariamente, a criação de uma
implementação genérica e funcional do protocolo Websocket, tanto do cliente quanto do servidor, na
forma de bibliotecas independentes, já que hoje as únicas implementações completas do protocolo são
embutidas dentro de grandes sistemas já prontos (como navegadores de internet), o que torna a sua
utilização muito difícil para novos sistemas que queiram tirar proveito desta nova tecnologia, permitindo,
desta forma, a criação, de maneira relativamente simples, de programas e sistemas utilizando este novo
protocolo. Esta implementação será licenciada sob uma licença livre (reconhecida como tal pela OSI –
Open Source Initiative) e permissiva, efetivamente tornando estas bibliotecas um software livre e de
código aberto, de maneira a poder ser utilizado pelo maior número de sistemas possível (comerciais ou
livres), e possibilitando também contribuições que poderão melhorar mais rapidamente a qualidade da
implementação. O objetivo último deste trabalho é a disseminação desta nova tecnologia para que o
maior número possível de pessoas possa se beneficiar dela.
4 REFERENCIAL TEÓRICO
Nas subseções a seguir, descrevem-se as principais tecnologias relacionadas ou abordadas neste
artigo.
4.1 HTTP
O HTTP é o protocolo que serve de base para toda a web. É um protocolo de camada de
aplicação, em uso na World-Wide Web global information initiative desde 1990. É um protocolo sem
estado (stateless), baseado no modelo de Requisição/Resposta. Um cliente estabelece uma conexão com
o servidor e envia uma requisição, que consiste de um método, um URI, e a versão do protocolo,
seguidos possivelmente por modificadores de requisição e informações sobre o cliente. O servidor
responde com uma linha de status, incluindo a versão do protocolo e um código de erro ou sucesso,
seguidos por uma mensagem contendo informações sobre o servidor e o corpo de dados do objeto
requisitado. (Berners-Lee et al, 1996).
A figura 1 mostra um exemplo de uma requisição HTTP em sua forma mínima e sua respectiva
resposta.
4.2 Sistemas Web Dinâmicos
As transformações no padrão de utilização da web na última década, impulsionadas
principalmente pelo surgimento de diversas plataformas cada vez mais dinâmicas e interativas, como
Gmail, Facebook e Orkut (surgidos em 2004), MySpace (criado em 2003) e Twitter (surgido em 2006),
apontam para a transformação da web, de uma simples rede de transferência de documentos estáticos, em
uma verdadeira plataforma para sistemas de larga escala, dinâmicos, sociais e interativos.
Diante deste novo paradigma, as antigas soluções começaram a mostrar-se inadequadas, pois o
modelo de requisição/resposta passou a não mais se enquadrar ao perfil destas novas plataformas, que
requerem um nível cada vez maior de interatividade, além do suporte a um número rapidamente crescente
de usuários.
3
Requisição:
GET /exemplo HTTP/1.0
Resposta:
HTTP/1.0 200
<conteúdo do objeto /exemplo>
Figura 1 – Exemplo de requisição e resposta HTTP
4.3 A Solução Atual para Comunicações Dinâmicas via Web
Com o surgimento desta demanda por maior interatividade, surgiram soluções para tornar a
interação com a web mais dinâmica.
A tecnologia predominantemente empregada nestes casos é algo que se chama de AJAX, que na
verdade não constutui por si uma tecnologia, mas sim várias técnicas diferentes sendo empregadas em
conjunto. Consiste basicamente em criar um motor de renderização da tela (na maioria dos casos em
Javascript), que é quem faz a interação com o usuário, interagindo com o servidor (na maioria dos casos
utilizando XML) assincronamente no plano de fundo. Desta maneira, o usuário não tem mais a
necessidade de ficar aguardando a resposta do servidor após cada requisição, pois o motor de
renderização pode previamente solicitar os recursos necessários, além de possibilitar a atualização de
apenas partes da tela, permitindo que o usuário continue interagindo com parte da aplicação enquanto
outra parte está sendo processada pelo servidor. (Jesse J. Garrett, 2005)
Entretando, este tipo de tecnologia ainda não permite uma comunicação de duas vias real (onde
qualquer um dos lados pode enviar dados quando desejar), pois as comunicações com o servidor ainda
acontecem sobre HTTP, e portanto, o servidor não consegue iniciar um envio de dados, apenas pode
responder a requisições efetuadas pelo cliente. (Coach K. Wei, 2005)
De modo a simular uma comunicação de duas vias, as aplicações cliente frequentemente
utilizam-se de uma técnica denominada polling, que consiste no envio periódico de requisições para o
servidor para permitir que ele envie novas informações, caso existam. Desta maneira, pode-se simular
uma conexão de duas vias já que, do ponto de vista do usuário, novas informações aparecem sem que ele
tenha que explicitamente fazer uma nova requisição por elas. Esta solução, entretanto, não é eficiente em
termos de recursos computacionais, uma vez que serão realizadas inúmeras requisições inúteis, quando o
servidor ainda não tiver novas informações para responder. Também não representa uma via de
comunicação de tempo real, já que quando houver nova informação no servidor, ela só irá mostrar-se
para o usuário depois de decorrido o intervalo até a próxima requisição periódica da aplicação cliente.
Outra técnica também utilizada no propósito de tornar a web mais dinâmica, é um conceito que
recebe o nome de Comet, que engloba um conjunto de soluções que são tecnicamente diferentes mas
conceitualmente semelhantes. Seu princípio de funcionamento baseia-se em efetuar uma requisição
HTTP para o servidor, e, ao receber a resposta, nenhum dos lados encerra a conexão, mantendo-a aberta
para que o servidor possa enviar os eventos subsequentes dentro da mesma conexão, sem precisar
aguardar que o cliente faça uma nova requisição.
Esta técnica é principalmente utilizada em conjunto com as tecnologias que formam o Ajax,
apenas substituindo o mecanismo de polling por este mecanismo de conexão longa.
4
Os mecanismos para a utilização de Comet podem englobar diferentes tecnologias, as principais
são a utilização de um Iframe oculto na página, implicitamente declarado com tamanho infinito, que
ficaria em estado “carregando” indefinidadamente, por onde o servidor enviaria seus dados, ou utilizando
uma técnica denominada long-polling, que consiste em uma variação do conceito de polling, porém cada
requisição efetuada pelo cliente é mantida aberta até que o servidor tenha alguma informação para enviar,
após isto, a conexão é encerrada e o cliente deve estabelecer uma nova conexão. A vantagem neste caso é
que não há requisições desperdiçadas enquanto o servidor não tem novas informações.
Estas soluções, apesar de representarem uma evolução sobre o modelo de polling comum, ainda
apresentam problemas. No caso do Iframe oculto, não existe maneira de saber o estado atual do objeto,
nem existe um método para realizar tratamento de erros, além de ser uma distorção em relação ao
objetivo da utilização de Iframes. A técnica de long-polling ainda requer o estabelecimento de múltiplas
conexões e a troca de cabeçalhos HTTP, portanto perdendo no que tange a eficiência computacional.
(Anthony T. Holdener III, 2008)
4.4 Websocket
O Websocket é um protocolo que provê um canal de comunicação de duas vias entre um agente
de usuário e um host remoto, cujo objetivo é prover um mecanismo para aplicações web que necessitam
de comunicação bidirecional sem ter que depender da abertura de múltiplas conexões HTTP (p. ex.
Usando XMLHttpRequest ou long polling). (Hickson, 2010)
Foi desenvolvido com o princípio de que deve existir apenas um enquadramento (framing)
mínimo, de modo a economizar recursos e simplificar as implementações. É esperado que um
subprotocolo seja utilizado sobre o Websocket pela camada de aplicação, da mesma forma que o HTTP é
utilizado sobre o TCP.
Tecnicamente, o Websocket é apenas uma camada sobre o TCP que adiciona um modelo de
segurança web baseado em origem, um esquema de nomes e endereçamento (para suportar múltiplos
serviços em uma mesma porta e múltiplos nomes de host em um mesmo endereço IP), encapsula um
simples mecanismo de enquadramento e reimplementa o handshake de fechamento. Nada além disto. A
intenção é torná-lo o mais próximo possível do TCP puro, mas levando em conta os requerimentos da
web. Também é desenvolvido de forma tal que, pelo fato de o handshake possuir um cabeçalho HTTP
válido, possa dividir uma mesma mesma porta com servidores HTTP. (Hickson, 2010)
O protocolo consiste de um handshake inicial seguido da tranferência dos dados propriamente
dita.
Caso o handshake tenha sucesso, é inciada a transferência de dados. Sendo este um canal de
comuncação de duas vias, cada lado da conexão pode enviar dados a qualquer momento, diferentemente
do HTTP, onde o servidor não consegue enviar dados para o cliente no momento em que desejar,
precisando aguardar que o cliente faça uma requisição para que só então ele consiga transmitir qualquer
informação para o cliente.
Os dados são transmitidos na forma de texto codificado em UTF-8. Cada quadro (frame) de
dados inicia com um byte 0x00 e termina com um byte 0xFF, contendo o texto UTF-8 no meio. O
Websocket provê este enquadramento para que as implementações do protocolo possam expor tais
conexões utilizando um modelo baseado em eventos, ao invés de requerer a utilização de buffering e
agrupamento manual de mensagens. (Hickson, 2010)
Para encerrar uma conexão, um quadro consistido apenas por um byte 0xFF seguindo por um
byte 0x00 é enviado por um par (peer) para pedir que o outro encerre a conexão. O outro par então envia
um quadro idêntico, que indicando que a conexão pode ser encerrada. (Hickson, 2010)
5
Campos adicionais são usados para selecionar opções do protocolo Websocket. Na versão atual,
os campos adicionais suportados são “Cookie”, que pode ser utilizado para enviar cookies para o servidor
(p. ex. como mecanismo de autenticação) e “Sec-WebSocket-Protocol”, que contém uma string arbitrária
que descreve o subprotocolo (o protocolo da aplicação utilizado sobre o Websocket) que o cliente
pretende utilizar. O servidor ecoa este campo na sua resposta para indicar que ele suporta este
subprotocolo especificado.
Os outros campos do handshake são todos relativos à segurança. O campo “Host” serve como
proteção contra adulteração de DNS e para permitir que múltiplos domínios sejam atendidos em um
mesmo endereço. O campo “Origin” é usado para proteger o servidor contra acesso cruzado não
autorizado. O servidor especifica de qual origem ele está disposto a receber conexões incluindo um
campo “Sec-WebSocket-Origin” informando esta origem. Se múltiplas origens forem aceitas, o servidor
apenas ecoa o valor do campo “Origin” presente na requisição do cliente.
A figura 2 ilustra o funcionamento do handshake enviado pelo cliente:
GET /demo HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Origin: http://exemplo.com
Host: exemplo.com
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Sec-WebSocket-Protocol: teste
^n:ds[4U
Figura 2: handshake Websocket enviado pelo cliente para estabelecer uma conexão com um servidor
Por fim, o servidor deve provar ao cliente que ele recebeu o seu handshake (de maneira a evitar
que um servidor aceite conexões que não são uma conexão Websocket). Para fazê-lo, o servidor deve
pegar três peças de informação e combiná-las para formar uma resposta. As primeiras duas informações
vêm dos campos “Sec-WebSocket-Key1” e “Sec-WebSocket-Key2” do handshake do cliente. Para cada
um destes campos, o servidor deve retirar apenas os números, e então dividir este número formado pelo
número de caracteres de espaço contidos no campo. Estes dois números resultantes são então utilizados
no handshake do servidor. A terceira informação são os últimos 8 bytes do handshake, após todos os
campos. Ela é concatenada com os dois números resultantes obtidos anteriormente, formando uma string
de 128 bits cuja soma MD5 é usada pelo servidor para provar que ele leu o handshake.