gurneetbhatia / p2p-academics

A P2P-based network connecting academics
0 stars 0 forks source link

Research p2p protocols and libraries that could be used #7

Open gurneetbhatia opened 2 years ago

gurneetbhatia commented 2 years ago

How I'm planning on using the P2P server. This is the architecture. Will be using socket.io as the library of choice.

IMG_20211004_192437.jpg

gurneetbhatia commented 2 years ago

Rules of the protocol

New User Registration

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.

Returning users

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').

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.

Resource discovery

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:

Downloading and sharing resources

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.

Chatrooms

One-on-one chats

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.

Chatting with multiple users

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.

Leaving a chatroom

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.

Disconnecting from a chatroom

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.

Storing messages

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).

Deleting a chatroom

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.