aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/api/websockets_api/writing_websocket_server/index.html
diff options
context:
space:
mode:
authorFlorian Merz <me@fiji-flo.de>2021-02-11 14:49:58 +0100
committerFlorian Merz <me@fiji-flo.de>2021-02-11 14:49:58 +0100
commit68fc8e96a9629e73469ed457abd955e548ec670c (patch)
tree8529ab9fe63d011f23c7f22ab5a4a1c5563fcaa4 /files/pt-br/web/api/websockets_api/writing_websocket_server/index.html
parent8260a606c143e6b55a467edf017a56bdcd6cba7e (diff)
downloadtranslated-content-68fc8e96a9629e73469ed457abd955e548ec670c.tar.gz
translated-content-68fc8e96a9629e73469ed457abd955e548ec670c.tar.bz2
translated-content-68fc8e96a9629e73469ed457abd955e548ec670c.zip
unslug pt-br: move
Diffstat (limited to 'files/pt-br/web/api/websockets_api/writing_websocket_server/index.html')
-rw-r--r--files/pt-br/web/api/websockets_api/writing_websocket_server/index.html237
1 files changed, 237 insertions, 0 deletions
diff --git a/files/pt-br/web/api/websockets_api/writing_websocket_server/index.html b/files/pt-br/web/api/websockets_api/writing_websocket_server/index.html
new file mode 100644
index 0000000000..553ba11aec
--- /dev/null
+++ b/files/pt-br/web/api/websockets_api/writing_websocket_server/index.html
@@ -0,0 +1,237 @@
+---
+title: 'Escrevendo um servidor WebSocket em C #'
+slug: WebSockets/Writing_WebSocket_server
+translation_of: Web/API/WebSockets_API/Writing_WebSocket_server
+---
+<h2 id="Introdução">Introdução</h2>
+
+<p>Se você quiser usar uma API WebSocket, você precisara ter um servidor. Neste artigo vou mostrar como escrever um WebSocket em C#. Você pode fazer isso em qualquer linguagem server-side, mas para manter as coisas simples e mais compreensíveis eu escolhi uma linguagem Microsoft.</p>
+
+<p>Este servidor está em conformidade com a <a href="http://tools.ietf.org/html/rfc6455" title="http://tools.ietf.org/html/rfc6455">RFC 6455</a>, por isso irá tratar apenas as conexões com os navegadores Chrome versão 16, Firefox 11, IE 10 ou superior. </p>
+
+<h2 id="Primeiros_passos">Primeiros passos</h2>
+
+<p>Os WebSocket´s se comunicam através de uma conexão TCP (Transmission Control Protocol), felizmente o C# possui a classe <a href="https://msdn.microsoft.com/pt-br/library/system.net.sockets.tcplistener.aspx">TcpListener</a> que, como o nome sugere, tem a função de escutar (Listener) as comunicações via TCP. A classe TcpListener está no namespace System.Net.Sockets.</p>
+
+<div class="note">
+<p><span style="line-height: 1.572;">É uma boa idéia usar a palavra chave using para escrever menos. Isso significa que não é preciso você reescrever o namespace toda vez que usar uma classe dele.</span></p>
+</div>
+
+<h3 id="TcpListener">TcpListener</h3>
+
+<p>Construtor:</p>
+
+<pre class="brush: cpp">TcpListener(System.Net.IPAddress localaddr, int port)</pre>
+
+<p>Aqui você define onde o servidor será acessível.</p>
+
+<div class="note">
+<p><span style="line-height: 1.572;">Para setar facilmente o tipo esperado no primeiro parâmetro, use o método estático Parse da classe IPAddress.</span></p>
+</div>
+
+<p><span style="line-height: 1.572;">Métodos</span><span style="line-height: 1.572;">:</span></p>
+
+<ul>
+ <li><span style="line-height: 1.572;">Start()</span></li>
+ <li><span style="line-height: 1.572;">System.Net.Sockets.<a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx" title="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx">TcpClient</a> AcceptTcpClient()<br>
+ Espera por uma conexão TCP, aceita a conexão e retorna um objeto TcpClient.</span></li>
+</ul>
+
+<p><span style="line-height: 1.572;">Veja como usar o que aprendemos:</span></p>
+
+<pre class="brush: cpp">​using System.Net.Sockets;
+using System.Net;
+using System;
+
+class Server {
+ public static void Main() {
+ TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);
+
+ server.Start();
+ Console.WriteLine("Server has started on 127.0.0.1:80.{0}Waiting for a connection...", Environment.NewLine);
+
+ TcpClient client = server.AcceptTcpClient();
+
+ Console.WriteLine("A client connected.");
+ }
+}
+</pre>
+
+<h3 id="TcpClient"><span style="line-height: 1.572;">TcpClient</span></h3>
+
+<p>Métodos:</p>
+
+<ul>
+ <li><code>System.Net.Sockets.<a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.aspx" title="http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.aspx">NetworkStream</a> GetStream()</code><br>
+ Obtém o fluxo (stream) do canal de comunicação. Ambos os lados do canal de comunicação possuem a capacidade de ler e escrever.</li>
+</ul>
+
+<p>Propriedades:</p>
+
+<ul>
+ <li><code>int Available</code><br>
+ Este é o numero de bytes de dados que foram enviados. o valor é zero enquanto <em>NetworkStream.DataAvailable</em> for <em>falso</em>.</li>
+</ul>
+
+<h3 id="NetworkStream">NetworkStream</h3>
+
+<p>Métodos:</p>
+
+<pre class="brush: cpp">Write(Byte[] buffer, int offset, int size)</pre>
+
+<p>Grava bytes do buffer, <em>offset </em>e <em>size </em>determinam o tamanho da mensagem.</p>
+
+<pre><span class="brush: cpp" style="line-height: 1.572;">Read(Byte[] buffer, int offset, int size)</span></pre>
+
+<p>Lê bytes para o <em>buffer, offset e size </em>determinam o tamanho da mensagem.<em> </em></p>
+
+<p>Vamos estender nosso exemplo.</p>
+
+<pre class="brush: cpp">TcpClient client = server.AcceptTcpClient();
+
+Console.WriteLine("A client connected.");
+
+NetworkStream stream = client.GetStream();
+
+//enter to an infinite cycle to be able to handle every change in stream
+while (true) {
+ while (!stream.DataAvailable);
+
+ Byte[] bytes = new Byte[client.Available];
+
+ stream.Read(bytes, 0, bytes.Length);
+}</pre>
+
+<h2 id="Handshaking">Handshaking</h2>
+
+<p>Quando um cliente se conecta a um servidor, ele envia uma solicitação GET para atualizar a conexão com o WebSocket a partir de uma simples requisição HTTP. Isto é conhecido como handshaking (aperto de mão).</p>
+
+<div class="warning">
+<p>Este código tem um defeito. Digamos que a propriedade client.<code>Available</code> retorna o valor 2 porque somente a requisição GET está disponível até agora. a expressão regular iria falhar mesmo que os dados recebidos sejam perfeitamente válidos.</p>
+</div>
+
+<pre class="brush: cpp">using System.Text;
+using System.Text.RegularExpressions;
+
+Byte[] bytes = new Byte[client.Available];
+
+stream.Read(bytes, 0, bytes.Length);
+
+//translate bytes of request to string
+String data = Encoding.UTF8.GetString(bytes);
+
+if (new Regex("^GET").IsMatch(data)) {
+
+} else {
+
+}</pre>
+
+<p>Criar a resposta é mais fácil do que entender porque você deve fazê-lo desta forma.</p>
+
+<p>Você deve,</p>
+
+<ol>
+ <li>Obter o valor do cabeçalho da requisição <em>Sec-WebSocket-Key</em> sem qualquer espaço à direita e à esquerda;</li>
+ <li>Concatenar com "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";</li>
+ <li>Calcular o código SHA-1 e Base64 dele;</li>
+ <li>Reescreva no cabeçalho de resposta o valor de <em>Sec-WebSocket-Accept</em> como parte de uma resposta HTTP.</li>
+</ol>
+
+<pre class="brush: cpp">if (new Regex("^GET").IsMatch(data)) {
+ Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + Environment.NewLine
+ + "Connection: Upgrade" + Environment.NewLine
+ + "Upgrade: websocket" + Environment.NewLine
+ + "Sec-WebSocket-Accept: " + Convert.ToBase64String (
+ SHA1.Create().ComputeHash (
+ Encoding.UTF8.GetBytes (
+ new Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+ )
+ )
+ ) + Environment.NewLine
+ + Environment.NewLine);
+
+ stream.Write(response, 0, response.Length);
+}
+</pre>
+
+<h2 id="Decodificação_de_mensagens">Decodificação de mensagens</h2>
+
+<p>Após um <em>handshake</em> de sucesso o cliente ponde enviar mensagens ao servidor, mas agora estas mensagens são codificadas.</p>
+
+<p>Se nós enviarmos "MDN", nós obtemos estes bytes:</p>
+
+<table>
+ <tbody>
+ <tr>
+ <td>129</td>
+ <td>131</td>
+ <td>61</td>
+ <td>84</td>
+ <td>35</td>
+ <td>6</td>
+ <td>112</td>
+ <td>16</td>
+ <td>109</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>- 129:</p>
+
+<table>
+ <thead>
+ <tr>
+ <th scope="col">FIN (Esta é toda a mensagem?)</th>
+ <th scope="col">RSV1</th>
+ <th scope="col">RSV2</th>
+ <th scope="col">RSV3</th>
+ <th scope="col">Opcode</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1</td>
+ <td>0</td>
+ <td>0</td>
+ <td>0</td>
+ <td>0x1=0001</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>FIN: Você pode enviar sua mensagem em quadros (frames), mas agora as coisas ficaram mais simples.<br>
+ <span style="line-height: 1.572;">Opcode </span><em>0x1</em><span style="line-height: 1.572;"> significa que este é um texto. Veja aqui a </span><a href="http://tools.ietf.org/html/rfc6455#section-5.2" style="line-height: 1.572;" title="http://tools.ietf.org/html/rfc6455#section-5.2">lista completa de Opcodes</a>.</p>
+
+<p>- 131:</p>
+
+<p>Se o segundo byte menos 128 estiver entre 0 e 125, este é o tamanho da mensagem. Se for 126, os 2 bytes seguintes (16-bit inteiro sem sinal) e se 127, os 8 bytes seguintes (64-bit inteiro sem sinal) são o comprimento.</p>
+
+<div class="note">
+<p>Eu posso escolher 128, porque o primeiro bit sempre será 1.</p>
+</div>
+
+<p>- 61, 84, 35 e 6 são os bytes de chave para decodificar. Sempre mudam.</p>
+
+<p>- O restante dos bytes codificados são a mensagem<span style="line-height: 1.572;">.</span></p>
+
+<h3 id="Algoritmo_de_decodificação">Algoritmo de decodificação</h3>
+
+<p>byte decodificado = [byte codificado XOR (posição do byte codificado MOD 4º byte da chave)]</p>
+
+<p>Exemplo em C#:</p>
+
+<pre class="brush: cpp">Byte[] decoded = new Byte[3];
+Byte[] encoded = new Byte[3] {112, 16, 109};
+Byte[] key = Byte[4] {61, 84, 35, 6};
+
+for (int i = 0; i &lt; encoded.Length; i++) {
+ decoded[i] = (Byte)(encoded[i] ^ key[i % 4]);
+}</pre>
+
+<h2 id="Link_Relacionado">Link Relacionado</h2>
+
+<ul>
+ <li><a href="/en-US/docs/WebSockets/Writing_WebSocket_servers">Writing WebSocket servers</a></li>
+</ul>
+
+<div id="cke_pastebin" style="position: absolute; top: 2209.23px; width: 1px; height: 1px; overflow: hidden; left: -1000px;"> </div>