Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare uma empresa Scribd logo
Workshop 
Real-time com Node.js e 
Socket.IO 
Caio Ribeiro Pereira
Sobre 
Entusiasta JavaScript e Node.js 
Web Developer na Concrete Solutions 
Bacharel em Sistemas de Informação 
Blogueiro no udgwebdev.com 
Twitter @crp_underground
meus livros 
http://casadocodigo.com.br
Tópicos do workshop 
Guia 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 JavaScript 
Orientado à 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áveis 
variáveis locais 
var language = "Node.js" // String 
var version = 1.0 // Number 
var isBeta = false // Boolean 
var itens = [1, 2, 3, 4] // Array 
var coord = {x: 10, y: 20} // Object 
var nothing = null // Null 
variáveis globais 
x = 10; // apenas omita o “var" 
window.x = 10; // global para os browsers 
global.x = 10; // global para o Node.js
Condicionais 
if / else 
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!"); 
}
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
Loops 
var 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ções 
declarando uma função 
function soma(a, b) { 
return a + b; 
} 
soma(1, 10); // 11 
declarando uma função anônima 
var multiplica = function(a, b) { 
return a * b; 
} 
multiplica(1, 10); // 10
Criando funções 
auto-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 arrays 
funções básicas de um array 
var itens = []; // Criando array vazio 
itens.length; // Tamanho do array 
itens.push(1); // Inclui um item 
itens.pop(); // Remove e retorna último item 
itens.splice(i, 1); // Remove um item baseado no índice 
itens[i]; // Retorna um item baseado no índice 
itens[0] = 2; // Altera um item baseado no índice 
itens.forEach(); // Itera todos os itens do array.
Criando objetos 
Instanciando objetos simples 
var joao = new Object(); 
joao["nome"] = "João"; 
// ou 
var maria = {}; 
maria["nome"] = "Maria" 
// ou 
var joana = { 
nome: "Joana" 
} 
// Acessando atributos dos objetos 
console.log(joao.nome); // "João" 
console.log(maria.nome); // "Maria" 
console.log(joana.nome); // “Joana"
Criando objetos 
protótipo de um objeto 
// Definição de um protótipo de objeto 
function Usuario(nome, idade) { 
this.nome = nome; 
this.idade = idade; 
} 
// Instanciando um objeto Usuario 
var usuario = new Usuario("João", 40); 
// Acessando atributos do objeto Cliente 
console.log(usuario.nome); // “João” 
console.log(usuario.idade); // 40
Criando objetos 
protó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 Cliente 
var cliente = new Cliente("João", 40); 
console.log(cliente.toString()); // “João:40”
1° Exercício 
Crie 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 usuarios 
var usuarios = []; 
// Adicione os objetos no array “usuarios.push(usuario)" 
// iterando array de usuarios 
usuarios.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 plataforma 
Compatí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.js 
var 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.js 
var 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.js 
var 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 ferramenta 
Gerenciador 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 npm 
npm 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 
Principais funções no servidor 
// 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));
Utilizando Socket.IO 
Criando um projeto do zero com socket.io 
npm init 
npm install socket.io --save
Principais funções do Socket.IO 
Principais funções no cliente 
// Cliente se conectando no servidor socket.io 
var 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));
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> 
Exemplo de cliente socket.io 
<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>
Exercício Final
Microblog 
Crie 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.IO 
var 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!

Mais conteúdo relacionado

Realtime com node.js e socket.io

  • 1. Workshop Real-time com Node.js e Socket.IO Caio Ribeiro Pereira
  • 2. Sobre Entusiasta JavaScript e Node.js Web Developer na Concrete Solutions Bacharel em Sistemas de Informação Blogueiro no udgwebdev.com Twitter @crp_underground
  • 4. Tópicos do workshop Guia 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
  • 5. Aprenda de verdade JavaScript https://developer.mozilla.org/en/docs/Web/JavaScript
  • 7. Características do JavaScript Orientado à 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)
  • 8. Declarando variáveis variáveis locais var language = "Node.js" // String var version = 1.0 // Number var isBeta = false // Boolean var itens = [1, 2, 3, 4] // Array var coord = {x: 10, y: 20} // Object var nothing = null // Null variáveis globais x = 10; // apenas omita o “var" window.x = 10; // global para os browsers global.x = 10; // global para o Node.js
  • 9. Condicionais if / else 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!"); }
  • 10. 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
  • 11. Loops var 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
  • 12. Loops while(true) { console.log("Loop infinito usando while!"); } while do { console.log("Loop infinito usando do…while!"); } while (true); do…while
  • 13. Criando funções declarando uma função function soma(a, b) { return a + b; } soma(1, 10); // 11 declarando uma função anônima var multiplica = function(a, b) { return a * b; } multiplica(1, 10); // 10
  • 14. Criando funções auto-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>
  • 15. Criando arrays funções básicas de um array var itens = []; // Criando array vazio itens.length; // Tamanho do array itens.push(1); // Inclui um item itens.pop(); // Remove e retorna último item itens.splice(i, 1); // Remove um item baseado no índice itens[i]; // Retorna um item baseado no índice itens[0] = 2; // Altera um item baseado no índice itens.forEach(); // Itera todos os itens do array.
  • 16. Criando objetos Instanciando objetos simples var joao = new Object(); joao["nome"] = "João"; // ou var maria = {}; maria["nome"] = "Maria" // ou var joana = { nome: "Joana" } // Acessando atributos dos objetos console.log(joao.nome); // "João" console.log(maria.nome); // "Maria" console.log(joana.nome); // “Joana"
  • 17. Criando objetos protótipo de um objeto // Definição de um protótipo de objeto function Usuario(nome, idade) { this.nome = nome; this.idade = idade; } // Instanciando um objeto Usuario var usuario = new Usuario("João", 40); // Acessando atributos do objeto Cliente console.log(usuario.nome); // “João” console.log(usuario.idade); // 40
  • 18. Criando objetos protó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 Cliente var cliente = new Cliente("João", 40); console.log(cliente.toString()); // “João:40”
  • 19. 1° Exercício Crie 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
  • 20. // Criar objeto “function Usuario(nome, idade)” // Criar método "Usuario.prototype.maiorDeIdade()" // Aqui instancie os 3 usuarios // Crie o array de usuarios var usuarios = []; // Adicione os objetos no array “usuarios.push(usuario)" // iterando array de usuarios usuarios.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
  • 22. 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
  • 23. Sobre a plataforma Compatí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
  • 24. JavaScript server-side Usa o runtime JavaScript V8, a mesma usada pelo Google Chrome https://code.google.com/p/v8
  • 25. 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
  • 26. Non-Blocking vs Blocking Exemplo de blocking threads
  • 27. Non-Blocking vs Blocking Exemplo de Non-blocking Threads
  • 28. Programação assíncrona Node.js usa o EventLoop para processamento assíncrono
  • 30. Primeiro app // server.js var 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
  • 31. Separando html do js // server.js var 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>
  • 32. Criando rotas // server.js var 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!"); });
  • 34. Sobre a ferramenta Gerenciador 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
  • 35. Principais comandos do npm npm 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
  • 36. 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
  • 38. 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
  • 39. Principais funções do Socket.IO Principais funções no servidor // 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));
  • 40. Utilizando Socket.IO Criando um projeto do zero com socket.io npm init npm install socket.io --save
  • 41. Principais funções do Socket.IO Principais funções no cliente // Cliente se conectando no servidor socket.io var 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));
  • 42. 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!"); });
  • 43. Utilizando Socket.IO <html> <body> Exemplo de cliente socket.io <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>
  • 45. Microblog Crie 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
  • 46. microblog // Carregando módulos do http e socket.io // Servidor http que renderiza a página principal // Servidor Socket.IO var 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
  • 47. 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