Pesquisar

Postagens populares

terça-feira, 5 de julho de 2011

Nodejs - Instalando e criando um servidor HTTP.


Objetiva-se apresentar um estudo a respeito de Node.js e Socket.IO voltado ao desenvolvimento de servidores web. Descreve-se um histórico do seu surgimento bem como os conceitos de servidores, javascript e comunicação em rede. Uma aplicação de exemplos é apresentada, assim como as aplicações práticas e comerciais. É relatado brevemente estudos realizados na área e feita as conclusões.

Palavras chave: Node.js, Socket.IO, Javascript, Javascript do lado servidor, Comunicação em Rede, Comunicação assíncrona, Google V8 JavaScript Engine

1. Introdução
Toda aplicação que busca interatividade entre seus usuário necessita de uma aplicação que funciona como servidor de processamento. Servidores de processamentos podem ser inscritos nas mais variadas linguagens, o javascript entrou nessa lista deixando de ser visto unicamente como uma linguagem de browser e que é interpretada unicamente no lado do cliente para uma ser uma alternativa poderosa na construção de servidores web.
Neste trabalho será descrito de forma resumida todos os componentes que tornam o javascript uma das melhores opções para esse tipo de tarefa.
No item 2 será apresentado um resumo histórico sobre o aparecimento do Node.js e do Socket.io.


2. Histórico
Inicialmente deve-se apresentar o Google V8 JavaScript Engine que é um interpretador de javascript desenvolvido pelo Google e que nativamente é embarcado no Google Chrome e que e encabeçado pelo programador Lars Bak [Lessen, 2008][Minto, 2009]. O V8 é escrito em C++, Javascript e Assemble e que opera nos mais diversos sistemas gerente, como Microsoft Windows, Mac OS X, Linux, FreeBSD, Android, webOS. Ele tem seu montador baseado no montador do Stronktalk “Smalltalk” que aumenta a performance compilando o javascript para linguagem de maquina em vez de executar algum tipo de bytecode ou interpretando e usando técnicas de otimização como inline caching, com tudo isso, códigos javascript rodando em V8 tem uma eficiência e velocidade comparados a um binário compilado. Possui também um coletor de lixo “garbage collector” no modelo stop-the-world collector. [Seeley, 2008]
Node.js é um framework para o V8 Engine em plataformas UNIX “unix-like” destinada a criação de programas web de forma escalável. Criada por Ryan Dahl em 2009 patrocinada por uma empresa chamada Joyent [1][2]. Node.js tem um propósito similar ao Twisted para o Python, Perl Object Environment para o Perl, e EventMachine para o Ruby e que ao contrário da maioria dos códigos JavaScript, não é executado em um navegador da Web, e sim relacionado às server-side JavaScript [3].

3. Instalando e compreendendo o Node.js
Para instalar e desenvolver aplicações usando o Node.js recomenda-se o uso de plataformas unix. Siga os passos encontrados no link abaixo:


Automaticamente quando Nodo.js for instalado o V8 estará embutido a ele, dessa forma é possível acessar um console javascript onde será possível realizar qualquer tipo de operação.
Para iniciar o console node basta digitar: node

Figura 1 – Exemple de comandos no terminal de comandos do Node.js

  Qualquercomando javascript nativo pode ser executado no console, operações matemáticas, formação de funções. Pode-se também executar códigos javascript escritos em um arquivo texto com a extensão .js com o comando node nome_do_arquivo.js. Para encerrar o console deve-se pressionar CTRL+C.
Juntamente com a instalação do Node.js são instalados alguns módulos padrões compilados que podem ser instanciados utilizando a função require(“nome_do_modulo.js”); . Os módulos padrões, conhecidos como Core Modules “Módulos de Núcleo”, estão armazenados na pasta /lib que fica na raiz da pasta de instalação do Node.js. Ao passar o nome do módulo para a função require pode-se ocultar a sua extensão, no caso de não ser encontrado o modulo, automaticamente é feito uma busca com a extensão .js ou .node.

//aquivo teste.js
var circulo = require('./circulo.js');
console.log( 'A área de um circulo de raio 4 é: '
           + circulo.area(4));
Código 1 – Código do arquivo teste.js.

No exemplo Código 1 é mostrado um exemplo de código onde é feita uma chamada a um módulo customizado que calcula a área e a circunferência de um círculo passando como parâmetro o seu raio.


//arquivo circulo.js
var PI = Math.PI;

exports.area = function (r) {
  return PI * r * r;
};

exports.circunferencia = function (r) {
  return 2 * PI * r;
};
Código 2 – Código fonte do módulo customizado circulo.

Para módulos customizados as funções que servirão para realizar tarefas referentes ao mesmo devem ser adicionados ao objeto especial exports, só assim poderão ser acessados.

4. Criando um servidor Web
Para a criação de um servidor web é necessário instanciar o módulo de núcleo HTTP, este módulo serve para criar uma abstração do protocolo HTTP, que é em geral é de difícil manejo. Este módulo atualmente não suporta todos os recursos do protocolo, em particular já prove mensagens chunk-encoded, que possibilita passar as mensagens e o cabeçalho em partes, a interfaçe também é sempre cuidadosa em nunca repassar toda a requisição e a resposta, para que o usuário seja capaz de manipular os dados.

var http = require("http");

var servidor = http.createServer(
function(requisicao, resposta){
resposta.writeHead(200, {"content-type" : "text-plain"});
resposta.write("");
resposta.write("
Hello World!
", "utf8");
resposta.write("");
resposta.end();
}
);

servidor.listen(8080);
console.log("Servidor rodando em http://127.0.0.1:8080");
Código 3 – Código para criar um servidor HTTP



No código 3, após instanciar um objeto HTTP a uma variável global de nome http, foi utilizado método createServer([requestListener]) que leva como parâmetro uma função interna que tratará todas as requisições, e retorna um objeto web server. Essa inner function é automaticamente adicionada ao evento request, evento que é chamado sempre que é feito uma requisição ao servidor, e deve ser composta com dois parametros distintos, o primeiro que será uma instancia do objeto http.ServerRequest e o segundo do objeto http.ServerResponse, são dois objetos que são dinamicamente criados ao objeto http. Estes objetos servem para coletar informações passadas do usuário para o servidor, no caso do http.ServerRequest e para manipular o retorno ao usuário, http.ServerResponse.

O objeto http.ServerResponse possui alguns métodos para tratar a resposta que será enviada ao solicitante, como:

writeHead(statusCode, [reasonPhrase], [headers])
      • statusCode, é um código HTTP de três digitos referente ao estado da conexão.
      • [reasonPhrase], parametro para criar labels.
      • [headers], carrega as opções do cabeçalo, podem também serem estes atribuidos ao objeto response usando o metodo setHeader(name, value).
write(chunk, [encoding])
      • chunk, texto ou variável contendo o testo de resposta.
      • encoding, determina o tip de codificação do testo, só terá efeito caso o chunk for um texto, exemplo: encoding='utf8'.
end([chunk], [encoding])
      • Este método serve para indicar ao servidor que toda a mensagem de resposta foi enviada, nunca deve ser chamada antes de writeHead(), e tem os mesmos parametros de write().
Por fim para completar a criação do servidor web é necessário configurar o objeto web server para escutar em uma determinada porta, podendo usar o método listen(port, [hostname], [callback]), tem como parâmetros o endereço numérico da porta, o nome do servidor e uma função de callback, essa função é acionada sempre que o servidor é associado a porta em questão.

Para o exemplo do servidos foi utilizado também o objeto console, ele faz parte de alguns objetos que estão disponíveis em todos os módulos, são conhecidos como objetos globais. Este objeto serve para imprimir mensagens ao stdout e stderr e conta com alguns simples métodos:
    • log([text]) ou info([text]), imprime mensagens de log no console.
    • warn([text], imprime uma mensagem de alerta no console.
    • error([text], Imprime uma mensagem de erro no console
    • dir(object), Imprime no console uma descrição do objeto passado por parâmetro em notação JSON.
    • time(label) e timeEnd(label), imprime no console uma contagem de tempo percorrido durante a chamada de time até a chamada de timeEnd, do referido label referenciado.

Nenhum comentário: