, load = require('express-load')
, error = require('./middleware/error');
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.cookieParser('ntalk'));
app.use(express.session());
app.use(express.json());
app.use(express.urlencoded());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
app.use(error.notFound);
app.use(error.serverError);
Vamos testar o nosso código? Reinicie o servidor e, no browser, digite pro-
positalmente uma nome de uma rota que não exista na aplicação, por exemplo:
58
Casa do Código
Capítulo 5. Dominando o Express
http://localhost:3000/url-errada . Esta foi a renderização da tela de erro para página não encontrada (erro 404).
Figura 5.3: Tela de erro 404.
E para testar a página de erro interno do servidor? Esta tela somente será exi-
bida em casos de erros graves no sistema. Para forçar
um simples bug no sistema,
remova um filtro da rota /contatos, forçando o bug que ocorria na seção anterior que falávamos sobre a implementação de filtros.
Figura 5.4: Tela de erro 500.
Parabéns! Agora temos uma aplicação que cadastra, edita, exclui e lista conta-
tos. Utilizamos o padrão de rotas REST, criamos um simples controle de login que
mantém o usuário na sessão, implementamos filtros para barrar acesso de usuários
não autenticados e pra finalizar, implementamos a renderização de páginas de er-
59
5.5. Indo além: criando páginas de erros amigáveis
Casa do Código
ros amigáveis afinal erros inesperados podem ocorrer em nossa aplicação e seria
desagradável o usuário ver informações complexas na tela.
60
Capítulo 6
Programando sistemas real-time
6.1
Como funciona uma conexão bidirecional?
Este capítulo será muito interessante, pois falaremos sobre um assunto emergente
nos sistemas atuais que está sendo largamente utilizado no Node.js. Estou falando
sobre desenvolvimento de aplicações real-time.
Tecnicamente, estamos falando de uma conexão bidirecional, que, na prática, é
uma conexão que se mantém aberta (connection keep-alive) para clientes e servidores
interagirem em uma única conexão. A vantagem disso fica para os usuários, pois a
interação no sistema será em tempo real, trazendo uma experiência de usuário muito
melhor.
6.2. Conhecendo o framework Socket.IO
Casa do Código
Figura 6.1: Imagem explicando sobre conexão bidirecional.
O Node.js se tornou popular por oferecer bibliotecas de baixo nível que supor-
tam diversos protocolos (HTTP, HTTPS, FTP, DNS, TCP, UDP e outros). O recente
protocolo WebSockets também é compatível com Node.js e ele permite desenvolver
sistemas de conexão persistente utilizando Javascript tanto no cliente quanto no ser-
vidor.
Infelizmente o único problema em utilizar este protocolo, é que nem todos os
browsers suportam esse recurso, tornando inviável desenvolver uma aplicação real-
time cross-browser.
6.2
Conhecendo o framework Socket.IO
Diante desse problema, nasceu o Socket.IO. Ele resolve a incompatibilidade entre o
WebSockets com os navegadores antigos, emulando, por exemplo, Ajax long-polling
ou outros transports de comunicação em browsers que não possuem WebSockets, de
forma totalmente abstraída para o desenvolvedor. Seu site oficial é: (http://socket.io) Figura 6.2: Framework Socket.IO.
62
Casa do Código
Capítulo 6. Programando sistemas real-time
O Socket.IO funciona da seguinte maneira: é incluído um script no cliente que
detecta informações sobre o browser do usuário para definir qual será a melhor co-
municação com o servidor. Os transports de comunicação que ele executa são:
1) WebSocket;
2) Adobe Flash Socket;
3) AJAX long polling;
4) AJAX multipart streaming;
5) Forever iframe;
6) JSONP Polling;
Se o navegador do usuário possuir compatibilidade com WebSockets ou FlashSoc-
kets (utilizando Adobe Flash Player do navegador), será realizada uma comunicação
bidirecional. Caso contrário, será emulada uma comunicação unidirecional, que em
curtos intervalos de tempo faz requisições AJAX no servidor. É claro que o desem-
penho é inferior, porém garante compatibilidade com browsers antigos e mantém o
mínimo de experiência real-time para o usuário. O mais interessante de tudo isso é
que programar utilizando o Socket.IO é muito simples e toda decisão complexa é ele
que faz, simplificando a vida o desenvolvedor.
6.3
Implementando um chat real-time
Vamos ver como funciona na prática? Criaremos o web chat no ntalk, com o qual
o usuário enviará mensagens para os usuários online da agenda de contatos. Inte-
graremos o frameworks: Socket.IO no Express. Primeiro, instalaremos o módulo
atualizando o package.json:
"dependencies": {
"express": "3.4.7",
"express-load": "1.1.8",
"ejs": "0.8.5",
"socket.io": "0.9.16"
}
63
6.3. Implementando um chat real-time
Casa do Código
Utilizaremos
a versão 0.9.16 do Socket.IO, agora vamos instalá-lo executando
no console: npm install
Vamos adaptar o app.js com o novo módulo. A função listen do servidor web
será realizada via módulo http através da função server.listen(3000) para