Preços

Visão geral do projeto

Arquivos-fonte

Esta página foi gerada com base nos seguintes arquivos-fonte:

O gochat é um sistema de mensageria instantânea (IM) leve, implementado inteiramente em Go puro, projetado para oferecer comunicação em tempo real com suporte a mensagens privadas e broadcast em salas. O sistema destaca-se pela arquitetura modular baseada em RPC, permitindo escalabilidade horizontal de cada camada independentemente. Com suporte simultâneo a conexões WebSocket e TCP, o gochat utiliza etcd para descoberta de serviços e Redis como transporte de mensagens, criando uma solução adequada para cenários que exigem comunicação bidirecional de baixa latência (readme.md:19-26).

O projeto foi desenvolvido com foco em simplicidade de deployment e clareza arquitetural, oferecendo Docker para construção unificada do ambiente e compilação cruzada nativa do Go para múltiplas plataformas. A estrutura de diretórios separa claramente as responsabilidades entre camadas de conexão, lógica de negócio, API REST e consumo de tarefas, facilitando a manutenção e extensão do sistema (readme.md:1-12).

Introdução e Características do Sistema

O gochat posiciona-se como uma solução de IM (Instant Messaging) de código aberto que prioriza leveza e clareza arquitetural. O sistema suporta dois modos principais de comunicação: mensagens privadas (diretas entre usuários) e broadcast de salas (mensagens entregues a todos os participantes de uma sala). A comunicação entre camadas ocorre exclusivamente via RPC, utilizando a biblioteca rpcx, o que permite que cada componente seja escalado horizontalmente de forma independente conforme a demanda (readme.md:19-26).

Características Principais

CaracterísticaDescriçãoBenefício
Go PuroImplementação 100% em Go sem bindings CCompilação cruzada simples, binários estáticos
WebSocket + TCPSuporte simultâneo a ambos os protocolosFlexibilidade para diferentes tipos de clientes
RPC entre camadasComunicação via rpcx com etcdEscalabilidade horizontal transparente
Redis como message brokerFilas para desacoplamento de produtores/consumidoresSubstituível por Kafka/RabbitMQ em produção
Descoberta de serviçoetcd para registro e descoberta dinâmicaAdição/remoção de nós sem reconfiguração
Snowflake IDGerador de IDs distribuídosQPS teórico de 409.6w/s para IDs únicos

O sistema foi projetado para demonstrar padrões arquiteturais de sistemas de chat em produção, utilizando componentes que podem ser substituídos por alternativas mais robustas conforme a escala. O Redis, utilizado para filas e cache, pode ser substituído por Kafka ou RabbitMQ; o SQLite, usado para demonstração, pode ser substituído por MySQL ou PostgreSQL com mudanças mínimas no driver (readme.md:150-173).

Capacidades Quantificáveis

  • 6 módulos independentes: api, connect_websocket, connect_tcp, logic, task, site
  • 2 protocolos de transporte: WebSocket (porta 7000) e TCP (portas 7001-7002)
  • 1 ponto de entrada unificado: main.go com seleção de módulo via flag -module
  • Suporte a Go 1.18+: Requerido para compilação com generics e otimizações recentes
  • Arquitetura de 5 camadas: Connect, Logic, Task, API, Site - todas escaláveis horizontalmente

Arquitetura e Design do Sistema

A arquitetura do gochat segue o padrão de separação em camadas com comunicação assíncrona via filas. O fluxo de mensagens é desacoplado através de Redis, permitindo que a camada de conexão (Connect) foque exclusivamente em manter conexões long-lived com clientes, enquanto a camada de lógica (Logic) processa regras de negócio e a camada de tarefas (Task) consome mensagens para entrega final (readme.md:64-68).

正在加载图表渲染器...

O diagrama acima ilustra a separação de responsabilidades entre as seis camadas do sistema. A camada Connect é responsável por manter conexões persistentes com clientes (WebSocket ou TCP), enquanto a camada Logic processa requisições RPC de ambas as camadas Connect e API. Mensagens são persistidas em filas Redis e consumidas pela camada Task, que então realiza broadcast via RPC para todas as instâncias Connect relevantes (readme.md:71-75).

Padrão de Descoberta de Serviço

O etcd atua como registro centralizado para descoberta de serviço. Cada instância de módulo registra-se no etcd ao iniciar, permitindo que outras camadas descubram dinamicamente os endpoints disponíveis. Quando uma nova instância Connect é adicionada, ela é automaticamente descoberta pela camada Task, que passa a enviar mensagens para ela via RPC. Este padrão elimina a necessidade de configuração estática de endpoints e suporta scaling automático (readme.md:64-68).

Fluxo de Entrega de Mensagens

O fluxo de mensagens no gochat segue um padrão producer-consumer desacoplado:

  1. Produção: Mensagens são enviadas via HTTP para a API ou diretamente via WebSocket/TCP
  2. Processamento: A camada Logic valida e empurra mensagens para filas Redis
  3. Consumo: A camada Task consome mensagens das filas
  4. Broadcast: Task realiza RPC call para todas as instâncias Connect relevantes
  5. Entrega: Connect entrega mensagens aos clientes conectados via WebSocket ou TCP

Este padrão garante que falhas temporárias em qualquer camada não resultem em perda de mensagens, desde que Redis esteja configurado com persistência adequada (readme.md:71-75).

Estrutura de Diretórios e Módulos

A organização do código reflete a separação arquitetural em camadas, com cada diretório representando um módulo independente que pode ser compilado e deployado separadamente. O ponto de entrada unificado em main.go utiliza flags para selecionar qual módulo executar, simplificando o processo de build e deployment (main.go:21-43).

text
1gochat/
2├── api/              # Camada API REST
3├── architecture/     # Diagramas e recursos visuais
4├── bin/              # Binários compilados (não versionados)
5├── config/           # Arquivos de configuração
6├── connect/          # Camada de conexão (WebSocket + TCP)
7├── db/               # Conexões de banco de dados
8├── docker/           # Dockerfile e scripts de build
9├── logic/            # Camada de lógica de negócio
10├── main.go           # Ponto de entrada unificado
11├── proto/            # Definições RPC/protobuf
12├── site/             # Interface web estática
13├── task/             # Camada de consumo de tarefas
14├── tools/            # Utilitários compartilhados
15└── vendor/           # Dependências vendorizadas

Análise dos Módulos Principais

Módulo Connect (connect_websocket e connect_tcp)

Responsabilidade: Manter conexões long-lived com clientes, gerenciar sessões de sala e entregar mensagens em tempo real. Não processa lógica de negócio - apenas recebe mensagens do cliente e encaminha para a camada Logic via RPC, além de receber broadcasts da camada Task para entrega aos clientes (readme.md:124-148).

Entrada e APIs:

  • Flag -module connect_websocket ou -module connect_tcp em main.go:29-32
  • RPC server para receber broadcasts da camada Task
  • WebSocket handler na porta 7000 ou TCP listener nas portas 7001-7002

Estruturas de Dados:

  • Mapa de sessões por sala (dupla lista encadeada de conexões)
  • Contexto de conexão com informações de autenticação e roomId

Fluxo de Chamadas:

  1. Cliente conecta via WebSocket/TCP com authToken
  2. Connect valida token e associa conexão à sala
  3. Mensagens do cliente são encaminhadas via RPC para Logic
  4. Broadcasts de Task são recebidos e entregues aos clientes da sala

Módulo Logic

Responsabilidade: Processar regras de negócio, validar mensagens, gerenciar autenticação e autorização, e empurrar mensagens validadas para filas Redis. Atua como intermediário entre Connect/API e o sistema de filas (readme.md:124-148).

Entrada e APIs:

  • Flag -module logic em main.go:27-28
  • RPC server recebendo chamadas de Connect e API
  • Métodos RPC para envio de mensagens, autenticação, gerenciamento de salas

Estruturas de Dados:

  • Requisições RPC com payload de mensagem, metadados de usuário
  • Respostas RPC com status de validação e IDs gerados

Fluxo de Chamadas:

  1. Recebe RPC call de Connect ou API
  2. Valida autenticação e autorização
  3. Aplica regras de negócio (rate limiting, filtros)
  4. Gera ID via Snowflake
  5. Empurra mensagem para fila Redis apropriada

Módulo Task

Responsabilidade: Consumir mensagens de filas Redis e realizar broadcast para instâncias Connect apropriadas. Implementa o padrão consumer com retry e garantia de entrega (readme.md:124-148).

Entrada e APIs:

  • Flag -module task em main.go:33-34
  • Consumer de filas Redis
  • RPC client para chamadas broadcast para Connect

Fluxo de Chamadas:

  1. Consome mensagem de fila Redis
  2. Identifica salas/destinatários
  3. Descobre instâncias Connect via etcd
  4. Realiza RPC call para cada instância Connect
  5. Connect entrega mensagem aos clientes conectados

Módulo API

Responsabilidade: Expor REST API para clientes externos, gerenciar autenticação HTTP, e atuar como gateway para a camada Logic via RPC (readme.md:124-148).

Entrada e APIs:

  • Flag -module api em main.go:35-36
  • HTTP server com endpoints REST
  • RPC client para Logic

Endpoints Principais:

  • /login - Autenticação de usuário
  • /register - Registro de novo usuário
  • /send - Envio de mensagem (HTTP como alternativa a WebSocket)

Ponto de Entrada Unificado

O arquivo main.go implementa um ponto de entrada unificado que seleciona o módulo a executar via flag -module. Este design simplifica o processo de build, pois apenas um binário precisa ser compilado para todos os módulos. A seleção ocorre em um switch statement que invoca a função Run() apropriada para cada módulo (main.go:21-43).

go
1// Ponto de entrada com seleção de módulo via flag
2switch module {
3case "logic":
4    logic.New().Run()
5case "connect_websocket":
6    connect.New().Run()
7case "connect_tcp":
8    connect.New().RunTcp()
9case "task":
10    task.New().Run()
11case "api":
12    api.New().Run()
13case "site":
14    site.New().Run()
15default:
16    fmt.Println("exiting,module param error!")
17    return
18}

O tratamento de sinais de sistema (SIGHUP, SIGINT, SIGTERM, SIGQUIT) garante shutdown gracioso, permitindo que conexões ativas sejam finalizadas adequadamente antes do término do processo (main.go:44-47).

Stack Tecnológica e Dependências

O gochat utiliza uma stack tecnológica moderna com foco em performance e simplicidade operacional. A escolha de Go 1.18+ como linguagem base proporciona compilação cruzada nativa, garbage collection eficiente e concorrência via goroutines, essenciais para sistemas de alta concorrência como IM (go.mod:1-22).

Componentes Principais

ComponenteVersãoPropósitoAlternativas em Produção
Go1.18+Linguagem base-
Gin1.7.7HTTP framework para APIEcho, Fiber
rpcx1.7.4Framework RPC com etcdgRPC, Twirp
etcdvia rpcx-etcdDescoberta de serviçoConsul, ZooKeeper
Redis6.15.9Filas, cache, sessõesKafka, RabbitMQ
GORM1.9.16ORM para banco de dadossqlx, ent
SQLitevia go-sqlite3Banco de dados (demo)MySQL, PostgreSQL
Gorilla WebSocket1.5.0Protocolo WebSocketnhooyr.io/websocket
Snowflake0.3.0Geração de IDs únicosUUID, ULID
Viper1.11.0Gerenciamento de configuraçãoenvconfig

Dependências de Infraestrutura

O sistema depende de três componentes de infraestrutura externos que devem estar disponíveis antes da inicialização:

  1. etcd: Registro para descoberta de serviço. Cada módulo registra-se ao iniciar e descobre outros módulos dinamicamente. A atualização de 2022 adicionou watch para mudanças de KV, permitindo detecção automática de novas instâncias (readme.md:150-173).

  2. Redis: Atua como message broker e cache. Filas são utilizadas para desacoplar produtores (Logic) de consumidores (Task). Sessões de usuário e contadores também são armazenados aqui.

  3. Banco de Dados: SQLite é usado para demonstração com GORM como abstração, permitindo substituição por MySQL ou PostgreSQL com mudanças mínimas no driver (go.mod:11).

Bibliotecas Auxiliares

Além dos componentes principais, o projeto utiliza bibliotecas auxiliares para funcionalidades específicas:

  • pkg/errors (0.9.1): Tratamento de erros com stack traces
  • sirupsen/logrus (1.8.1): Logging estruturado
  • google/uuid (1.3.0): Geração de UUIDs
  • rcrowley/go-metrics (0.0.0-20201227073835-cf1acfcdf475): Métricas de aplicação

O arquivo go.mod define o módulo como gochat com Go 1.18, garantindo compatibilidade com features como generics e otimizações do compilador. Dependências são vendorizadas no diretório vendor/, permitindo builds offline e garantindo reprodutibilidade (go.mod:1-3).

Interoperabilidade WebSocket e TCP

Uma característica distintiva do gochat é o suporte simultâneo a conexões WebSocket e TCP, com interoperabilidade completa entre clientes de diferentes protocolos na mesma sala. Esta funcionalidade permite que clientes web utilizem WebSocket enquanto clientes mobile ou IoT utilizem TCP raw, todos participando do mesmo ecossistema de mensagens (readme.md:37-60).

Mecanismo de Autenticação

A autenticação TCP utiliza um token (authToken) enviado pelo cliente após estabelecer a conexão. Este token é o mesmo retornado pela API de login web, permitindo que usuários alternem entre WebSocket e TCP com a mesma identidade. O servidor Connect valida o token, recupera informações do usuário e associa a conexão TCP à sala apropriada (readme.md:46-49).

Fluxo de Mensagens Misto

正在加载图表渲染器...

O diagrama de sequência acima ilustra o fluxo completo de uma mensagem em um cenário com clientes mistos. A chave da interoperabilidade está na camada Connect, que mantém um mapa unificado de sessões por sala, independentemente do protocolo de transporte. Quando a camada Task realiza broadcast para uma sala, a camada Connect itera sobre todas as conexões (WebSocket e TCP) e entrega a mensagem usando o protocolo apropriado para cada cliente (readme.md:51-59).

Implementação TCP: Desafios de Streaming

TCP é um protocolo de camada 4 baseado em stream, não em mensagens. Para delimitar mensagens no stream, o gochat implementa um protocolo de framing com operações de Pack (empacotamento) e Unpack (desempacotamento). O arquivo stickpackage.go no diretório pkg/ contém esta lógica, que é invocada tanto no servidor quanto no cliente TCP (readme.md:40-43).

Estrutura do Frame TCP:

  • Header: 4 bytes indicando tamanho do payload
  • Payload: Mensagem serializada (JSON ou protobuf)

Clientes Android/iOS devem implementar o mesmo protocolo de framing para comunicação TCP. O repositório inclui um cliente de teste em Go (stickpackage_test.go) que demonstra a implementação correta (readme.md:43-44).

Inicialização Separada de Módulos

O ponto de entrada main.go trata WebSocket e TCP como módulos separados, permitindo que sejam deployados independentemente. A função connect.New().Run() inicializa o servidor WebSocket, enquanto connect.New().RunTcp() inicializa o servidor TCP. Esta separação permite escalar cada protocolo independentemente conforme a demanda (main.go:29-32).

go
1case "connect_websocket":
2    connect.New().Run()
3case "connect_tcp":
4    connect.New().RunTcp()

Cenários de Uso e Aplicabilidade

O gochat é adequado para diversos cenários que exigem comunicação em tempo real com arquitetura escalável:

Chat em Tempo Real

Sistemas de chat público ou privado com suporte a salas e mensagens diretas. A arquitetura de filas permite processamento assíncrono de mensagens com garantia de entrega.

Notificações Push

Sistemas de notificação em tempo real onde mensagens precisam ser entregues a usuários conectados. A camada Task pode ser estendida para integrar com serviços de push notification externos.

Dashboards em Tempo Real

Atualização de dashboards com dados em tempo real via WebSocket. A estrutura de salas pode ser utilizada para agrupar usuários por contexto (ex: sala por projeto ou empresa).

Sistemas de Colaboração

Editores colaborativos, whiteboards ou qualquer aplicação que exija sincronização de estado em tempo real entre múltiplos clientes.

Limitações Conhecidas

  • Persistência de Mensagens: Mensagens não são persistidas em banco de dados por padrão, apenas transitam pelas filas. Implementação de persistência requer extensão da camada Logic (readme.md:273-274).
  • SQLite em Produção: O banco SQLite é adequado apenas para demonstração. Deployments de produção devem utilizar MySQL ou PostgreSQL.
  • Redis como Fila: Para alta escala, Redis pode não oferecer garantias de entrega equivalentes a Kafka. Avaliar requisitos de durabilidade antes de deploy em produção.

Roteiro de Leitura do Relatório

Para maximizar a compreensão do sistema gochat, recomenda-se a seguinte sequência de leitura dos capítulos deste relatório técnico:

正在加载图表渲染器...

Sequência Recomendada:

  1. Visão Geral (capítulo atual): Introdução ao sistema, características principais e stack tecnológica
  2. Arquitetura do Sistema: Análise detalhada da separação em camadas, padrões de comunicação e descoberta de serviço
  3. Modelo de Dados: Estruturas de dados, esquemas de banco de dados e fluxo de persistência
  4. Design de API: Endpoints REST, contratos RPC e padrões de autenticação
  5. Deployment: Configuração Docker, variáveis de ambiente e procedimentos de operação

Este roteiro progressivo permite que desenvolvedores compreendam primeiro o contexto geral antes de mergulhar em detalhes de implementação específicos.