Open gurneetbhatia opened 2 years ago
After a new user has finished their registration locally, the application should request the NoSQL database for a list of currently online devices. The current user's device then sets up a Server
instance of the Socket.io
library which will be used for rooms they create and connecting with users that come online after them (discussed later). For each of the currently active devices on the network, we create a Client
instance and establish a connection with them.
In the event a pre-registered device is connecting to the network, we first set up a Server
instance of the Socket.io
library and then update the NoSQL database to reflect that we're online. After this, we fetch the the collection of currently active users and create a Client
instance for each of them and attempt a connection with them. If for some reason it fails, we record our fail vote on the NoSQL database to reflect this (look at 'Detecting devices disconnecting').
The actual disconnection is detected by the Socket.io
library itself, but we need to update the NoSQL database. Keeping in mind that it is possible one device isn't able to connect due to some local issues such as proxy restrictions, we use a polling mechanism. In the NoSQL database, when Device 1 detects that it is unable to connect to Device 0, it increments the disconnectedCount
property of Device 0's object. When the disconnectedCount
/onlineUsers
ratio exceeds a certain amount r
, we remove Device 0 from the NoSQL collection of active users and new devices connecting onto the network won't attempt to connect to it.
Anytime a user uploads a new resource onto their local repository, we send out a signal to the NoSQL database to add it. If the user happens to be disconnected from the network when they attempt this operation, the request for the database is added to a persistent queue on the users' device and is sent out whenever the user is next detected to be connected.
When another user goes onto the Explore repositories
tab of the Electron application, we request the collection of resources on the network from the NoSQL database. For each resource, the collection must hold the following information:
String
[String]
String
[String]
[String]
One device can request to download a resource from another from their repository. Once it is downloaded it is stored onto the repository of the downloading client's device. If the initial contributor of that resource goes offline, other devices will still be able to download the resource from the users' device who downloaded it previously from them. To be able to implement this, we need to keep a collection in the NoSQL database keeping track of which user has a copy of each resource locally. If the user deletes it locally, we will detect this when a user tries to download it from them and the operation fails. In this case, we will update the database to reflect the change. On the UI side of things, it might also be helpful to show which of the resources on the network are currently available to download. For each of the resources in the repositories of the users on the network, we check if any of the users who holds the resource is currently online or not. If they are online, the resource is available to download. If not, it can be shown with a greyed out text.
If User 1 wishes to have a chat with User 2, they can do easily since we've established a connection using either a Server
or a Client
instance. They can proceed to chat with each other without any changes.
If one user wishes to chat with multiple users, they can create a chatroom with them. They will be the host of the chatroom, and their Server
instance will be used for this. For the connecting users, we will send them instructions to join using their Client
instance which is already connected up to this Server
. Need to explore exactly what the code will look like in the Socket.io documentation.
A user may choose to leave a chatroom that they were added to. In case they do so, the host will be sent a message telling them to remove the corresponding user from the room object and stop sending them future messages. If, for some reason, this request does not go through properly, the leaving users' device will have muted the rooms' messages and will simply ignore them.
If one of the non-host members of a chatroom disconnects from the network, messages to them will be held in a queue on the hosts' end, and will be sent the next time they are both online. If the host of the chatroom disconnects from the server, one of the non-host members is voted to become the new host. This voting will be done by computing relative latency scores and the user with the lowest latency will become the new host. In case of a tie, a successor is chosen at random. New messages for the initial disconnected host will be stored in a queue on the new hosts' device.
Messages are stored persistently using the fs
package on the node
side of the application. These messages can be encrypted (additional feature to implement if time permits).
A chatroom may only be deleted by the original host. In this event, the host sends out a signal to all the non-host members and their devices are updated accordingly to reflect this. The chat will still be stored on all of their devices persistently and they will be able to access it at a later point.
How I'm planning on using the P2P server. This is the architecture. Will be using socket.io as the library of choice.