<!doctype HTML>
<html lang="pt-BR">
	<head>
		<meta charset="utf-8"/>
		<meta name="viewport" content="width=device-width, user-scalable=no"/>
		<link rel="stylesheet" href="../../../style/style.css" media='all'>
		<link rel="stylesheet" href="../../../style/texto.css" media='all'>
		<title>PHP - Socket com php 🐘 | RootThings.org</title>
		<link rel="shortcut icon" href="../../../img/icn.png" type="image/x-png"/>
		<!-- coisas importantes pra não dá treta na hora de alguém pesquisar e não achar. -->
	<meta property="description" content="Já cansou de pesquisar como criar um chat web socket com PHP? Eu também tinha cansado quando fiz isso. Faça com PHP mesmo não precisa mudar de linguagem, o PHP é forte o suficiente para criar um chat real time e web socket, agora se liga como o bagulho é doido!" />
  	<meta property="og:title" content="PHP - Socket com php 🐘 | RootThings.org" />
    <meta property="og:site_name" content="RootThings.org" />
    <meta property="og:url" content="https://rootthings.org/artigos/PHP/Chat-web-socket" />
    <meta property="og:image" content="https://rootthings.org/artigos/PHP/Chat-web-socket/handshake1.jpg" />
  	 <meta property="og:description" 
		content="Já cansou de pesquisar como criar um chat web socket com PHP? Eu também tinha cansado quando fiz isso. Faça com PHP mesmo não precisa mudar de linguagem, o PHP é forte o suficiente para criar um chat real time e web socket, agora se liga como o bagulho é doido!" />
		<script async src="../../../js/principal.js"></script>	
	</head>
	<body>
		{{cabecalho}}
		<section class="corpo">
			
			<div id="links"><br/>
				<a href="../../../">Home</a><br/>
				<a href="../../">Artigos</a><br/>
				<span>Introdução</span><br/>
				<a href="../PHP funcional - Map, Filter e Reduce | conheça/">PHP funcional - Map, Filter e Reduce | conheça</a><br/>
				<a href="../PHP Automatização/">Saiba como agendar a data a hora e qual email enviar a determinada pessoa com PHP</a><br/>

			</div>
			<nav id="linksbg">
			</nav>
			<div id="conteudo">
				<h1>Crie um chat em tempo real com PHP utilizando a tecnologia de websocket 🐘</h1>
				<p>
					Essa foi uma tarefa que eu tinha que fazer para um amigo que tinha me pedido, e assim que ele me pediu isso, eu pensei
				</p>
				<figure>
					<img src="lego.jpg" alt="Imagem de lego, que se relaciona com os socketes"/>
					<figcaption>Achei facinho(Esse lego de encaixe que remete ao socket, tem duplo sentido)</figcaption>
				</figure>
					<blockquote>
						Hêr, facinho eu faço isso aí, crio um <code>xhr</code> basicão.
					</blockquote>				
				<p>
					Mas, depois de dois dias, eu pensei, nossa porquê eu não me atualizo? E aí me veio a mente o websocket.
					<hr/>
				</p>
				<p>
					Depois de muito tempo de busca, eu pensei:
				</p>
					<blockquote>
						P$@ é uma merda encontrar suporte de websocket com PHP, nem o manual php.net fala de todos os assuntos!
					</blockquote>
				<p>
					Mas só pensei nisso porque eu não tinha lido este artigo😎!
				</p>
				<h1>Porquê das coisas</h1>
				<h2>O que diabos é websocket🤔?</h2>
				<p>
					É um protocolo de comunicação com o servidor, montado em Ecmascript(Javascript) pelo lado clientes, este suporte é apartir de a versão cinco
					do HTML, então! Ele é montado no lado do cliente, usa tecnologogia de real time, mas sem precisar que configure algum tempo de latância
					ele, simplesmente reconhece os dados que são pra eles, e você pode trata-los facilmente com um <code>onmessage()</code>.
				</p>
				<h2>E no lado do servidor🤔?</h2> 
				<p>
					Agora o bagulho vai ficar sério!😈 <br/>
					Vamos lá, o socket, é um recurso popular já usado e manjado em c desde que o mundo é mundo, em python também, mas não com suporte a HTML5,
					então vamos direto ao ponto de <strong>o que precisamos fazer</strong>.
				</p>
				<p>
					Primeiramte, abri-se o socket, definindo o que ele será, socket é uma forma de comunicação do servidor para o cliente, só que uma forma
					mais eficiente ainda do que o próprio http mesmo para streaming e audios, chat etc. Então após definir o socket, precisa dizer qual porta
					e qual o seu ip, até também dizer o numero de entradas que deseja responder, após isso, tem que aceitar a conexão feita e criar um handshake.					
				</p>
				<h2>Show-me the theory🤓!</h2>
				<p>
					A comunicação funciona de forma bem interessante, no servidor eu já disse o que é feito, mas no cliente, é assim
				</p>
					<hr/>
				<p>		
					O cliente, abre a conexão com instruções no browser, após isso ela receberá uma mensagem falando se de fato essa comunicação websocket
					é a que deve ser usada, este processo é no <code>HTTP</code> mesmo, e logo após da resposta do servidor também em <code>HTTP</code> óbio né!
					E logo após tudo isso, inicia o handshake, e já inicia o socket.
				</p>
				<h2>E como é esse cabeçalho HTTP🤔?</h2>
				<p>
					O cabeçalho de conexão http é bem simples, como qualquer outro, ele leva informação do protocolo, do que que gostaria de acessar e a forma 
					de acessar, ele traz algo peculiar.
				</p>
				<p>
					A <a href="https://tools.ietf.org/html/rfc6455" target="_blank">RFC 6455</a> diz que no processo de cabeçalho http, deve levar uma chave
					para o socket, algo parecido com a chave na linha que diz <code>Sec-WebSocket-Key</code>:
				</p>				
				<pre>
	<!-- Ele é do cliente para o servidor, e não o inverso -->
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
<span class="distaque-branco">Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==</span>
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
					</pre>
				<p>
					Esta é um processo chamado de handshake, que é as primeiras impressões, para fazer isso entenda o que é o processo, e saiba como monta
					a chave na explicação abaixo
				</p>
				</p>				
				<h2>O que é esse processo de handshake🤔?</h2>
				<p>
					Handshake do inglês
				</p>
				<figure>
					<img src="handshake1.gif" alt="Aperto de mão entre bender e um outro robô"/>
					<figcaption>Aperto de mão</figcaption>
				</figure>
				<p>
					O handshake é um processo em que o servidor e a máquina que acessa, identifica se reconheceu e está pronta para começar ou não o websocket.
					Então o nosso handshake é a abertura para que inicie toda a conexão usando http, é algo como:	<br/>
					1) A maquina faz uma requisição, envia uma mensagem como:"Tudo certo man? e aí?"  e o servidor responde: "Tudo beleza, vamos mudar de protocolo?".<br/>
					2) e desde já o protocolo é passado a ser usado normalmente.<br/>
					Olhe a imagem abaixo que ilustra para facilitar o entendimento:
				</p>
				<figure>
					<img src="handshake1.jpg" alt="O processo chamado de handshake, é em http e mostra o cabeçalho de ambos." width="100%"/>
					<figcaption>Veja que na figura mostra os cabeçalhos: 1) Do cliente ao servidor. 2) Do servidor ao cliente.<figcation>
				</figure>
				<p>
					A parte <span class="distaque-preto">Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==</span> do envio do cliente ao servidor é uma chave 
					ela é de 16 bits e encriptada em base64 em hexadecimal do padrão "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" segundo a 
					<a href="https://tools.ietf.org/html/rfc6455" target="_blank">RFC</a>, o browser é o responsável por criar e enviar, então todo esse processo ocorre a
					partir do momento que no JS você chama <code>new socket()</code> para um determinado servidor que rode o socket né! 
					E a resposta do servidor será	<span class="italic">101 - trocando protocolo</span>.
				</p>
				<p>
					Já na parte do servidor, não é algo nativo ou padrão <span title="até a utima versão de quando escrevi">ainda</span>, mas para montar a 
					<span class="distaque-preto">Sec-WebSocket-Key</span> que a montagem é similar a do cliente para o servidor, para monta-la existe um padrão	
					que é "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", este valor e o recebido pelo cabeçalho é encriptado em hash sha1 e transformado em hexadecimal,
					e passado para base64, a saída é um valor que fará com que seja confirmada e ocorra as proximas conexões já por websocket.
				</p>
				<p>
					E você acha que eu iria saber disso sem testar? como sou extremamente curioso fiz um algoritmo em php que simulasse a conexão e saísse
					o resultado do cabeçalho do servidor para o cliente. Veja a saída.
				</p>
				<figure>
					<img src="terminal.jpg" alt="Cabeçalho handshake, emulado em um terminal"/>
					<figcaption>Eu rodei apenas os padrões passados para um simples echo e saiu o resultado como esperado, a saída era igual tudas as que tinha 
					pesquidado.</figcaption>
				</figure>
				<h2>Diferencial 🔧</h2>
				<p>
					O websocket funciona diferente de qualquer outro protocolo onde o servidor responde um usuário por vez, o socket cria e pode atender 
					vários usuários ao mesmo tempo(Aí está a ideia de real-time), e no motor em PHP funciona um unico processo onde ele fica
					rodando infinitamente	para verificar se tem algum pedido e assim flui de uma forma bem rápida.
				<p>
				<blockquote>
					Mas este processo rodando infinitamente não seria prejudicial ao servidor?
				</blockquote>
				<p> 
					Sim! mas a grande maioria usa uma forma diferente, e diz que é bastante mudada, mas vamos ver como é a forma que o Node.js e o PHP React usa.
				</p>
				<p>
					Eles usaram um programa do unix que é acesso pela linguagem C, chamado de <span class="distaque-preto">select</span>, o 
					<a href="http://man7.org/linux/man-pages/man2/select.2.html" target="_blank">select</a> funciona como uma função, onde faz determinada ação
					após receber outra determinada ação, e ela faz isso em tempo real, algo bastante promissor, mas como é que ela funciona?<br/>
					Sim, ela funciona da mesma forma que um laço infinito, então seria o mesmo resultado diferenciando apenas a aparência do seu código
					e a linguagem que será usada, e por ser em C a obstrução é menor, e atualiza até mais rádido, <strong>TEORICAMENTE</strong> porque o intermediário entre o PHP
					e o C é uma biblioteca e o tempo da biblioteca fazer ele retornar a seu arquivo e tomar determinada ação resultará em um tempo igual ou mais duradouro 
					do que utilizando algo nativo do PHP, e o do Node é algo similar ao select do C, porém ele funciona como um loop infinito, e consome o mesmo	
					que consumiria um comum feito em PHP.
				</p>	
				<p>
					No exemplo deste artigo usei <code>while(true)</code> o que faz o loop infinito, ele processarar diferentes entradas em um só loop, ao mesmo tempo
					assim.
				</p>
				<figure>
					<img src="async.jpg" alt="Vários computadores fazendo requisições a um servidor e cada qual sendo respondido sem que um tempo interfira o outro"/>
					<figcaption>Veja, como ele trata individual cada processo, sem com que um atrapalhe o outro</figcaption>
				</figure>
				<p>
					Esse processo chama-se de req não bloqueável, e funciona de forma independente, assíncrona
				</p>
				<p>
					Para facilitar o entendimento veja o seguinte gif animado:
				</p>
				<figure>
					<img src="websocks.gif" alt="Mostra uma requisição lenta não bloqueando as outras que podem ser carregadas mais rápidos"/>
					<figcaption>Veja como é a forma da seta laranja que representa uma conexão distante e lenta, porém ela não impede que os outros sejam respondidos</figcaption>
				</figure>
				<h1>Show-me the code <span class="emoj">😏</span>!</h1>
				<p>
					Agora é a melhor parte, vejamos os códigos, como tudo deve funcionar e quais as melhores práticas.
				</p>
				<p>
					Eu montei o projeto em paradigma procedural, para que você possa aplicar no que for mais conviniente para você ou para os seus projetos.
				</p>
				<h2>
					O servidor ⚙️
				</h2>
				<p>
					Nosso motor usado será apenas um, vamos aos códigos mais importante para o seu funcionamento.
				</p>
				<p>
					Leia o seguinte códigos, e as linhas de comentários, eu resumi tudo o que eu precisaria escrever por um enfadonho texto em comentários
					de código.
				</p>
				<figure>	
					<script src="https://gist.github.com/Jul10l1r4/bc35882546f11b2a3b81f502bd4e3214.js"></script>
					<figcaption>Este é o motor principal, ei não esquece de ler a linha de código</figcaption>
				</figure>
				<p>
					Viu? bem legal né?! Agora devemos montar a parte do frontend, mas se você só queria esta parte, dê uma olhada no git onde está e use a aplicação
					quando estiver funcionando você mesmo pode fazer testes, veja aqui <a href="" target="_blank">@jul10l1r4</a>.
				</p>
				<p>
					Agora vamos ao frontend 😏 o nosso JS é ele quem fará a requisição e receberá e além disso ele mudará escreverá no nosso HTML
				</p>
				<p>
					Veja o nosso JS:	
				</p>
				<figure>
					<script src="https://gist.github.com/Jul10l1r4/5bb8c8163ee182a2ce43a8d94927107d.js"></script>
					<figcaption>Lembrando, qualquer dúvida leia os comentários, fui bem detalhista em todos neles</figcaption>
				</figure>
				<p>
					Esse JS fará uma requisição bem básica, ele recebe dois campos em json, esses dois campos são os enviados do PHP q é quem enviou a mensagem
					e qual a mensagem, olhe esse print, que interessante, essa é a primeira resposta, que foi encurtada com uma entrada em hexadecimal.
				</p>
				<figure>
					<img src="hex.jpg" alt="Valor de uma mensagem em hexadecimal para transferencia websocket"/>
					<figcaption>Viu? essa mensagem é o valor em hexadecimal de nosso arquivo em PHP, mas óbviamente, o navegador em sí decifra tudo isso e entrega apenas o json com strings</figcaption>
			  </figure>	
				<p>
					E agora teremos nossa saída simples de valores em nosso HTML, onde terá um formulário simples, com a entrada e um <code>submit</code> que chamará uma função e enviará para o servidor a mensagem e o autor dela				
				</p>
				<figure>
					<script src="https://gist.github.com/Jul10l1r4/6f583e006e754f400f1a8a779428570b.js"></script>
					<figcaption>Lembrando que os caminhos informados de todos os exemplos são baseados nos nomes do git oficial</figcaption>
				</figure>
				<p>
					Agora vá atualize e rode B-), e... opa... ao rodar mostrou uma mensagem dizendo que não estava conectado? sim esqueceu, temos nosso PHP
					mas para iniciar o socket, tem que ir e rodar ele, óbvio... para provar isso abra uma aba e acesse no seu servidor local <code>socket/respostas.php</code>
					e mantenha a aba aberta, ok agora volte e veja no que deu... isso a aplicação funcionará, mas eu não acho nada conviniente ter que manter a aba rodando para 
					o chat conseguir funcionar, então fiz um pequeno motor para executar aplicação e manter ela em execução.
				</p>	
				<p>
					O pequeno motor, é apenas uma função do PHP chamada <code>exec()</code>, que executa códigos do terminal(Se estiver em um terminal), ela funciona no PHP desde a versão 3,
					mas neste caso ele funcionará em apenas unix-like, por motivo da estrutura de arquivo, se quiser rodar em um Windows, você pode substituir
					o caminho do PHP pelo simples <code>php</code>, ele chamará e abrirá o arquivo.<br/>
					Obs.: Lembre-se do caminho do arquivo PHP, que deve ser executado para que funcione.
				</p>	
				<figure>
					<script src="https://gist.github.com/Jul10l1r4/f167f1b5dd84628e0e6d3190d35199e8.js"></script>
					<figcaption>Viu? isso é bem interessante, pra isso você apenas carregará uma vez a página e para sempre ele funcionará :)</figcaption>
				</figure>
				<p>
					Para o uso e a correta forma de disparar, precisa que você mesmo defina o caminho de onde fica o PHP e o caminho no servidor para o seu artigo.
					Para executa-lo em um servidor apenas para teste, você pode cancelar o processo, porém é algo que precisa de um nível maior no terminal, o código
					<code>top</code> pode ajudar para encontrar qual o processo que é aquele, e assim finaliza-lo.
				</p>
				<h2>Conclusão 📜</h2>
				<p>
					O PHP é uma linguagem sim forte o suficiente para que você desenvolva absolutamente tudo, ela é uma linguagem bastante madura, se as sintaxes não lhe atrai
					olhe em sua volta o PHP possui vários frameworks e bibliotecas para facilitar seu desenvolvimento, se você deseja performance o PHP funciona
					independentemente de bibliotecas, ela é uma linguagem tão forte quanto o Python 💙
				</p>
			</section>		
			<footer id="rodape"><!-- pronto -->
			<?php             //Fernando, esse comentário esta no backend, ngm vai ler
		  $a = curl_init("https://rootthings.org/rt/rodape.php");// Não mexe onde tem <?php ← 
	          $b = curl_exec($a);                                   // Essa parte aqui é responsável pelo rodape
		  echo str_replace("1","",$b); 
                ?>
			</footer>
	

	</body>
</html>
