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!
Parabéns pelos artigos. Deu-me uma enorme ajuda.
ResponderExcluirSó 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];
}
Realmente, acabou me escapando, vlw pela correção ^^
ExcluirEm qual classe eu coloco esse code??
ResponderExcluirNa classe de conexão.
ExcluirEsse codigo é para tratar as mensagens que chegam e que enviam.