Chat em tempo real com suporte a múltiplos servidores WebSocket, histórico persistente e indicador de digitação.
Construído com Flask + Flask-SocketIO no backend, Flask no frontend e PostgreSQL como banco de dados. Utiliza Redis como message queue para sincronizar mensagens entre instâncias do servidor.
frontend/ → Cliente Flask (porta definida por PORT)
│ client.py → Rotas HTTP (login, chat)
│ requirements.txt
│ templates/ → HTML (login.html, chat.html)
│ static/ → JS e CSS da interface
│
backend/ → Servidor WebSocket (porta definida por PORT)
│ server.py → SocketIO: histórico, mensagens, typing
│ requirements.txt
A comunicação entre frontend e backend acontece via WebSocket (Socket.IO). O frontend tenta se conectar a cada servidor listado em SOCKET_SERVERS em sequência, reconectando automaticamente em caso de queda.
- Mensagens em tempo real via WebSocket
- Histórico de mensagens persistido em banco de dados (carregado ao conectar)
- Indicador de "digitando..." para outros participantes
- Fila de envio garantindo ordem das mensagens
- Fallback automático entre múltiplos servidores WebSocket
- Interface responsiva em português
- Python 3.10+
- PostgreSQL
- Redis
git clone https://github.com/seu-usuario/socketext.git
cd socketextBackend:
cd backend
pip install -r requirements.txtFrontend:
cd frontend
pip install -r requirements.txtCrie um arquivo .env em cada pasta conforme as seções abaixo.
CREATE TABLE messages (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
message TEXT NOT NULL,
sent_at TIMESTAMP NOT NULL DEFAULT NOW()
);Backend (produção com Gunicorn + gevent):
cd backend
gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 -b 0.0.0.0:$PORT server:appBackend (desenvolvimento local):
cd backend
python server.pyFrontend:
cd frontend
python client.pyAcesse http://localhost:8000, digite seu nome e comece a conversar.
| Variável | Descrição |
|---|---|
INTERNAL_DATABASE_URL |
URL de conexão PostgreSQL usada em produção (rede interna) |
EXTERNAL_DATABASE_URL |
URL de conexão PostgreSQL usada em modo DEBUG (acesso externo) |
DEBUG |
true usa EXTERNAL_DATABASE_URL; false usa a interna |
SECRET_KEY |
Chave secreta do Flask — use uma string longa e aleatória |
REDIS_URL |
URL de conexão Redis usada como message queue pelo SocketIO |
PORT |
Porta em que o servidor WebSocket irá escutar (ex: 5000) |
Exemplo:
INTERNAL_DATABASE_URL=postgresql://user:senha@host-interno/nome_do_banco
EXTERNAL_DATABASE_URL=postgresql://user:senha@host-externo/nome_do_banco
DEBUG=false
SECRET_KEY=troque-por-uma-chave-segura-e-aleatoria
REDIS_URL=redis://default:senha@host-redis:porta
PORT=5000| Variável | Descrição |
|---|---|
SECRET_KEY |
Mesma chave usada no backend (para sessões Flask) |
SOCKET_SERVERS |
Lista de URLs dos servidores WebSocket, separadas por vírgula |
PORT |
Porta em que o frontend irá escutar (ex: 8000) |
Exemplo:
SECRET_KEY=troque-por-uma-chave-segura-e-aleatoria
SOCKET_SERVERS=http://192.168.1.10:5000,http://192.168.1.10:5001
PORT=8000O frontend tenta conectar aos servidores na ordem listada. Se o primeiro falhar, tenta o próximo automaticamente.
- New → Web Service, conecte ao repositório
- Root Directory:
backend - Build Command:
pip install -r requirements.txt - Start Command:
gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 -b 0.0.0.0:$PORT server:app - Em Environment Variables, adicione as variáveis do
backend/.env. O Render injetaPORTautomaticamente — não é necessário definir manualmente.
- New → Web Service, conecte ao repositório
- Root Directory:
frontend - Build Command:
pip install -r requirements.txt - Start Command:
python client.py - Em Environment Variables, adicione as variáveis do
frontend/.env. EmSOCKET_SERVERS, use a URL pública gerada pelo Render para cada instância do backend (ex:https://socketext-backend.onrender.com).
O
-w 1no Gunicorn é obrigatório com WebSockets — múltiplos workers quebrariam as conexões persistentes. Para escalar, suba múltiplos serviços apontando para o mesmo Redis.
Todas as instâncias devem apontar para o mesmo Redis — ele sincroniza as mensagens entre elas independentemente de qual instância o cliente estiver conectado.
# Instância 1 (usa PORT=5000 do .env)
gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 -b 0.0.0.0:$PORT server:app
# Instância 2
PORT=5001 gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 -b 0.0.0.0:$PORT server:appListe todas as URLs no SOCKET_SERVERS do frontend.
socketext/
├── backend/
│ ├── server.py
│ ├── requirements.txt
│ └── .env
├── frontend/
│ ├── client.py
│ ├── requirements.txt
│ ├── .env
│ ├── templates/
│ │ ├── login.html
│ │ └── chat.html
│ └── static/
│ ├── script.js
│ └── style.css
└── README.md