0

I'm building a web app, where users can create locations, which are displayed on a map.

Also, users can click on the map objects in order to get to a place details page where further interactions with the server can be done.

Users also can delete the places they added on the map and this could happen pretty often.

All connections to my node.js server are made with WebSockets (socket.io). I would like to notify all clients when a location is deleted in order to have the map up to date at any time and prevent them to trigger server requests for places that aren't available anymore.

Can I just notify all clients as much and often as I want or are there some caveats which I have to take care of especially if there are thousands of active connections?

Any advice would be greatly appreciated.

  • There may be scalability issues if you have many clients. I'm not sure I'd worry about that yet, though. You can always delay the updates by some small period of time to thin out the data. – Robert Harvey Aug 24 '19 at 16:05
  • Hi @RobertHarvey thx for your comment, ok those are good news if there is no real issue with this. How would you approach these delays? – Getter Jetter Aug 24 '19 at 16:57
  • @OlivierKrull: *those are good news if there is no real issue with this* - that is not what Robert Harveys comment says. – Doc Brown Aug 25 '19 at 06:06
  • @DocBrown ok, for me it didn't sound that bad, can you help me with that? Regarding the scalability I think I can handle it, I'm load balancing the connections and keep track of them with Redis. What else should I be aware of? I just want to know where I have to be careful and if there are some caveats to this problem. – Getter Jetter Aug 26 '19 at 20:39

2 Answers2

2

You should not do that. The reason is simple: everytime you have a change you would try to inform them. And this comes with 3 major downsides:

1) You try to reach someone that maybe not reachable. Just because you think there is an open connection does not mean it really is. The information that is has been closed may not have reached you. Based on the implementation the data loss may be significant nor not. 2) You send a single information and not a package of information. Each information has the full overhead necessary for communication. 3) If the user just established a connection, you need to sync anyways. So it's only an additional option not the only way.

The passive approach is often the better one if not realtime sync is required.

If a user wants to use something, let him ask for a checkinfo if there are any news. The checkinfo can also be something simple as a date. When a user initiates the use, it tries to request the latest updates and changes. But identifying the changes can be difficult. So another way is working with a version number for information. Then you exactly know what have changed for the user and can provide any information the user has to get work with it.

As it may take a moment, its always good to work asynchron. To ensure a connected user has the newest information, implement a method that your communication also handles your latest info version number. If so, the client always know if it has to request an update. And then the update can be requested and updated.

Serverside, you can decide whether information is necessary for the user or optional. Optional information is e.q. for regions the user does not use regulary or unlikely or if something non relevant has changed the user may not work with. But that's maybe the next level.

The checkinfo is fine as a date in milliseconds. That should do the trick. And if the date already exists (in rare cases) just count up by 1. If it's even lower, take the newest and update the number. If you have too many updates in on ms level, you need to find another way for enrichment of your checkinfo.

Based on the amount of information, it can make sense to work with multiple versionings to shrink the required amount of information. Downside is, that it will be much more difficult to know what has changed and what not. So you have to group it or make sure you store another information what has been updated separately apart from the global stuff.

Minimizing the amount of data that is transported is one of the most important things to make it performant and reduce costs on all sides. But make sure you define a proper logic that is unbreakable. Otherwise think of a workaround if something went wrong - like a checksum over all information to compare with the server, and if there are any irregularities, try to zoom with different checksums of different elements to potentially reduce the amount of data sent. Receiving the full package everytime something is out of sync maybe too much.

Based on the size of your project you can decide which depth is appropiate. You do not need a solution that can scale huge but to have a solution that allows itself to exchange parts easily and allow you to scale larger. That like you dont need to know it all, if you have a lexikon at hand.

That basically has nothing to do with open sockets, it's just how information should be shared. Synchronization is not so trivial but active pushes should only be used if a realtime performance is required. From what you wrote, it does not seem to be necessary. So avoid it at any costs. Synchronize your data client sided to ensure the user received the desired amount of information. You almost never need to sync all data everytime. Make sure to also think of the situations that does not fit the in general case and to ensure they do not suffer much from desynchronization.

Better not think about "can I do that" but "should I do that".

Christian
  • 94
  • 2
0

It sounds like the answer is that you might be thinking of this backwards.

If your client app is built with reactivity in mind (see: React or similar libraries) the client should be updated when the data changes. This would be dependent on the client checking in but it's not necessary to manually push out these updates; you need to effectively bind the front-end data to the state of data in your server-side app.

Basically, your client should be checking for updates, and doing so after a certain amount of time. You might want to look at creating a worker process locally on the client to manage this.

You may also want to look at RxJS/ReactiveX (also see learnrxjs.io). This allows the concept of "subscriptions" where you create an "observable" that you "watch" for updates. It's far too involved to explain in one post, but the concept is similar to reactivity but handled much differently.

The short answer is it's probably a waste of time and resources to code the app to force clients to update by constantly pushing on web sockets when you can rely on the client to check in for updates.

methodbox
  • 11
  • 2