A real-time corporate chat built on the Akka actor model with event-sourced persistence and a WebSocket transport. Co-workers message each other from a shared contact list, with delivery, online/offline presence and typing indicators. Originally built around 2016 as an exploration of Akka Persistence and actor-based system design.
This is a historical project on a 2016-era stack (Scala 2.11, sbt 0.13, Akka 2.4 / Akka HTTP 10.0, AspectJ + Kamon metrics). It is preserved here as an architecture reference rather than a maintained, build-on-modern-toolchains app. Company-specific names and hosts have been removed.
| Path | What | Stack |
|---|---|---|
backend/ |
Chat server: WebSocket API, actor-per-conversation, event-sourced journal, admin/CRM token auth. | Scala · Akka · Akka HTTP · Casbah/MongoDB · Kamon |
frontend/ |
Admin web client (contact list, conversations, admin panel). | AngularJS · Bootstrap · Grunt |
perf-tests/ |
Actor-based load generator that simulates many concurrent users/admins. | Scala · Akka |
- Actor topology — connections, conversations and the per-user dialog list
are each modelled as supervised actors (
client_connection/,chat_api/). AConversationSupervisorroutes messages to aConversationactor per dialog; aDialogsListSupervisormaintains each user's dialog list. - Event sourcing — conversations persist their events through Akka Persistence (MongoDB journal + snapshot store), so state is rebuilt by replaying events.
- Auth — admin/CRM tokens are validated against an external CRM endpoint
(
CRM_TOKEN_URL); aMockCrmTokenis provided for local runs. - Metrics — Kamon (StatsD) with AspectJ weaving for Akka actor metrics.
Toolchain is pinned with mise:
mise install # Java 8, sbt, Node
mise run backend:run # chat server (WebSocket on :9100)
mise run frontend:serve # admin client
mise run perf:run # load testBackend config lives in backend/application.conf (MongoDB URL, bind host,
CRM auth mode — set env = "MOCK" to skip the external CRM).