Need Some Advice to implement a Realtime Feature for my application using elixir

Hey Elixir Community,
I am trying to create a simple application where users can create a lobby to play turn based games like chess, scribble , poker etc with their friends and it also should has a feature so that other users can spectate the game. For spectate feature I am using MQTT broker and each spectator subscribes to game topic. Game topics are like game_topic/{game_id}. For players I am using socket.io to implement realtime event passing but there are certain limitations with socket io , like if two users are connected to different WS servers how will they pass events to each other. I know I can use something like signalling server or redis (for pub/sub) but if I am going to use pub/sub I thought why don’t I give elixir a try.

This is the current architecture:

For the new one I am thinking I should just create a new elixir service where for each user connection we spin up a process which will be responsible to pass events to user frontend client using pub/sub. This is the new architecture:

I am thinking of creating a process for each lobby, and that process should hold all the connected users and should also decide the turn of the users in some order and similarly the process could hold the current state of game so if any new new move is made by any new user (like moving pawn from e2->e4) I can just make changes in the chess FEN string and publish it to mongoDB. I have not worked with elixir earlier. Any suggestions/resources on how can I implement something like this would be really appreciated. Thanks for reading

1 Like

Hi necromorph23!

Sounds to me like using Elixir for a system like this is an excellent choice.

EDIT from the future: I realised after writing this post that I’m not sure how much of this service you’ve already written and created, and how much is in the design phase. If you’ve already implemented most of the things, then do feel to completely ignore my points about the architecture.

While you’re asking for guidance specifically for how to build what you’ve architected, I think it could be worthwhile to take a step back and think about the architecture from a fresh perspective.

I don’t know your use case well enough to say for sure, but at a glance it seems to me like the architectural diagram is somewhat at odds with the premise of “a simple application”. It sounds like there are many moving parts in the design, and I’m wondering if fewer individual pieces could lead to both easier and even simpler design?

Could you explain why, for instance, we need both MongoDB and PostgreSQL to store various pieces of data? Could we get away with only using PostgreSQL as data store here?

Similarly, it sounds like “Messier” uses something called Axum. A quick Google tells me it’s a Rust web framework. Could we streamline things by using Phoenix instead, allowing us to run all the Elixir code in a single service?

This allows you to use Distributed Elixir and Phoenix PubSub to coordinate users that connect to different machines, potentially allowing you to drop your requirement of Redis as a Pub/Sub service completely.

You also mention Kafka and MQTT in the diagram. I’m not 100% sure how those would be used, but I’ll just share a link to Broadway here as well, in case it could prove to be a helpful tool in the system.

In general, I would perhaps try to start building this with (or at least start designing it with the idea of) just a single Elixir + Phoenix + PostgreSQL -service, and add other pieces only when absolutely necessary. This way you minimize the need to build all the plumbing that is required for separate systems to talk to each other, allowing you to focus on the bits that actually make your service useful for user :slightly_smiling_face:

Now, it could be that you want to build exactly something like this using exactly these kinds of services that you’ve drawn on the diagram. There’s nothing wrong with that either, so feel free to ignore my questions and comments if what you’ve decided is something you absolutely want to use!

Good luck with your project!

Hey @juhalehtonen ,
Initially when i started the project even I was not sure what I exactly wanted to make, as the project grew so did the requirements, like I said currently i am using socket io but i don’t think socket io is really fir for the very high load , additionally i don’t want to use something like redis pub/sub just to keep publish events among multiple Messier server.

Could you explain why, for instance, we need both MongoDB and PostgreSQL to store various pieces of data? Could we get away with only using PostgreSQL as data store here?

As far as using different DB is concerned , my only concern was since we will be getting a lot of UserMove events (like moving a chess piece, or drawing on scribble board from (x1,y1) to (x2,y2) ) i wanted to use something which can handle high write throughput so a No-SQL database made much more sense to me because i was planning to use it later for some kind of game performance analysis as well.

I do agree that design can be simpler, but since i have implemented a lot of functionality, i am not planning to change a whole lot. I have a working app as of now where users can play only chess for now and spectate feature is also working, but i wanted to remove socket io because using it is like using a double edge sword, hence i wanted to use something like elixir which number of concurrent connections without degrading the performance or experience for the user.