It may be in vogue, but is there a practical reason to adopt Node.js? Lee Boynton mostra como ele pode ser usado para adicionar uma fonte de notícias em tempo real para o seu site PHP.

este artigo pretende mostrar-lhe como pode começar a usar o Node para adicionar recursos em tempo real ao seu website baseado no PHP. Primeiro, vamos olhar um pouco mais para o que faz o Node um bom ajuste para aplicativos em tempo real, antes de continuar a demonstrar como construir um feed de notícias em tempo real e incorporá-lo em seu site PHP.

Thread-based vs Event-based

tradicionalmente o PHP é servido com o Apache e o módulo mod_php. Se você executar o comando ‘ top ‘ no seu servidor web baseado em Unix você provavelmente verá um grande número de processos Apache servindo clientes web. Nesta configuração, cada pedido de cliente tipicamente gera um novo processo Apache até que toda a RAM disponível seja usada. Recentemente, nginx e php-fpm emergiram como o método mais eficiente de servir sites de PHP, mas mesmo nesta configuração cada cliente é servido por um processo de PHP diferente. O ponto chave aqui é que, do início ao fim, um pedido do cliente está usando um processo PHP para toda a duração. Se demorar muito tempo para processar cada pedido, os recursos do servidor podem ser usados muito rapidamente.

no nó, um único processo de nó normalmente serve a cada cliente em um loop de Evento. Para processos de longa duração, caros como acessar o sistema de arquivos, um banco de dados ou uma API remota, é defendido a utilização de chamadas de método assíncrono ao invés de bloquear as chamadas. Isto é conseguido através do uso de callbacks que são desencadeados quando uma ação como acessar o sistema de arquivos terminou. Isto significa que um único processo de nó pode continuar a processar novas solicitações enquanto a operação cara é executada em segundo plano. Quando a operação cara está completa, ela volta para a fila de eventos para ser processada mais por nó.

em essência, o nó pode ser visto como um ambiente semelhante para a construção de aplicações tais como Python’s Twisted ou EventMachine em Ruby. Node também tem um Servidor HTTP built-in pronto para produção, de modo que ele não precisa de um servidor separado para executá-lo, como o Apache ou Nginx, melhorando ainda mais seus requisitos de recursos lean (salvo qualquer vazamento de memória).

var http = require('http');http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn');}).listen(1337, '127.0.0.1');console.log('Server running at http://127.0.0.1:1337/');

o exemplo de código acima mostra como você pode escrever um servidor web obrigatório” hello world ” em apenas algumas linhas de código. A primeira linha demonstra o uso do sistema de módulos conhecido como CommonJS que o nó usa para incluir módulos separados. A função require é incorporada, e neste caso importa o módulo HTTP do Node para uso na aplicação. A segunda linha cria um novo objeto de servidor web. Observe que o primeiro parâmetro do método createServer é uma função anônima. A maioria dos métodos no nó aceitam uma função de callback como um parâmetro, e esta é a chave para a construção de aplicações movidas por eventos.

a próxima linha de execução é a linha 5, que usa o método de encadeamento para chamar o método de escuta no valor de retorno do método createServer (o valor devolvido é a instância do módulo HTTP). O método de escuta faz com que o servidor comece a aceitar pedidos HTTP na porta 1337 no localhost. A última linha escreve uma mensagem para a consola para dizer que o servidor começou. Somente quando um pedido para o servidor é feito é a função anônima chamada, que define o código de estado HTTP para 200 OK e define o cabeçalho do tipo de conteúdo. A mensagem’ Hello World ‘ é finalmente escrita para o corpo de resposta HTTP na Linha 4.

Por Que devo usar o nó.js, então?

o modelo do Node baseado em Eventos é especialmente adequado para aplicações em tempo real, tais como jogos, fontes de notícias e aplicações de chat. Além disso, ele também permite que você use o mesmo idioma na interface e infra-estrutura. JavaScript só está se tornando mais popular como aplicativos Mais Ricos do lado cliente são construídos e navegadores da web ficam mais rápidos na execução de JavaScript. Ter que mudar de línguas pode ser frustrante.

o WordPress Spezial

Entwickler Magazin Spezial Vol. 10: WordPressEntwickler Magazin Spezial Vol. 10: WordPress
Alles rund um WordPress im Entwickler Spezial Vol. 10-ab 18.11.2016 im Handel.WordPress ist längst weit mehr als ein simples Blogsystem. In diesem Sonderheft beschäftigen sich zahlreiche Spezialisten mit allen wichtigen Fragen rund um das verbreitetste CMS im Web; und dabei geht es nicht nur um klassische Themen, sondern auch um Marketing de Afiliados, E-Commerce u.v.m.

em Segundo lugar, ele tem um bom suporte a WebSockets. Embora seja possível suportar WebSockets em PHP, a natureza assíncrona de Node e seu Servidor HTTP embutido torna-o um ajuste melhor. WebSockets são uma forma de manter uma conexão persistente com o navegador, a fim de enviar dados para o cliente rapidamente. Em comparação com soluções anteriores, como sondagens longas ou cometas, WebSockets implicam uma latência muito menor, uma vez que não há nenhuma sobrecarga de instanciação de uma conexão HTTP cada vez que alguns dados precisam ser enviados. A desvantagem para WebSockets é que é um recurso HTML5, e como tal não é tão bem suportado em navegadores como Ajax simples velho é. No entanto, é possível recuar graciosamente para técnicas alternativas, tais como sondagens longas em navegadores que não suportam WebSockets.

na Conferência Internacional de PHP deste ano você pode aprender mais sobre integração de nós.js com PHP!

a Conferência Internacional de PHP é a primeira Conferência Mundial de PHP e tem sido um marco para a experiência pragmática top-notch em PHP e tecnologias web por mais de uma década . No IPC, especialistas de renome internacional da indústria PHP se reúnem com usuários e desenvolvedores de PHP de grandes e pequenas empresas. Confira nossos primeiros preços de aves para grandes descontos!

Aqui estão algumas sessões de destaque do IPC:

  • tornando o seu Angular.js Aplicação acessível
    Dirk Ginader (Google)
  • TypeScript de Tomada de JavaScript de Desenvolvimento Mais Produtivo e Robusto
    Rainer Stropek (arquitetos de software gmbh)
  • Como chegar pronto para PHP 7
    Sebastian Bergmann (thePHP.cc)

tenha em mente, porém, o Nó é um imaturo plataforma comparado com o PHP. Originalmente criado em 2009, ele ainda está em sua infância e ainda não alcançou a versão 1.0 – se isso importa para você. Você pode descobrir que as APIs que você usa a mudança no futuro, ou ser incapaz de encontrar um framework que tem o mesmo conjunto de recursos que o seu framework PHP favorito. Na verdade, na minha experiência as bibliotecas de terceiros e os frameworks disponíveis tendem a consistir em pacotes muito menores de funcionalidade que você precisa juntar.há também um maior risco de vazamentos de memória trazendo sua aplicação a uma parada de moagem. Os processos de nó normalmente são executados continuamente, enquanto os processos de PHP tendem a ser respawned periodicamente para negar o efeito de vazamentos de memória.

a parte integradora

a fonte de Notícias será integrada com um site de PHP básico que lida com logins e sessões de usuários, usando uma configuração comum de php-fpm e nginx. Estaremos usando JavaScript para comunicar com uma aplicação de nó no lado do servidor e atualizar dinamicamente a fonte de notícias sem recarregar a página. Em primeiro lugar, porém, um rápido aparte nas sessões.

se ainda não o estiver a fazer, deverá usar uma área de armazenamento centralizada para as suas sessões (Figura 1). O Memcached pode ser facilmente usado para esta tarefa, usando o controlador de gravação de sessão incorporado na extensão PECL memcached. Se você quer a capacidade de reiniciar o servidor de armazenamento de suas sessões sem perder dados, então Redis é uma boa aposta. De qualquer forma, um armazenamento de sessão centralizado permite-lhe carregar balancear a sua aplicação através de vários webservers. Ele também permite que você compartilhe dados de sessão com aplicativos construídos com outras linguagens de programação.

Figura 1: arquitectura de sessões partilhadas.

no entanto, há um pequeno problema de analisar os dados da sessão. Abaixo mostra o formato de serialização por omissão de uma sessão de PHP:

not|a:2:{i:0;s:4:"easy";i:1;a:1:{s:2:"to";s:5:"parse";}}

pode parecer que você pode usar a manipulação de texto para analisá-la, mas pode haver casos de aresta que são difíceis de resolver. Seria bom se a sessão fosse serializada no formato JSON:

{"this":{"is": "easier", "to": "parse"}}

muito melhor. É bastante fácil de escrever o seu próprio serializador de sessão que irá converter o que você armazenar em $_SESSION para o formato JSON, veja a minha versão.

Alternativamente, você pode querer considerar msgpack que pode ser configurado para serialise sessões, como no código abaixo, o que também demonstra como usar o memcached como a sessão de salvar manipulador.


existe uma biblioteca de terceiros disponível para o Node que pode serializar e deserializar o msgpack, disponível no npm (Gestor de pacotes de nós, contém um grande número de módulos que podem ser usados na sua aplicação com apenas uma simples instalação do npm ). Vamos agora olhar para a construção do feed de notícias usando Node e incorporando isso em uma aplicação PHP.

App PHP

a aplicação PHP lida simplesmente com logins e sessões do Usuário. As sessões são armazenadas no memcached, mas podem ser facilmente armazenadas no redis. O código abaixo mostra trechos de uma simples página da aplicação (para a fonte de ir para github.com/lboynton/phphants-march-php).

// // <!]>

A primeira linha do script inclui o Compositor autoloader do arquivo, o que significa que todas as dependências estão automaticamente automaticamente, eliminando a necessidade de separar incluir ou necessitam de linhas (nota do Editor: para saber mais sobre o Compositor, consulte Jefersson Nathan de O. O artigo de Chaves). Neste caso, a sessão save handler é a única peça de código externo que é necessária. No entanto, é muito fácil incluir quaisquer pacotes de terceiros disponíveis no packagist ou em qualquer outro lugar em uma data posterior, usando o compositor que também será automaticamente adicionado ao autoloading. As linhas 3 e 4 configuram uma conexão com o memcached, enquanto a sessão save handler é inicializada e registrada com PHP nas linhas 5-14. Os usuários são conectados simplesmente especificando o nome de usuário como um parâmetro GET, embora em um sistema real isso deve ser substituído por um sistema de autenticação mais funcional.

no lado JavaScript, nós usamos algumas bibliotecas de terceiros: jQuery, underscore.js e o Socket.IO cliente, que é a parte do navegador do módulo de nó que vamos usar para enviar dados para o navegador. A io.a chamada do método connect cria uma conexão para a aplicação de nós, que poderia usar um de um número de transportes, como websockets ou Ajax, dependendo do suporte do navegador. Soquete.no method configura um manipulador de eventos que irá mostrar um item de notícias na página sempre que um evento de ‘notícias’ é despoletado pelo lado do servidor.Nota: A aplicação usa o compositor para instalar a sessão save handler e Bower, um gerenciador de pacotes para instalar ativos do lado do cliente. Para instalar o Bower, execute o ‘npm-g install bower’. Em seguida, para instalar os ativos, Faça “bower install”. Em alternativa, actualize as marcas do programa e as folhas de estilo com as versões locais.

o pedido é servido utilizando nginx. Aqui está o ficheiro de configuração do nginx:

upstream node { server localhost:3000;}server { listen 8080; server_name php-node-demo.localhost; root /home/lee/public_html/php-node-demo; index index.php; location / { try_files $uri $uri/ /index.php?$args; } location ~ .php$ { include fastcgi_params; fastcgi_index index.php; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } location ~ /socket.io { proxy_pass http://node; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }}

as linhas 1-3 definem um servidor a montante que executa a aplicação do nó. Qualquer pedido que termine .php será enviado para php-fpm (linhas 15-20), enquanto quaisquer solicitações com /socket.io no URL será passado para o aplicativo de nós (linhas 22-27). As linhas 25 e 26 dizem à nginx para suportar a mudança de protocolo e permitir que websockets sejam proxied para o nó. Isto significa que o aplicativo de PHP e Node são ambos executados no mesmo porto, no que diz respeito ao cliente.

nó.js App

o nó.js app simplesmente lida com qualquer pedido do cliente para o feed de notícias. Os seus excertos são apresentados em baixo (ver github.com/lboynton/phphants-march-node para a fonte completa).

io.set('authorization', function(handshake, callback) { var cookies = cookie.parse(handshake.headers.cookie); mcClient.get('sessions/' + cookies.PHPSESSID, function(error, result) { if (error) { callback(error, false); } else if (result) { handshake.session = JSON.parse(result); callback(null, true); } else { callback('Could not find session ID ' + cookies.PHPSESSID + ' in memcached', false); } });});io.sockets.on('connection', function(socket) { var session = socket.handshake.session; sockets = socket;);function getNews() { redis.blpop('news', 0, function(err, data) {news = JSON.parse(data);if (typeof news.to !== 'undefined') { if (typeof sockets !== 'undefined') {sockets.emit('news', news.content); }} else { io.sockets.emit('news', news.content);}process.nextTick(getNews); });}

Socket.io é uma biblioteca que fornece uma única API para realizar a comunicação WebSocket entre cliente e servidor. Ele também suporta o recurso gracioso quando WebSockets não estão disponíveis no navegador, e outras características úteis em um protocolo de mensagens, tais como batimentos cardíacos, timeouts e suporte de desconexão que não é suportado fora da caixa com a API WebSocket HTML5.

o primeiro excerto configura a autorização para os pedidos que Socket.io recebe. Quando um novo pedido entra, ele vai processar os cookies no pedido e tentar recuperar uma chave memcached que corresponde ao valor do cookie PHPSESSID (o nome padrão para o cookie de sessão PHP). Se encontrado, ele irá armazenar o valor processado da chave memcached em dados.sessão que pode ser acessada mais tarde.

O próximo excerto configura o que deve acontecer quando Socket.io activa o evento ‘ligação’. Este evento é desencadeado durante a conexão inicial do cliente, uma vez autorizado. Os dados de sessão que foram anteriormente recuperados do memcached agora podem ser referenciados através do socket.variável aperto de mão. Quando o cliente se conecta, a instância do socket é associada com o nome de usuário do cliente para que as mensagens possam ser enviadas a usuários individuais.

o último excerto contém uma função para verificar os novos itens de notícias numa fila redis. Ele usa o comando BLPOP em redis, o que significa que se a fila estiver vazia, irá bloquear até que alguns dados sejam adicionados à fila antes de estourar. Quando alguns dados podem ser retirados da fila, ele é processado como JSON antes de determinar se o conteúdo deve ser enviado para cada cliente conectado ou apenas um único usuário. O conteúdo do item de notícias é enviado para o socket correto, chamando o método de emissão() no socket que foi associado com o usuário anteriormente no tratador de eventos de conexão.

finalmente, o processo do nó.o método nextttttick () é chamado com a função getNews como um argumento. Isto significa que a função getNews será chamada da próxima vez que o ciclo de eventos correr e continuará a verificar a fila redis para os dados até que a aplicação seja parada.

para instalar, use npm para transferir as dependências necessárias. Em seguida, execute o aplicativo com o node app.js.

deve agora ser capaz de abrir um navegador web e navegar para http://localhost:8080/?username=bob e ver a aplicação news feed. Agora abra uma segunda página de navegador ou janela com um nome de utilizador diferente, por exemplo http://localhost:8080/?username=sally.

actualizar a fonte

actualizar a fonte é simplesmente um caso de empurrar um novo item de notícias para a fila. Ligue-se à interface redis CLI usando o comando redis-cli. Esta é uma shell interativa para o redis, que lhe permite enviar comandos diretamente para o servidor. A amostra de código abaixo mostra como empurrar para a fila:

rpush news '{"content": "Testy test", "to": "bob"}'

na janela do navegador web que abriu para o utilizador bob deverá ver o item de notícias deslizar do topo da página. Como alternativa, você pode enviar notícias para tanto bob, sally e qualquer otherall clientes conectados excluindo-se o “a” parâmetro, como a seguir:

rpush news '{"content": "Everyone should see this"}'

Em um aplicativo real, você deve enviar dados para a fila do PHP, usando por exemplo, o php-redis extensão ou predis.

conclusão

Este é apenas um exemplo simples para demonstrar como o nó pode ser integrado com a sua aplicação PHP. Há algumas limitações na implementação. Por exemplo, ele só se lembrará de uma conexão de cada usuário. Portanto, se um usuário tem várias páginas ou janelas abertas para a fonte de notícias, apenas uma página irá atualizar. Isso pode ser resolvido armazenando um array de sockets por usuário, e mantendo o controle de cada conexão e desconexão para adicionar ou remover os sockets do array. Cabe ao leitor implementar uma solução melhor. Ele também mostrou ferramentas como compositor e Bower, que eu recomendo que você considere usar em suas aplicações.

Lee Boynton é um desenvolvedor baseado em Hampshire, Reino Unido, com um interesse particular em aplicações em tempo real, tais como mensagens instantâneas e fluxos de atividade. Ele tem conhecimento de desenvolvimento e administração do lado servidor, bem como desenvolvimento frontend. Ele trabalha na empresa local Symbios Group e também é membro do PHP Hampshire para quem ele ajuda a organizar eventos.

Deixe uma resposta

O seu endereço de email não será publicado.