Neste tutorial, vamos guiá-lo na criação de um painel de dados em tempo real usando o SuperViz, um SDK poderoso para comunicação em tempo real e sincronização de dados. Painéis em tempo real são ferramentas essenciais para monitorar e analisar dados à medida que são gerados, permitindo que os usuários tomem decisões rápidas e informadas com base nas informações mais recentes.
Painel de dados em tempo real
Usaremos dados do mercado de ações do Yahoo Finance como nosso exemplo de fonte de dados. No entanto, os princípios e técnicas que você aprenderá podem ser aplicados a qualquer fonte de dados que você tenha acesso no servidor. Seja para dados financeiros, atualizações climáticas ou atividade de usuários, este tutorial lhe dará as habilidades para criar um painel dinâmico que atualiza em tempo real.
Ao final deste tutorial, você terá um painel totalmente funcional em tempo real que pode ser personalizado e expandido para atender às suas necessidades específicas. Vamos começar!
Pré-requisitos
Para seguir este tutorial, você precisará de uma conta SuperViz e de um token de desenvolvedor. Se já tiver uma conta e um token de desenvolvedor, pode passar para o próximo passo.
Criar uma conta
Para criar uma conta, acesse https://dashboard.superviz.com/register e crie uma conta usando o Google ou um e-mail/senha. É importante observar que, ao usar e-mail/senha, você receberá um link de confirmação que precisará clicar para verificar sua conta.
Obtendo um Token de Desenvolvedor
Para usar o SDK, você precisará fornecer um token de desenvolvedor, essencial para associar as solicitações do SDK à sua conta. Você pode obter tokens de desenvolvimento e de produção do SuperViz no painel de dados.
Copie e salve o token de desenvolvedor, pois você precisará dele nos próximos passos deste tutorial.
Passo 1: Configurando o Servidor com Express.js
O servidor é responsável por buscar dados de ações do Yahoo Finance e transmitir atualizações para o frontend usando o SuperViz.
1. Criar um Novo Projeto e Instalar Dependências
Primeiro, configure um novo projeto Node.js e instale os pacotes necessários para o servidor.
mkdir realtime-dashboard-server
cd realtime-dashboard-server
npm init -y
npm install express body-parser dotenv cors yahoo-finance2 node-fetch
Explicação:
- express: Um framework de aplicação web para configurar o servidor.
- body-parser: Middleware para analisar corpos de requisições JSON.
- dotenv: Carrega variáveis de ambiente a partir de um arquivo
.env
. - cors: Middleware para habilitar o Compartilhamento de Recursos de Origem Cruzada.
- yahoo-finance2: Biblioteca para buscar dados de ações do Yahoo Finance.
- node-fetch: API Fetch para fazer requisições HTTP
2. Configurar o Servidor Express
Crie um arquivo chamado server.js
e configure o servidor.
// server.js
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import dotenv from "dotenv";
import yahooFinance from "yahoo-finance2";
dotenv.config();
const app = express();
app.use(bodyParser.json());
app.use(cors());
const subscriptions = [];
Explicação:
- Express App: Crie uma aplicação Express para lidar com as requisições.
- Middlewares: Use
bodyParser
para análise de JSON ecors
para lidar com requisições de origem cruzada. - Assinaturas: Um array para armazenar assinaturas de ações ativas, identificadas por IDs de sala.
3. Inscrever-se em Atualizações de Ações
Defina um endpoint para se inscrever em atualizações de ações.
app.get('/subscribe', async (req, res) => {
console.log(req.query)
if(!req.query.symbol) {
return res.status(400).json({ error: 'Missing symbol' })
}
try {
const response = await yahooFinance.quote(req.query.symbol)
if(!response) {
return res.status(404).json({ error: 'Symbol not found' })
}
subscriptions.push({
roomId: req.query.roomId,
symbol: req.query.symbol
})
return res.json({
symbol: response.symbol,
name: response.shortName,
price: response.regularMarketPrice,
change: response.regularMarketChange,
changePercent: response.regularMarketChangePercent,
high: response.regularMarketDayHigh,
low: response.regularMarketDayLow,
updatedAt: new Date().toISOString(),
})
} catch (error) {
return res.status(500).json({ error: error.toString() })
}
})
Explicação:
- Endpoint de Inscrição: Um endpoint
/subscribe
permite que os clientes se inscrevam em atualizações de ações fornecendo umsymbol
eroomId
. - API Yahoo Finance: O método
yahooFinance.quote
busca os dados da ação usando o símbolo fornecido. - Response Data: Se a ação for encontrada, adiciona uma assinatura e retorna dados detalhados da ação.
4. Cancelar Inscrição em Atualizações de Ações
Forneça uma maneira de cancelar a inscrição em atualizações de ações.
app.get('/unsubscribe', (req, res) => {
if(!req.query.roomId) {
return res.status(400).json({ error: 'Missing roomId' })
}
if(!req.query.symbol) {
return res.status(400).json({ error: 'Missing symbol' })
}
const index = subscriptions.findIndex(subscription => subscription.roomId === req.query.roomId && subscription.symbol === req.query.symbol)
if(index === -1) {
return res.status(404).json({ error: 'Subscription not found' })
}
subscriptions.splice(index, 1)
return res.json({ message: 'Subscription removed' })
})
Explicação:
- Endpoint de Cancelamento: Um endpoint
/unsubscribe
permite que os clientes removam assinaturas peloroomId
. - Encontrar Assinatura: Localiza a assinatura usando o
roomId
e a remove se encontrada.
5. Enviar Atualizações de Ações para o SuperViz
Use um intervalo de tempo para buscar atualizações de ações e transmiti-las usando a API do SuperViz.
const interval = setInterval(async () => {
for(const subscription of subscriptions) {
try {
const stock = await yahooFinance.quote(subscription.symbol)
if(!stock) return
const data = {
symbol: stock.symbol,
name: stock.shortName,
price: stock.regularMarketPrice,
change: stock.regularMarketChange,
changePercent: stock.regularMarketChangePercent,
high: stock.regularMarketDayHigh,
low: stock.regularMarketDayLow,
updatedAt: new Date().toISOString(),
}
const channelId = 'stock-price'
const response = await fetch(`https://api.superviz.com/realtime/${channelId}/publish`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
secret: process.env.VITE_SUPERVIZ_SECRET_KEY,
client_id: process.env.VITE_SUPERVIZ_CLIENT_ID,
},
body: JSON.stringify({
name: 'stock-update',
data,
})
})
console.log(`Sending data to ${channelId}, stock: ${stock.symbol}`, response.status)
} catch (error) {
console.error(error)
}
}
}, 2000)
Explicação:
- Intervalo: A cada 2 segundos, busca atualizações de ações para todas as assinaturas.
- API SuperViz: Envia dados de ações para a API em tempo real do SuperViz, usando
roomId
echannelId
para direcionar clientes específicos.
6. Iniciar o Servidor
Inicie o servidor para escutar requisições.
app.listen(3000, () => {
console.log("Server is running on <http://localhost:3000>");
});
Explicação:
- Server Listening: O servidor escuta na porta 3000 e registra uma mensagem de confirmação quando está em execução.
Passo 2: Configurando o Frontend com React
O frontend usa React para exibir atualizações de ações em tempo real conectando-se ao SuperViz Real-time.
1. Criar um Novo Projeto React
Inicialize uma nova aplicação React usando o Create React App com TypeScript.
npm create vite@latest
cd realtime-dashboard-frontend
2. Instalar o SDK do SuperViz
Adicione o SuperViz e outros pacotes necessários.
npm install @superviz/realtime luxon uuid
Explicação:
- @superviz/realtime: Biblioteca SuperViz Real-Time para integrar sincronização em tempo real em sua aplicação.
- luxon: Biblioteca DateTime para formatação de datas.
- uuid: Biblioteca para gerar identificadores únicos.
3. Configurar o Tailwind
Neste tutorial, usaremos o framework Tailwind CSS. Primeiro, instale o pacote do Tailwind.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Em seguida, precisamos configurar o caminho do template. Abra tailwind.config.js
na raiz do projeto e insira o seguinte código:
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Depois, precisamos adicionar as diretivas do Tailwind ao arquivo CSS global. (src/index.css)
@tailwind base;
@tailwind components;
@tailwind utilities;
4. Configurar Variáveis de Ambiente
Crie um arquivo .env
no diretório frontend e adicione a chave da API do SuperViz.
VITE_SUPERVIZ_API_KEY=YOUR_SUPERVIZ_API_KEY
VITE_SUPERVIZ_CLIENT_ID=YOUR_SUPERVIZ_CLIENT_ID
VITE_SUPERVIZ_SECRET_KEY=YOUR_SUPERVIZ_SECRET_KEY
Explicação:
- Variáveis de Ambiente: Armazena a chave da API de forma segura usando
.env
e a acessa através de import.meta.env
.
5. Definir Tipos Comuns
Crie um diretório src/common
e adicione um arquivo types.ts
para definir os tipos usados em toda a aplicação.
// src/common/types.ts
export type Stock = {
symbol: string;
name: string;
price: number;
change: number;
changePercent: number;
high: number;
low: number;
updatedAt: string;
};
Explicação:
- Tipo Stock: Define a estrutura para dados de ações, garantindo uso consistente em toda a aplicação.
6. Implementar o Componente Principal da Aplicação
Abra src/App.tsx
e configure o componente principal para lidar com interações do usuário e exibir dados de ações.
import { v4 as generateId } from "uuid";
import { useCallback, useEffect, useState } from "react";
import { Realtime } from "@superviz/realtime/client";
import { Stock } from "./common/types";
import { StockPrice } from "./components/stock-price";
const apiKey = import.meta.env.VITE_SUPERVIZ_API_KEY as string;
export default function App() {
const [stock, setStock] = useState('AAPL')
const [stockList, setStockList] = useState<Stock[]>([])
const subscribeToStock = useCallback(async () => {
const params = {
roomId: ROOM_ID,
symbol: stock,
}
const url = new URL('http://localhost:3000/subscribe')
url.search = new URLSearchParams(params).toString()
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
})
const data = await response.json()
if(!data || stockList.includes(data.symbol)) return
setStockList((prev) => [...prev, data])
}, [stock, stockList])
}
Explicação:
- Gerenciamento de Estado:
stock
contém o símbolo de entrada, enquantostockLis
t
mantém a lista de ações assinadas. - Função de Inscrição: Constrói uma URL com parâmetros de consulta e busca dados de ações do servidor. Atualiza o estado se a ação não estiver já inscrita.
7. Inicializar o SuperViz para Sincronização de Dados em Tempo Real
Adicione a lógica de inicialização para conectar-se ao SuperViz.
const initialize = useCallback(async () => {
const realtime = new Realtime(apiKey, {
participant: {
id: generateId(),
name: "participant-name",
},
});
const channel = await realtime.connect("stock-price");
channel.subscribe("stock-update", (data) => {
console.log("New channel event", data);
if (typeof data === "string") return;
setStockList((prev) => {
return prev.map((stock) => {
const newStock = data.data as Stock;
if (stock.symbol === newStock?.symbol) {
return newStock;
}
return stock;
});
});
});
}, []);
Explicação:
- Inicialização do SuperViz: Conecta-se à sala do SuperViz usando uma chave API e detalhes da sala. Adiciona o componente Realtime para lidar com eventos em tempo real.
- Assinatura em Tempo Real: Assina
stock-update
de ações, atualizando a lista de ações com novos dados.
8. Renderizar os Componentes da UI
Finalize o componente App
renderizando a interface do usuário.
return (
<div className="w-full h-full bg-gray-200 flex items-center justify-center flex-col">
<header className="w-full p-5 bg-purple-400 flex items-center justify-between">
<div>
<h1 className="text-white text-2xl font-bold">
Realtime Data Dashboard
</h1>
</div>
<div>
<input
type="text"
value={stock}
onChange={(e) => setStock(e.target.value)}
className="p-2 border border-gray-400 rounded-md focus:outline-none focus:border-purple-400"
/>
<button
onClick={subscribeToStock}
className="p-2 bg-purple-500 text-white rounded-md ml-2 focus:outline-none"
>
Subscribe
</button>
</div>
</header>
<main className="flex-1 p-20 flex w-full gap-2">
{stockList.map((stock) => (
<StockPrice key={stock.symbol} stock={stock} />
))}
</main>
</div>
);
Explicação:
- Estrutura da UI: A UI contém um campo de entrada para símbolos de ações e um botão de inscrição. O componente
StockPrice
é usado para exibir os detalhes de cada ação. - Atualizações de Estado: O evento
onChange
atualiza a entrada de ações, enquanto clicar no botão aciona a lógica de inscrição.
9. Implementar o Componente StockPrice
Crie um diretório src/components
e adicione um arquivo stock-price.tsx
para definir como cada ação é exibida.
// src/components/stock-price.tsx
import { Stock } from "../common/types";
import { DateTime } from "luxon";
type Props = {
stock: Stock;
};
export function StockPrice({ stock }: Props) {
const formatPrice = (price: number) => {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
}).format(price);
};
const formatDateTime = (date: string) => {
return DateTime.fromISO(date).toFormat("DD HH:mm:ss");
};
return (
<div className="p-6 border border-solid border-gray-300 bg-white min-w-40 rounded-xl h-fit shadow-md">
<h1>{stock.name}</h1>
<p>{stock.symbol}</p>
<p>Current Price: {formatPrice(stock.price)}</p>
<p>Lower Price: {formatPrice(stock.low)}</p>
<p>Higher Price: {formatPrice(stock.high)}</p>
<p>Updated At: {formatDateTime(stock.updatedAt)}</p>
</div>
);
}
Explicação:
- Componente StockPrice: Exibe informações detalhadas da ação, incluindo o nome, símbolo, preço atual, preços mínimo/máximo e timestamp de atualização.
- Funções de Formatação:
formatPrice
eformatDateTime
garantem que os preços e datas sejam exibidos de maneira amigável ao usuário.
Passo 3: Executando a Aplicação
Para iniciar a aplicação, execute este comando no terminal:
npm run dev
Esse comando iniciará tanto o servidor quanto a aplicação frontend.
Você pode acessar a aplicação frontend em http://localhost:5173
e o servidor em http://localhost:3000
.
Resumo
Neste tutorial, construímos um painel de ações em tempo real usando SuperViz, Express.js e React. O servidor busca dados de ações da Yahoo Finance e envia atualizações para clientes inscritos usando a API em tempo real do SuperViz. O frontend se inscreve para receber atualizações de ações, exibindo-as em uma interface de usuário responsiva. Seguindo esses passos, você pode personalizar o painel de dados para acompanhar diferentes ações, adicionar mais recursos e implantá-lo em um ambiente de produção.
Sinta-se à vontade para consultar o código completo no repositório do GitHub para mais detalhes.
e assista ao vídeo a seguir: