English | 简体中文
This document explains how the open-source JuggleIM server is structured, how a message moves through the system, and which infrastructure it requires. It describes the master branch and the single-node community deployment. Cluster-specific behavior belongs to the professional edition and is intentionally outside this document's implementation claims.
JuggleIM is a modular real-time messaging server built as a single Go process. HTTP and WebSocket gateways feed requests into an internal actor and RPC runtime. Domain modules own message delivery, users, groups, conversations, history, push, files, subscriptions, bots, moderation, and RTC room signaling.
The community deployment uses MySQL for required application and messaging metadata. Message-related collections can optionally use MongoDB. A local LevelDB-backed KV store is available for time-series-style internal data.
- Keep long-lived client connections separate from server-side management APIs.
- Route work by method and target ID so stateful operations for the same user, group, or conversation have a stable execution path.
- Support synchronous queries, asynchronous commands, group routing, and broadcast through one internal RPC envelope.
- Keep domain code modular even though the community edition runs in one process.
- Allow MySQL-only deployments while supporting MongoDB for selected message workloads.
- Preserve tenant context (
app_key) throughout request handling and message delivery.
| Entry point | Default | Consumer | Responsibility |
|---|---|---|---|
| Server API Gateway | HTTP :9001 |
Business backend | Users, groups, messages, conversations, history, push, moderation, and other server-side APIs |
| Navigator | HTTP :9002 |
Client SDKs | Validates the client token and returns the configured WebSocket connection address |
| Connect Manager | WebSocket :9003 |
Client SDKs | Maintains long connections, decodes Protobuf frames, routes client publications, delivers messages, and handles ACKs |
| Admin Gateway | HTTP :8090 |
Operators | Serves the admin console and administrative APIs |
| Diagnostics | HTTP :6060 |
Operators | Go pprof; bind or firewall this endpoint appropriately in production |
The ports are independently configurable. Production deployments should place TLS termination, access control, rate limiting, and public routing in front of these listeners.
launcher/main.go performs the following work in order:
- Load configuration and initialize logging.
- Connect to MySQL and run schema upgrades.
- Open the optional local KVDB.
- Initialize MongoDB collections when
msgStoreEngine: mongois selected. - Create the
gmicroactor runtime and register node entry-point metadata. - Register gateway and domain actors.
- Start HTTP, WebSocket, metrics, and background services.
- Shut services down after receiving a termination signal.
Each service registers one or more string method names, such as p_msg, g_msg, msg_dispatch, qry_convers, or push. Calls use a Protobuf RpcMessageWraper containing the tenant, requester, target ID, QoS, sequence, message payload, and routing metadata.
The runtime supports:
- Synchronous unicast for request/response queries with a bounded timeout.
- Asynchronous unicast for commands and message delivery.
- Grouped routing for batches of target IDs.
- Broadcast for events that must reach every eligible actor.
In the community edition, gmicro.Cluster resolves routes to the current process. This keeps the same domain boundary and RPC contract without claiming multi-node behavior that is not present in this repository.
| Layer | Modules | Primary responsibility |
|---|---|---|
| Access | apigateway, navigator, connectmanager, admingateway |
REST APIs, endpoint discovery, WebSocket sessions, and operations UI |
| Messaging | message, broadcast, botmsg |
Private messages, dispatch, broadcast, acknowledgements, bot messages, and sendbox state |
| Identity | usermanager, friendmanager, statussubscriptions |
Users, settings, friend relationships, presence, bans, blocks, and status subscriptions |
| Conversation | conversation, group, historymsg |
Conversations, unread state, tags, groups, membership, history, recall, read state, favorites, and merged messages |
| Extensions | pushmanager, fileplugin, subscriptions, rtcroom, sensitivemanager, logmanager |
Offline push, file credentials, event subscriptions, RTC signaling, moderation, and visual logs |
| Runtime | commons/gmicro, commons/bases, commons/imstarters |
Actor lifecycle, routing, RPC envelopes, callbacks, startup, and shutdown |
| Data | dbcommons, mongocommons, kvdbcommons |
MySQL migrations, optional MongoDB collections, and local LevelDB storage |
Services communicate through actor method names instead of importing another service's internal implementation. Shared lookup and delivery helpers live under services/commonservices.
sequenceDiagram
autonumber
participant A as Sender Client
participant WS as Connect Manager
participant RPC as Actor Runtime
participant PM as Private Message Actor
participant Store as Message Storage
participant Dispatch as Message Dispatch
participant Push as Push Manager
participant B as Receiver Client
A->>WS: Publish message over WebSocket
WS->>RPC: Route p_msg by target ID
RPC->>PM: Process UpMsg
PM->>PM: Tenant, interceptor, block and friend checks
PM->>Store: Save sendbox and history
PM->>Dispatch: Dispatch message to receiver
alt Receiver is online
Dispatch->>WS: Route msg or ntf
WS->>B: Deliver over WebSocket
B-->>WS: Delivery ACK
else Receiver is offline
Dispatch->>Push: Request offline push
Push-->>B: APNs / FCM / vendor push
end
PM-->>WS: Sender publish ACK
WS-->>A: Message ID, sequence and timestamp
Important behaviors include interceptor checks, block/friend policy checks, client-message deduplication, message ID and sequence allocation, sendbox/history persistence, online delivery, offline push, and sender acknowledgement.
sequenceDiagram
autonumber
participant A as Sender Client
participant WS as Connect Manager
participant RPC as Actor Runtime
participant GM as Group Message Actor
participant Group as Group Service
participant Store as Message Storage
participant Dispatch as Message Dispatch
participant Members as Online Members
participant Push as Push Manager
A->>WS: Publish group message
WS->>RPC: Route g_msg by group ID
RPC->>GM: Process UpMsg
GM->>Group: Check group and sender membership
Group-->>GM: Group snapshot and member settings
GM->>GM: Apply mute, allow-list and interceptor rules
GM->>Store: Persist group history and sendbox state
GM->>Dispatch: Fan out by member IDs
Dispatch->>Members: Deliver msg or ntf over WebSocket
Dispatch->>Push: Push to eligible offline members
GM-->>WS: Sender publish ACK
WS-->>A: Message ID, sequence and timestamp
The exact fan-out and storage work depends on message flags, group settings, member settings, online state, and push configuration.
| Dependency | Required | Responsibility |
|---|---|---|
| MySQL 8 | Yes | Applications, credentials, users, groups, relationships, conversations, configuration, and the default message/history storage path |
| MongoDB | No | Alternative storage collections for message, history, and push workloads when msgStoreEngine: mongo is configured |
| Local LevelDB | No | Embedded KV and timestamp-ordered data when kvdb.isOpen is enabled |
| Object storage | Feature-dependent | Attachments and upload credentials through S3-compatible storage, MinIO, OSS, or Qiniu |
| Push providers | Feature-dependent | APNs, FCM, and supported Android vendor push channels |
MySQL remains required even when MongoDB is selected because application metadata, configuration, and several domain tables still use MySQL. Database changes are applied through the repository's upgrade path during startup.
app_keyidentifies a tenant and is carried through API, RPC, storage, and delivery contexts.app_secretbelongs only on a trusted business backend and must never be shipped in a client application.- Client access uses a tenant-scoped token validated by Navigator and the WebSocket connection path.
- Public deployments should terminate TLS so HTTP becomes HTTPS and WebSocket becomes WSS.
- The admin console, diagnostics endpoint, database ports, local log uploads, and storage credentials must not be exposed without network controls.
- Default local credentials are for development only and must be changed before production use.
- Security-sensitive configuration belongs in runtime configuration or a secret manager, never in the repository.
This document does not claim end-to-end encryption between chat participants. Transport encryption and any application-level content encryption must be evaluated separately for the chosen deployment and SDK configuration.
- QoS-aware acknowledgements allow clients and services to observe delivery outcomes.
- Client message IDs support duplicate-publication filtering.
- Message sequence numbers and timestamps support ordered synchronization.
- Sendbox and history paths separate delivery state from conversation history.
- Online users receive a message or lightweight notification; eligible offline users can receive push notifications.
- Actor routing serializes work around stable routing keys where the registered actor type requires it.
- RPC queries have bounded timeouts instead of waiting indefinitely.
Performance limits depend on hardware, database configuration, message shape, group size, online ratio, and enabled integrations. See the planned reproducible benchmark work in Issue #37; marketing scale claims should be evaluated against published benchmark conditions.
- Structured application logs are written under the configured log directory.
GET /metricsreturns the server's current performance metrics snapshot when the default HTTP mux is served by an integrated application path.- Go
pprofis exposed on port6060by the launcher. - Root
GETandHEADhandlers on API and Navigator can be used for basic process-level checks. - Docker Compose provides a MySQL health check and starts the server after MySQL becomes healthy.
Production operators should add external health checks, log aggregation, metrics retention, alerting, backup verification, and capacity dashboards. The diagnostics port should be restricted to an operations network.
The repository's supported quick start is a single JuggleIM process plus MySQL. MongoDB and external file/push providers are optional. The process exposes several listeners but shares one runtime, configuration, and lifecycle.
The open-source gmicro.Cluster implementation routes only to the current node. Multi-node discovery, routing, failover, and horizontal scaling must not be inferred from the class name alone. Refer to JuggleIM's commercial documentation for professional-edition topology and guarantees.
When adding a domain capability:
- Keep the module under
services/<name>with its actor, service, and storage boundaries. - Register actor method names in the module's
starter.go. - Load the starter from
launcher/main.go. - Use
bases.SyncRpcCall,bases.AsyncRpcCall, grouped routing, or broadcast instead of importing another module's internals. - Preserve tenant, requester, target, QoS, sequence, and message metadata in the RPC context.
- Add database changes through
dbcommons.Upgrade(). - Update this document and the relevant message flow when a boundary or lifecycle changes.
The editable Mermaid sources are under docs/diagrams. Keep the source and exported overview SVG in sync.