Instalando e configurando node.js e socket.io no Windows 7
Autor: Weslley Alves | Publicado: 2012-08-12T18:42:00-07:00




Olá meu caro leitor(a) este é o meu primeiro poste sobre node.js e espero que seja o primeiro de muitos. Neste poste irei abordar sobre a instalação e configuração do node.js e scoket.io no Windows 7, sendo o &nbsp;principal foco a demonstração da instalação e configuração dos aplicativos e a criação de alguns exemplos para demonstrar o uso do node.js e socket.io. Caso você utiliza o SO Linux pode utilizar as instruções deste link.&nbsp;

O meu conhecimento sobre node.js e socket.io ainda está no nível iniciante, pois tem pouco tempo que comecei a brincar com essa plataforma, mas espero que com o tempo e com os posts posso ir evoluindo junto com vocês.




Sobre o node.js

O node.js nasceu em meados de 2009 sendo o seu criador Ryan Dahl e uma equipe de 14 desenvolvedores que pretendiam criar uma plataforma para facilitar a criação de aplicações real-time e de alta escalabilidade.

O objetivo principal do node.js é "fornecer uma maneira fácil de criar programas de rede escaláveis" solucionando o principal problema das aplicações atuais feitas em Java, PHP ou .NET, pois essas aplicações iniciam um processo para cada conexão que é acompanhado de aproximadamente de 2MB de memória, desta forma limitando o número de acessos pela quantidade de memória da máquina. Para contornar este problema são criados vários servidores para tornar a aplicação mais escalável.
O node.js veio para solucionar este problema mudando a forma que é feito as conexões no servidor, pois ao invés de iniciar um encadeamento em cada conexão será criado um processo que não necessita que o bloco de memória fique alocado a este processo.&nbsp;

Algumas característica do node.js&nbsp;

Threads não bloqueantes: uma das melhores características do node.js onde não há um controle de concorrências entre os recursos disponíveis para os processos. Nas linguagens tradicionais como JAVA e .NET gerenciam as suas threads colocando em fila de execução onde os processos que necessitam utilizar o mesmo recurso esperam a sua vez par usufruir do recurso.

Programação Orientada à eventos I\O: existem diversas bibliotecas para se trabalhar com os protocolos HTTP, HTTPS, Web Sockets (para aplicações real-time), entre outros protocolos.

Mecanismo V8:&nbsp;node.js roda Javascript no lado do servidor utilizando o mecanismo V8 (mecanismo Javascript do Google utilizado no Chrome). Podendo utilizar todo o poder da ECMAScript5

Módulos: contém vários módulos para facilitar o desenvolvimento de aplicações como o módulo de sockets, manipulação de arquivos, url, banco de dados NoSQL, entre outros.&nbsp;



Sobre o socket.io

O socket.io é um modulo do node.js que permiti fazer comunicação bidirecional utilizando as APIs de transporte nativas dos browsers. Resumidamente este modulo que irá proporcionar o real-time criando uma conexão com o servidor permitindo que haja a troca de informações entre Client e Server sem a necessidade de solicitar um novo request.&nbsp;

A troca de informações entre Server e Client são feitas através de eventos onde cada ponta deve monitorar um determinado evento que será disparado. Na parte de exemplos irei detalhar com maiores informações como funciona o disparo dos eventos entre o Server e Client.



Pré requisitos

Executável do Node.js v.0.8.6 (Última versão até a data deste post)&nbsp;

Python v.3.2.3 (Última versão até a data deste post)&nbsp;

Servidor Web.&nbsp;

Estarei utilizando o WAMP como servidor Web local para demonstração do exemplo, caso não tenha um servidor Web local e queira instalar o WAMP pode efetuar a instalação e configuração utilizando este poste sobre Instalando e configurando o WAMP.




Instalando e configurando o node.js

A instalação do node.js no Windows 7 é muito tranquila, pois segue o padrão das instalações for Windows os passos NNF (Next Next Finish) ou PPR (Próximo próximo e reiniciar). Baixe o executável do node.js através do site oficial.&nbsp;Neste tutorial irei utilizar a versão v0.8.6.


Tela de download do executável do node.js


Após o download execute o aplicativo de instalação. Nesta instalação será instalado o node.js, alguns módulos nativos e seu gerenciador de pacotes o NPM (Node Package Manager). Este gerenciador servirá para a isntalação dos demais módulos para a utilização no node.js como o nosso caso o socket.io. Vamos aos passos da instalação.



1º passo - Tela de instalação do node.js:&nbsp;esta tela informa sobre a instalação do node.js para continuar clique no botão "Next"



2º passo - Licença de uso do node.js:&nbsp;nesta tela está descrito a licença do node.js para instalação deve ser selecionado a opção "I accept the terms in the License Agreement" e clique no botão "Next" caso apareça uma mensagem solicitando a confirmação da instalação selecione a opção para continuar com o wizard.



3º passo - Conclusão da instalação do node.js:&nbsp;se tudo der certo a imagem abaixo deve ser exibida assim confirmando a instalação do node.js. Clique no botão "Finish" para finalizar o wizard.





4º passo - Permissão de acesso:&nbsp;O node.js será instalado no diretório padrão dos aplicativos do Windows. No meu caso este será instalado em "C:\Program Files\nodejs". Precisamos dar permissão para esta pasta para a instalação dos demais módulos do node.js no nosso caso o socket.io. Para dar permissão a pasta vá no diretório de instalação do node.js e clique com o botão direito do mouse na pasta "nodejs" e vá na opção "Propriedades":



Clique na aba "Segurança" no campo "Nome de grupos ou de usuários" você deverá dar permissão ao Grupo de Usuários, então clique no botão "Editar" sendo exibida a tela conforme imagem abaixo:




Selecione a opção "Usuários (NOME_DO_COMPUTADOR\Usuários)" e abaixo no campo "Permissões para Usuários" clique na coluna "Permitir" no checkbox "Controle total" sendo marcado o campo "Modificar" automaticamente. Clique botão "OK" retornando para a tela das propriedades da pasta, clique novamente em "Ok" sendo fechado a tela o retornado para a pasta de instalação do node.js




Instalando o Python

Quando necessitamos instalar algum módulo do node.js como o nosso caso o socket.io o gerenciador de pacotes do Node.js (NPM) utiliza na versão Windows o Visual Studio ou o Python, desta forma antes de instalar o módulo socket.io devemos instalar o Python.
Baixe o executável para a sua versão através deste link. Após o download execute o arquivo baixado (python-3.2.3.msi).



1º passo - Permitindo execução:&nbsp;caso seja solicitado a execução deste aplicativo clique em "Executar":




2º passo - Selecionando o tipo de instalação:&nbsp;nesta tela é informado se esta instalação será para todos os usuários ou somente para o usuário que este instalando o aplicativo. Deixe a opção "Install for all users" e clique em "Next":




3º passo - Selecionando diretório de instalação:&nbsp;neste passo você poderá informar um diretório default para a instalação do Python, no meu caso deixarei o default "C:\Python32\". Caso queira alterar escolha a sua pasta e clique no botão "Next" para prosseguir:




4º passo - Customizando a instalação:&nbsp;neste passo você poderá informar o que deseja ou não na sua instalação. Em minha instalação deixei as opções como estão. Após a customização clique em "Next":




5º passo - Finalizando a instalação:&nbsp;Neste ponto o sistema está instalando o aplicativo caso seja informado uma mensagem para execução do aplicativo clique em "Sim". A tela de finalização da instalação é exibida clique na opção "Finish" para finalizar a instalação.




Reiniciando o Windows


Este não é um passo que gostaria de estar colocando neste tutorial, mas em minhas últimas três instalações tudo ocorreu corretamente só após reiniciar o Windows. Então antes de continuar reinicie o seu SO para que as devidas configurações sejam efetivadas.





Instalando o socket.io


Com a instalação do node.js o seu gerenciador de pacotes (NPM) já está instalado e pronto para ser usado assim podemos instalar os demais módulos para a utilização do node.js.&nbsp;

Por padrão as instalações dos módulos eu utilizo a mesma pasta onde efetuei a instalação do node.js que no meu caso foi em "C:\Program Files\nodejs". Assim abra o prompt do Windows&nbsp;(WinKey + R e digite cmd)&nbsp;e navegue até a pasta da sua instalação utilizando os comandos:
cd ..&nbsp;para voltar uma estrutura e cd NOME_DA_PASTA&nbsp;para acessar uma pasta. A instalação do módulo será feita através do comando "npm install socket.io".&nbsp;

Vá no prompt e digite o comando acima e pressione ENTER, se tudo der certo deverá ser informado a mensagem do sucesso da instalação.



Fique atento as mensagens que são exibidas no prompt, pois caso ocorra algum erro será demonstrada uma mensagem.

Neste momento temos tudo que precisamos para utilizar o node.js com socket.io. Então vamos aos exemplos para testarmos os aplicativos instalados.



Botando a mão na massa

Nesta parte do tutorial iremos ver através dos exemplos como podemos utilizar o node.js e o socket.io. Os arquivos de exemplos serão executados pelo console (prompt do Windows) utilizando o executável "node". Para demonstração irei salvar os arquivos de exemplos na pasta de instalação do node.js que no meu caso está em&nbsp;"C:\Program Files\nodejs". Então vamos os exemplos.



O famoso "Hello world": este exemplo que foi tirado do site oficial do node.js irá exibir o texto "Hello word" no browser do usuário conectado no servidor, porém fiz algumas alterações para demonstrar de uma forma mais detalhada o funcionamento de cada parte do código.&nbsp;Crie um arquivo com o nome "hello_world.js" na pasta de instalação do node.js com o conteúdo abaixo:


// Requisitando os módulos
var http = require('http');

/**
 * Função que irá ser chamada a cada conexão com o Node.js
 * @param {http.ServerRequest} req Instância do request da requisição
 * @param {http.ServerResponse} resp Instância do response da requisição
 */
var onRequest = function (request, response) {
   // Informando o tipo do cabeçalho da página
   response.writeHead(200, {'Content-Type': 'text/plain'});
 
   // Escrevendo um texto no response
   response.write('Hello World\n');

   // Encerrando o response
   response.end();
};

// Criando o servidor informando a função de callback para o request
var server = http.createServer(onRequest);

// Iniciando o servidor na porta 1337
server.listen(1337, '127.0.0.1');

// Informando no console (prompt do Windows) a informação
console.log('Server running at http://127.0.0.1:1337/');


Com o arquivo criado abra o prompt do Windows e navegue até a pasta da instalação (ou a pasta onde se encontra o arquivo). Digite o comando&nbsp;"node hello_world.js" e pressione ENTER, se tudo der certo será exibido o texto no prompt "Server running at http://127.0.0.1:1337/" conforme imagem abaixo:


Console de execução do exemplo


Detalhando o código:

Linha #2: nesta linha é carregado o módulo HTTP do node.js utilizando o método require. Este método irá retornar o Object referente ao módulo solicitado.

Linhas&nbsp;#9&nbsp;a&nbsp;#18:&nbsp;criada a função que será executada a cada conexão no servidor. Esta função irá receber dois parâmetros um sendo o request&nbsp;da conexão e outro o response&nbsp;da requisição. Através do response podemos exibir as informações no browser do usuário.

Linha&nbsp;#11:&nbsp;nesta linha utilizando o método writeHead para informar o status code da página (no nosso caso 200) e informando no segundo parâmetro o content type (tipo do conteúdo) da página.

Linha&nbsp;#14:&nbsp;após informar qual será o content type da página será escrito o texto "Hello world" utilizando o método write do Objeto response no browser do usuário.

Linha&nbsp;#17:&nbsp;o método end do Objeto response deve ser chamado em todo request. Caso desejamos informar algo na página podemos informar no primeiro parâmetro o texto a ser exibido. Seguindo o mesmo raciocínio do método&nbsp;write.

Linha&nbsp;#21:&nbsp;aqui que a mágica acontece. Nesta linha estamos criando o nosso servidor utilizando o método createServer do módulo HTTP. Este método irá receber como parâmetro uma função que será chamada (executada) no evento request do servidor, ou seja, em toda requisição feita para o servidor.

Linha&nbsp;#24:&nbsp;com a referência do servidor criado podemos informar a porta que este irá escutar, assim utilizando o método listen informo a porta de conexão e o hostname do servidor.

Linha&nbsp;#27:&nbsp;uma forma de se debugar o código pelo console (prompt do Windows, Shell Linux, etc) é utilizando a função console.log() onde esta deve receber como parâmetro o valor a ser exibido no console. No nosso caso será somente exibida uma mensagem informando que o servidor está rodando no hostname e porta informada no método&nbsp;listen.



Utilizando socket.io:&nbsp;irei demonstrar um exemplo simples, mas detalhado de como utilizar o socket.io. Antes de demonstrar o exemplo gostaria de relembrar uma das características informadas no início deste post, sobre "Programação Orientada à eventos I\O (POE)". Quando estamos programando orientado a eventos temos que sempre estar pensando em callbacks, ou seja, uma forma de interagir com o sistema quando um certo evento é disparado. Será desta forma que iremos trabalhar com o socket.io.

"Então como funciona os eventos com o scoket.io?" Eventos serão disparados pelas duas pontas da aplicação (Server side e Client side) através do socket que foi aberto. Nos dois lados teremos um monitoramento (listeners) dos eventos que podem ser disparados.


Demonstração dos eventos com socket.io



Note pela imagem acima que o evento "userconected" é disparado pelo Client side informando ao Server que o usuário foi conectado, desta forma temos no server um monitoramento para este evento, onde através da função de callback será realizado uma interação com o sistema. Da mesma forma o Server side emite o evento&nbsp;"showmessage" para o Client, onde o socket deste possui um monitoramento do evento utilizando uma função de callback que irá interagir com a aplicação.

Quem já programa algum tempo com Javascript esta&nbsp;familiarizado&nbsp;com este tipo de programação, principalmente quem utiliza jQuery, ExtJS, Prototype,&nbsp;entre outros. Então vamos ao nosso exemplo para demonstrar os conceitos informados acima.



1º Passo - Criando a estrutura no Server side: como no primeiro exemplo iremos criar um arquivo na pasta de instação do node.js com o nome&nbsp;"socketio_exemplo.js" com o conteúdo abaixo:


/**
 * Função que irá ser chamada a cada conexão com o node.js
 * @param {ServerRequest} request Instância do request da requisição
 * @param {ServerResponse} response Instância do response da requisição
 */
var onRequest = function (request, response) {
    // Informando o tipo do cabeçalho da página
    response.writeHead(200, {'Content-Type': 'text/html'});
  
    // Mensagem exibida no console há cada requisição
    console.log('Usuário conectado no Server!!!');

    // Encerrando o response
  response.end();
};

// Requisitando os módulos
var http = require('http').createServer(onRequest),
    io = require('socket.io').listen(http);

// Informando a porta para ser monitorada pelo Server
http.listen(8088, '127.0.0.1');

/**
 * Evento "connection" que ocorre quando um usuário conecta no socket.io
 * @param {SocketObject} socket Objeto do socket conectado
 */
io.sockets.on('connection', function(socket){
    /**
     * Evento "userconected" que ocorre quando a página é carregada.
     */
    socket.on('userconected', function(){
        // Enviando a mensagem só para o socket atual
        socket.emit('showmessage', 'Usuário conectado no socket!!!');

        // Servidor responde o mesmo resultado via broadcast.
        socket.broadcast.emit('showmessage', 'Outro usuário foi conectado');
    });

   /**
    * Evento "disconnect" emitido quando o usuário recarregar ou sair da página
    */
   socket.on('disconnect', function(){
      // Resposta do servidor via broadcast.
      socket.broadcast.emit('showmessage', 'Um usuário saiu ou recarregou à página!!!');
   });
});






Detalhando o código:

Linhas&nbsp;#6&nbsp;a #15:&nbsp;é informado a função de callback que será chamada em toda requisição ao node.js na porta 8088.
Linhas&nbsp;#18&nbsp;e&nbsp;#19:&nbsp;são requisitados os dois módulos http e o socket.io. Sendo criado o servidor do node.js utilizando a função "onRequest" e informando para o socket.io escutar a conexão do módulo&nbsp;http.
Linha&nbsp;#22:&nbsp;informando para o servidor qual a porta e IP que este irá ser executado.
Linhas&nbsp;#28&nbsp;e&nbsp;#47:&nbsp;este bloco será executado a toda conexão efetuada com o socket.io através do Client. Note que informamos utilizando o método "on" o nome do evento a ser monitorado e a função de callback que será executada quando esse evento for disparado pelo Client.
Na função de callback utilizando o parâmetro do socket passado na conexão é atachado dois eventos no socket ("userconected" e "disconnect"), desta forma o Server irá monitorar esses dois eventos que serão emitidos pelo Client.
Linhas&nbsp;#32&nbsp;a&nbsp;#38:&nbsp;é informado através do método&nbsp;"on"&nbsp;o monitoramento do evento&nbsp;"userconected"&nbsp;onde este utilizando o método "emit" do socket será enviado uma mensagem para o usuário referente ao socket passado via parâmetro para o evento&nbsp;"connection". Já na linha #37 será enviada uma mensagem para todos os usuários conectados, menos o usuário do socket corrente. O método&nbsp;"broadcast"&nbsp; envia uma mensagem para todos os demais canais/usuários que estão conectados no Server menos o usuário do socket atual.
Linhas&nbsp;#43&nbsp;a&nbsp;#46:&nbsp;é informado através do método&nbsp;"on"&nbsp;o monitoramento do evento&nbsp;"disconnect"&nbsp;onde&nbsp;este irá emitir uma mensagem para os demais usuários conectados informando que o usuário referente ao atual socket saiu da página.
Pelo código conseguimos ver como utilizar o monitoramento dos eventos utilizando os métodos:
- on: para informar o evento a ser monitorado e a função de callback que será executada quando o evento for disparado pelo Client. Note que nenhuma das funções recebem&nbsp;parâmetros&nbsp;pelo Client, mas podemos também informar parâmetros para o Server assim como informamos para o Cliente (linha #34 é um exemplo disso).
- emit: este método irá emitir o evento para o Client/Server. Nele devemos informar no primeiro parâmetro o nome do evento e os demais itens informados serão os&nbsp;parâmetros que o Client/Server irá receber na função de callback.
- broadcast: este atributo utilizando em conjunto com o método "emit" irá emitir o evento para todos os usuários conectados menos o atual usuário.


2º Passo - Criando a estrutura no Client side:&nbsp;neste passo iremos criar uma página HTML para demonstrar o monitoramento dos eventos disparados pelo Server side. Como mencionado no início do poste irei utilizar um servidor Web local para a demonstração do exemplo com socket.io. Então vamos a configuração.

- Crie uma pasta no DOCUMENT_ROOT do seu servidor Web com o nome "socketio_exemplo" crie um arquivo HTML com o nome "socket.html" e com o conteúdo abaixo:


&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Exemplo utilizando socket.io&lt;/title&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
    
    &lt;!-- CSS --&gt;
    &lt;style type="text/css"&gt;
        h2 { 
            color: #439;
            font-size: 120%;
        }
    &lt;/style&gt;
    
    &lt;!-- JS --&gt;
    &lt;script type="text/javascript" src="http://localhost:8088/socket.io/socket.io.js"&gt;&lt;/script&gt; 
    &lt;script type="text/javascript"&gt;
        // Criando a conexão com o Socket.io
        var socket = io.connect('http://localhost:8088',{
             'reconnect': true
            ,'reconnection delay': 500
            ,'max reconnection attempts': 1000
            ,'secure': false
        });

        // Emitindo o evento para o Server
        socket.emit('userconected');

        // Listeners

        /**
         * Monitorando o evento "showmessage" que será disparado pelo Server
         * @param {String} msg Mensagem a ser exibida
         */
        socket.on('showmessage', function(msg){
            var messageEl = document.getElementById('message-info');

            // Exibindo a mensagem enviada
            messageEl.innerHTML += msg;
        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h2&gt;Mensagens do socket.io&lt;/h2&gt;
    &lt;div id="message-info"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;




Detalhando o código:

Neste ponto irei detalhar somente as linhas de código que fazem a mágica acontecer, pois no mais é só HTML e CSS.
Linha&nbsp;#17:&nbsp;nesta linha estamos solicitando o arquivo JS do socket para o Server. Note que utilizamos o mesmo IP e porta que foi informado na configuração do socket no Server.
Linhas&nbsp;#20&nbsp;a&nbsp;#25:&nbsp;neste bloco que estamos criando a conexão com o socket no Server, neste momento que é disparado o evento&nbsp;"connection". Há algumas opções que podemos passar para a criação do socket. Abaixo a informação de cada atributo:
- reconnect (bool): que irá informar se o socket irá tentar se conectar caso perca a conexão com o Server.
- reconnection delay (int):&nbsp;informa o tempo em milissegundos que será o delay da tentativa de conexão.
- max reconnection attemps (int):&nbsp;informa o valor máximo de tentativas de conexão com o Server.
- secure (bool):&nbsp;informando se a conexão com o Server irá utilizar criptografia (conexões HTTPS).
Linha&nbsp;#28:&nbsp;utilizando o método "emit" dispara o evento&nbsp;"userconnected" para o Server.
Linhas&nbsp;#36&nbsp;a&nbsp;#41:&nbsp;neste bloco utilizando o método&nbsp;"on" é informado o monitoramento do evento&nbsp;"showmessage" que será disparado pelo Server passando como parâmetro a mensagem a ser exibida no browser do usuário.
Linha&nbsp;#37:&nbsp;utilizando o método "getElementById" do JS resgatamos a referência da DIV onde iremos inserir o texto da mensagem enviada pelo Server.
Linha&nbsp;#40:&nbsp;utilizando a propriedade "innerHTML" do elemento inserimos o texto que é informado pelo Server.

3º Passo - Rodando o exemplo:&nbsp;para executar o nosso exemplo primeiro temos que iniciar o serviço do node.js através do nosso arquivo&nbsp;"socketio_exemplo.js", assim pelo prompt do Windows vá na pasta de instalação do node.js e execute o comando "node socketio_exemplo.js" (sem&nbsp;aspas) e pressione ENTER.


Iniciando o serviço do node.js com socket.io

Veja a mensagem escrita no console (prompt do Windows) informando que o socket.io foi iniciado.
Agora iremos acessar o nosso arquivo&nbsp;"socket.html" pelo servidor Web no browser digite&nbsp;http://localhost/socketio_exemplo/socket.html&nbsp;exibindo o conteúdo conforme abaixo:


Conteúdo informado no browser

O texto "Usuário conectado no socket!!!" é exibido através do monitoramento feito nas linhas #36 a #41 do arquivo "socket.html".&nbsp;


Mensagens após conexão no socket.io

A imagem acima demonstra as mensagens que estão sendo exibidas no prompt do Window informando o usuário conectado. Note no texto grifado em vermelho. Neste trecho o socket está emitindo uma mensagem para o Client utilizando o evento&nbsp;"showmessage" passando como parâmetro a mensagem a ser exibida no DIV.
Abra outro navegador e digite&nbsp;http://localhost/socketio_exemplo/socket.html&nbsp;será exibido a mensagem "Outro usuário foi conectado" no primeiro browser aberto e no último será exibido a mensagem&nbsp;"Usuário conectado no socket!!!".


Browser conectados no socket.io

Se você olhar novamente para o prompt do Windows verá as mensagens enviadas para os dois sockets conectados.


Console exibindo as mensagens para os sockets conectados

Pelo imagem podemos ver que a mensagem&nbsp;"Usuário conectado no socket!!!" é disparada duas vezes uma para o primeiro browser (Chrome) e outra para o segundo browser (Firefox), já a mensagem&nbsp;"Outro usuário foi conectado" foi enviada somente para o socket já conectado (Chrome).

Sei que esses dois exemplos são simples, mas o principal fundamento deles foram para instruir e informar como utilizar o node.js como um serviço e como podemos utilizar o socket.io para criar aplicações real-time. No próximo poste irei criar um exemplo do jogo "Batalha naval" utilizando node.js e socket.io. Neste exemplo irei utilizar muito dos conceitos que mencionei neste post.
Espero que este seja de grande ajuda para os demais que como eu estão iniciando com node.js.
Obrigado pela leitura e até o próximo post.




Referências

Site oficial do node.js&nbsp;

Site oficial do socket.io&nbsp;

Github socket.io


O que é exatamente o Node.js?&nbsp;

Webnar Node.js com Éder Frances

 SyntaxHighlighter.highlight();