segunda-feira, 19 de setembro de 2011

Tutorial WebSocket (C# e Javascript) - Parte 2

Frames

Todas as mensagens trocadas pelo webSocket, tem um formato bem específico. Como se estivesse encapsulada, para o browser poder reconhecer, o tipo de mensagem, o tamanho do texto, etc.
Esse encapsulamento nas mensagens é chamado de Frames.

Estrutura:
A estrutura dos frames, até que é bem simples, porém toda a estrutura é feita em bits. 1 bit é 1/8 bytes, ou seja, 1 byte é 8 bits. Os bits são binários, e para poder verificar as mensagens e encapsulá-las precisaremos fazer operções bits a bits.
Pela estrutura definida no draft10 os frames serão basicamente:

FIN 1 bit: Significa se existirá mais mensagens, ou se esta é a última mensagem, como não iremos trabalhar com fragmentação, ele sempre será 1.
Os próximos 3 bits serão sempre 0.

Os próximos 4 bits significa o opcode, ou código de operação, que será:

0x0 = 0000, uma continuação de frame.
0x1 = 0001, um frame de texto.
0x2 = 0010, um frame binário.

Como iremos trabalhar com mensagens de texto, nosso primeiro BYTE sempre será = 0x81 (ou 1000 0001 em binário).



O próximo byte é composto por:
1 bit: Indica se está mascarado (ou criptografado) o texto.
7 bits: Indica o tamanho da mensagem. Se o valor for menor que 125, então mostra o tamanho real, se for igual à 126, então os próximos 2 bytes representam o tamanho, se for igual à 127 então os próximos 8 bytes representam o tamanho.

Primeiro vamos ter certeza que está usando uma máscara, para isso iremos verificar se o segundo byte é maior que 0x80 (1000 0000), ou seja, qualquer valor dos outros bits, se o primeiro bit for 1, será sempre maior que 0x80.



Agora vamos pegar o tamanho, primeiro temos que nos livrar do primeiro bit, então vamos fazer a operação AND com 0x7F (0111 1111) o que retornará o valor dos outros 7 bits com um 0 na frente (ignorando o bit de máscara). Agora teremos que fazer a verificação, se for menor ou igual a 125, pegamos o tamanho, se não, pegamos os próximos 2 bytes, e assim por diante. E depois, pegamos os próximos 2 bytes depois do tamanho, que será nossa chave de máscara, e enfim pegamos o resto do byte, desde o último byte de máscara, até o tamanho. O que nos retornará o texto mascarado.

Mascarando e Desmascarando:
Isso é bem simples, segundo o draft, para mascarar a mensagem, precisamos usar o XOR na chave de máscara. E para mascarar um texto (envio) a operação é a mesma.



Enviando uma mensagem:
Os frames da mensagem são iguais para envio e recebimento, então, é só fazer o mesmo processo, com o texto que você quer enviar e funcionará perfeitamente.



Pronto, agora já conseguimos conectar, realizar o handshake, e receber e enviar mensagens. Agora finalizamos toda a parte de websocket, conexão, servidor e client. Agora vocês podem implantar do jeito que vocês preferirem!
Obrigado, e boa sorte!

4 comentários:

  1. Parabéns pelos artigos. Deu-me uma enorme ajuda.

    Só uma pequena correcção:

    if (unmaskText.Length > 126)
    {
    send = new byte[4 + unmaskText.Length];
    }
    else
    {
    // EM VEZ DE:
    //send = new byte[2];
    // COLOCAR:
    send = new byte[2 + unmaskText.Length];
    }

    ResponderExcluir
  2. Respostas
    1. Na classe de conexão.
      Esse codigo é para tratar as mensagens que chegam e que enviam.

      Excluir