Workshop Real-time com Node.js e
Socket.IOCaio Ribeiro Pereira
SobreEntusiasta JavaScript e Node.js
Web Developer na Concrete Solutions
Bacharel em Sistemas de Informação
Blogueiro no udgwebdev.com
Twitter @crp_underground
Tópicos do workshopGuia rápido JavaScript
Exercícios de JavaScript
Introdução Node.js
Programando com Node.js
Introdução NPM (Node Package Manager)
Brincando com Socket.IO
Exercício final: microblog realtime
Aprenda de verdade JavaScript
https://developer.mozilla.org/en/docs/Web/JavaScript
Guia rápido JavaScript
Características do JavaScriptOrientado à protótipo de objetos
Fracamente tipado ou tipagem fraca
Linguagem interpretada
Presente nos browsers desde o início da internet
Manipula objetos JSON (JavaScript Object Notation)
Declarando variáveisvar language = "Node.js" // Stringvar version = 1.0 // Numbervar isBeta = false // Booleanvar itens = [1, 2, 3, 4] // Arrayvar coord = {x: 10, y: 20} // Objectvar nothing = null // Null
variáveis locais
x = 10; // apenas omita o “var"window.x = 10; // global para os browsersglobal.x = 10; // global para o Node.js
variáveis globais
Condicionais
var nota = 10;if (nota == 10) { console.log("Parabéns você tirou nota 10!");} else if (nota >= 7 && nota < 10) { console.log("Parabéns você passou no curso.");} else if (nota >= 4 && nota < 7) { console.log("Calma cara, ainda da pra recuperar!"); } else { console.log("Pois é, infelizmente você pegou DP!");}
if / else
Condicionais
var fruta = "maçã";switch (fruta) { case: "maçã" console.log("Maçã custa R$ 1,00"); break; case: "uva" console.log("Uva custa R$ 0,50"); break; default: console.log("Demais frutas custam R$ 1,50");}
switch case
Loopsvar cores = ["vermelho", "azul", "branco"];for (var i = 0; i < cores.length; i++) { console.log(cores[i]);}
for clássico
var cores = ["verde", "amarelo", "azul"];cores.forEach(function(cor) { console.log(cor); });
forEach
Loops
while(true) { console.log("Loop infinito usando while!");}
while
do { console.log("Loop infinito usando do…while!");} while (true);
do…while
Criando funçõesfunction soma(a, b) { return a + b; }soma(1, 10); // 11
declarando uma função
declarando uma função anônimavar multiplica = function(a, b) { return a * b; }multiplica(1, 10); // 10
Criando funçõesauto-execução de função anônima
<html> <body> <p>JavaScript is awesome!</p> <script> (function() { var p = document.querySelector("p"); alert(p.textContent); })(); </script> </body></html>
Criando arraysfunções básicas de um array
var itens = []; // Criando array vazioitens.length; // Tamanho do arrayitens.push(1); // Inclui um itemitens.pop(); // Remove e retorna último itemitens.splice(i, 1); // Remove um item baseado no índiceitens[i]; // Retorna um item baseado no índiceitens[0] = 2; // Altera um item baseado no índiceitens.forEach(); // Itera todos os itens do array.
Criando objetosInstanciando objetos simples
var joao = new Object();joao["nome"] = "João";// ouvar maria = {};maria["nome"] = "Maria"// ouvar joana = { nome: "Joana" }// Acessando atributos dos objetosconsole.log(joao.nome); // "João"console.log(maria.nome); // "Maria"console.log(joana.nome); // “Joana"
Criando objetosprotótipo de um objeto
// Definição de um protótipo de objetofunction Usuario(nome, idade) { this.nome = nome; this.idade = idade;}
// Instanciando um objeto Usuariovar usuario = new Usuario("João", 40);// Acessando atributos do objeto Cliente console.log(usuario.nome); // “João” console.log(usuario.idade); // 40
Criando objetosprotótipo de objeto com métodos
function Cliente(nome, idade) { this.nome = nome; this.idade = idade;}Cliente.prototype.toString = function() { return this.nome + ":" + this.idade; };
// Executando o método toString do Clientevar cliente = new Cliente("João", 40);console.log(cliente.toString()); // “João:40”
1˚ ExercícioCrie um protótipo de objeto "Usuario" com os atributos nome e idade.
Neste objeto crie também o método: "Usuario.prototype.maiorDeIdade()" que deve retornar verdadeiro se a idade for maior ou igual 18.
Após prototipar o objeto, instancie 3 usuarios, com os seguintes dados:
Nome: Joao - idade: 20
Nome: Joana - idade: 10
Nome: Maria - idade: 18
Crie um array de usuarios e inclua os 3 objetos nele;
Por último, implemente um loop para iterar o array de usuarios, neste loop deve ser impreso somente o nome dos usuarios que são maiores de idade;
Salve o código no arquivo: app.js
// Criar objeto “function Usuario(nome, idade)”
// Criar método "Usuario.prototype.maiorDeIdade()"
// Aqui instancie os 3 usuarios
// Crie o array de usuariosvar usuarios = [];
// Adicione os objetos no array “usuarios.push(usuario)"
// iterando array de usuariosusuarios.forEach(function(usuario) { // imprima somente usuarios maiores de idade // Para imprimir execute "console.log(usuario.nome)"});
1˚ Exercício - Dicas
Para rodar o código, execute o comando: node app.js
Introdução
Plataforma baixo-nível para webapps
JavaScript server-side
Non-Blocking Threads
Programação assíncrona e síncrona
Programação orientado à eventos
Desenvolvimento modular
Sobre a plataformaCompatível nativamente com protocolos:
http - webapps
https - webapps segura
tcp/udp - redes locais e intranets
dns - domain servers
websockets - conexão real-time
Também trabalha com outros protocolos via 3rd-party
JavaScript server-side
Usa o runtime JavaScript V8, a mesma usada pelo Google Chrome
https://code.google.com/p/v8
Non-Blocking Threads
Node.js é single-thread, mas é assíncrono
Não existe dead-locks, afinal é single-thread
Por ser single-thread consume menos RAM
Node.js faz I/O em non-blocking threads
Non-Blocking vs Blocking
Exemplo de blocking threads
Non-Blocking vs Blocking
Exemplo de Non-blocking Threads
Programação assíncrona
Node.js usa o EventLoop para processamento assíncrono
Programando com Node.js
Primeiro app// server.jsvar http = require("http");
var server = http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html"}); res.write("<h1>Primeiro app Node.js!</h1>"); res.end();});
server.listen(1337, function() { console.log("Servidor web no ar!");});
Para rodar o servidor execute o comando: "node server.js”
acesse no browser: http://localhost:3000
Separando html do js// server.jsvar http = require("http");var fs = require("fs");var server = http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html"}); fs.readFile("./index.html", function(err, html) { res.end(html); });});server.listen(1337, function() { console.log("Servidor web no ar!"); });
// index.html<html> <body> <h1>Meu primeiro app Node.js</h1> </body></html>
Criando rotas// server.jsvar http = require("http");var fs = require("fs");var server = http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html"}); if (req.url == "/") { fs.readFile("./index.html", function(err, html) { res.end(html); }); } else { fs.readFile("./404.html", function(err, html) { res.end(html); }); }});server.listen(1337, function() { console.log("Servidor web no ar!");});
Introdução
Sobre a ferramentaGerenciador de dependência do Node.js
Hospeda +100k módulos open-source
21 milhões de download por dia!
Integrado no Node.js desde a versão 0.6.0
Site oficial: https://npmjs.org
Principais comandos do npmnpm init - Cria um *package.json
npm install - Instala um módulo
npm remove - Remove um módulo
npm update - Atualiza versão do módulo
Veja mais comandos do npm: https://npmjs.org/doc
Anatomia do package.json{ “name”: “nome-do-modulo”, “description”: “Descrição do que é este módulo.”, “version”: “1.0.0”, “private”: false, “author”: “Nome <e-mail>”, “homepage”: “homepage do módulo”, “dependencies”: { “nome-do-modulo1”: “1.0.0”, “nome-do-modulo2”: “~1.0.0”, “nome-do-modulo3”: “>=1.0.0" }}
Mais detalhes sobre o package.json: https://npmjs.org/doc/files/package.json.html
Brincando com Socket.IO
Sobre o Socket.IO módulo Node.js para interação real-time
utiliza os transports:
WebSockets
FlashSockets
Ajax LongPolling
cross-browser (inclusive IE6+)
site oficial: http://socket.io
Principais funções do Socket.IO // Evento que ocorre quando um novo cliente se conecta.io.on("connection", function(client));
// Servidor envia mensagem para o cliente.client.emit("evento-para-cliente", data);
// Servidor envia mensagem para os demais clientes.client.broadcast.emit("evento-para-clientes", objeto);
// Evento que ocorre quando um cliente se desconecta.client.on("disconnect", function())
// Evento que o servidor escuta uma ação do cliente.client.on("evento-para-servidor", function(data));
Principais funções no servidor
Utilizando Socket.IO
npm initnpm install socket.io --save
Criando um projeto do zero com socket.io
Principais funções do Socket.IO
// Cliente se conectando no servidor socket.iovar socket = io("http://dominio-do-servidor");
// Cliente envia mensagem para o servidor.socket.emit("evento-para-servidor", objeto);
// Cliente escuta evento que é acionado pelo servidor.socket.on("evento-do-servidor", function(data));
Principais funções no cliente
Utilizando Socket.IO Exemplo de servidor socket.io
var http = require("http");var socketio = require("socket.io");var fs = require("fs");var server = http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html"}); fs.readFile("./index.html", function(err, data) { res.end(data); });});var io = socketio(server);io.on("connection", function(socket) { var address = socket.handshake.address; socket.emit("address", address); socket.broadcast.emit("address", address);});server.listen(1337, function() { console.log("Servidor socket.io no ar!");});
Utilizando Socket.IO <html> <body> <h1>Visitantes online</h1> <script src="/socket.io/socket.io.js"></script> <script> var socket = io("http://localhost:1337"); socket.on("address", function(address) { var p = document.createElement("p"); p.textContent = address; document.body.appendChild(p); }); </script> </body></html>
Exemplo de cliente socket.io
Exercício Final
MicroblogCrie um servidor para um microblog que escute a porta 1337, ele deve renderiza a página principal (ver próximo slide) e iniciar o servidor socket.io.
Dentro do evento io.on(“connection”) crie o evento socket.on(“new-msg”) para o servidor escutar as mensagens enviadas pelos clientes.
Ao receber uma nova mensagem do evento “new-msg” reenvie a mensagem do cliente para os demais clientes, usando as funções socket.emit e socket.broadcast.emit
microblog// Carregando módulos do http e socket.io
// Servidor http que renderiza a página principal
// Servidor Socket.IOvar io = socketio(server);io.on("connection", function(socket) {
socket.on("new-msg", function(msg) { // Reenviar msg para os clientes });
});
// Iniciar listen do servidor http
Dicas de como criar o server-side do microblog
microblog<html> <head> <script src="/socket.io/socket.io.js"></script> <script> var socket = io("http://localhost:1337"); var button = document.querySelector("button"); button.on("click", function(e) { var msg = document.querySelector("input").value; socket.emit("new-msg", msg); }); socket.on("update-timeline", function(data) { var p = document.createElement("p"); p.textContent = data; document.body.appendChild(p); }); </script> </head> <body><input type="text"><button>Enviar</button></body></html>
Client-side do microblog
Obrigado!