I’m working on a private project which is basically a very extended version of the chatroom example and I also had startup problems with akka and the whole “decentralized” thinking.
So I can tell you how I “solved” my extended chatroom:
I wanted a server which could easily be deployed multiple times without much additional configuration.
I am using redis as the storage for all open user sessions (simple serialization of their ActorRefs) and for all chatrooms.
The server has the following actors:
WebsocketSession
: which holds the connection to one user and handles requests from the user and forwards messages from the system.ChatroomManager
: this is the central broadcaster, which is deployed on every instance
of the server. If a user wants to send a message to a chatroom, the WebSocketSession-Actor sends all the information to the ChatroomManager-Actor which then broadcasts the message to all members of the chatroom.
So here is my procedure:
- User A connects to server 1 which allocates a new WebsocketSession. This actor inserts the absolute path to this actor into redis.
- User A joins a chatroom X which also inserts his absolute path (I use this as the unique ID of a user session) into redis (each chatroom has a “connections” set)
- User B connects to server 2 -> redis
- User B joins chatroom X -> redis
- User B sends a message to chatroom X as follows: user B sends his message over the Websocket to his session-actor, which (after some checks) sends a actor-message to the ChatroomManager. This actor actually retrieves the user-list of the chatroom from redis (absolute paths used with akka’s
actorFor
-method) and then sends the message to each session-actor. These session-actors then write to their websockets.
In each ChatroomManager-actor I do some ActorRef
caching which gave additional speed.
I think this differs from your approach, especially that these ChatroomManagers handle requests for all chatrooms. But having one actor for one chatroom is a single point of failure which I wanted to avoid. Further would this cause a lot more messages, eg:
- User A and user B are on server 1.
- Chatroom X is on server 2.
If user A wants to talk to user B, they both would have to communicate over the chatroom-actor on server 1.
In addition I used akka’s functionalities like (round-robin)-routers to create multiple instances of a the ChatroomManager-actor on each system to handle many requests.
I spend some days on setting up the whole akka remote infrastructure in combination with serialization and redis. But now I am able to create any number of instances of the server application which use redis to share there ActorRef
s (serialized as absolute paths with ip+port).
This may helps you a little bit further and I’m open for new questions (please not about my english ;).