简体   繁体   中英

Update large HTML content in realtime using Node.js and Socket.io

I am building a web application which updates the HTML content of every client's web page depending on changes made by one client, for this purpose I am using Node.js's Socket.io so far.

I am using HTML5's contenteditable property to allow the client to manually edit the content of the div elements which I need to update for other clients as well.

The problem that I'm facing is that I don't understand what data to send over websockets to inform the server and, in turn, other clients of the changes made.

To send the whole innerHTML on adding and removing of every character means sending huge amount of data over websockets which results in bad performance and slow speed. To send the appended data is not an option since we don't know at what position in the div element the data is appended or removed or edited.

Note that using the keyboard is not the only way how one client can change the HTML content of their copy of the web page. The required div element's data is changed depending on several activities by client using javascript.

Now I need to know how can I send the exact changed information over websockets on even the slightest change to get a realtime experience.

PS I intend not to use any existing modules like Share.js but suggestions are welcome.

This is not really a "question" rather a discussion and would be sort of "brainstorming" topic. As well it is pretty opinion based, as there is no specific one way of doing things talking so broad topic.

But I will take chance, and provide my pure IMHO the way I would approach this (sorry for being so personal):

  • Text Version Control - a way to keep track of version of text, something similar as git, but using character positions rather than lines. Each editable text should be version controlled, there should be one "master" that merges things in, and notifies clients of new versions. On client side, version changes (commits) should be applied the same way as server does merging. With respect of commits order.
  • Structure Updates - this is slightly different, as structure updates involve only HTML structure, and do not require versioning (there still is chance you would want versioning, or at least some history of actions, and there is racing conditions involved). Editing structure would notify server of such changes. It should make sure all clients are "on the same page" regarding structure.
  • Referencing - this can be hard bit. Referencing HTML elements can be pretty simple (selectors), but there is one complexity - when there is for example <ul> with many <li> , referencing each by index - fair enough, but what if you put new element in between? That will mess up references. So referencing should be unique, and fully depend on synchronised IDs that server would decide. You need to keep list of all references with pointer to html elements, so it is easy to access them directly.
  • Server <> Client politics. If you are talking fully about synchronised experience, then you have to follow authoritative politics of communication. Where only server really decides things, and clients render and only provide some input (requests). For example when client want to add element into HTML, he sends request and then server decides of such, and inserts it, once it is in, it will publish such event and then element will appear on clients and then they can edit content of this element. You can further enhance it by "going forward" without waiting for server but that should be done as extra layer, rather than part of main logic.
  • When one client is working on node (element/text), it should be the only who can work on it (to prevent conflicts). Commit will be considered as "in progress" and it should be single version commit. In beginning you can only update once user is "done" editing text or element. And later on add real-time visual capabilities of such process.
  • You have to research into amount of traffic this will inflict. With version controlling and event-based elements editing - it will be very efficient, but cost will be that server side should actually simulate whole DOM structure and do merging and other stuff.

Again this is primarily opinion based answer, and is not a small topic, it involves many fields. I think in terms "pure" and "good" approach to target, not the "fastest", there might be just much simpler solutions with some tradeoffs..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM