Rohit Choudhari Rohan Hemant Wanare
@InfernapeXavier @r0hhan
Disclaimer: The dotnet SDK was recently updated to make
5.0
an official release. We have been using that to test this project.
Video Demo: YouTube
Requirements:
F#: Suave StackExchange.Redis Newtonsoft.Json
Python 3.7+: websocket-client
Run:
1. Start Server => `dotnet fsi server.fsx`
2. Start Clients => `python client.py`
Files for building the server via Docker have also been included
- The design is pretty straightforward. We opted for a Client-Server model that uses a central server to process all messages and are using Redis running on a local store as a Memory store as a database. The server starts a websocket server at the default port
8080
and the client code is configured to connect to this port. - The flow of execution is as follows:
- The server connects to Redis running at the default port.
- The server initially clears the Redis to start a new simulation.
- Start up a client from the python terminal
- Each client is made to register with the server. This also "connects" the user.
- The clients have menu-driven interface, enter the number for the corresponding action to execute the action.
- The clients are online until the server is stopped or the client exits.
- The server can be stopped with
ctrl+c
- Redis is a key-value store, so all data is Serialized using a JSON serializer and stored in the JSON format.
- All the data that is put on the socket is JSON serialized and is deserialized on both ends when received.
Note: A client that exits/closes a terminal is considered to have left the system and cannot reconnect.
Note: The Python client has no processing and is only sending serialized messages to the server and deserializing the received messages for display.
- Register: A new user is created and added to the database. At the same time, the user is added to a set that maintains all the currently connected clients.
- Connect: If a user chooses to disconnect from the server, they can reconnect to the server using this function. This is equivalent to logging in the twitter environment, so the client can carry all kinds of functionality.
- Disconnect: A user can choose to disconnect if they are currently connected to the server. Being disconnected will result in removal from the connected clients set on the server and they will no longer receive tweets from the people they follow or be allowed to make requests. This is equivalent to logging out of the twitter environment.
- Tweet: A user can send a new tweet using this function. The tweet is parsed and the appropriate mappings are added to the database. Once the tweet is registered, it is pushed by the server to all users that are live and have followed the user who initiated the tweet.
- Retweet: A user can use this function to send a retweet provided they know the tweet id of a tweet by someone else. The server first fetched the original tweet's details and modifies it appropriately before registering it as a new tweet (with the retweet flag) and then processes it in the same way as a regular tweet.
- Search: We have 3 search queries, each of them returns a set of tweets that satisfy the appropriate conditions.
- Remove: Whenever the user exits the environment, our program closes the client's websocket as well as removes the client's details from the Database since after that another client with same username can register. This is equivalent to deleting your account.
- Redis is a Key-value store
- Users = Key:
'u'+username
- Tweets = Key:
tweetid
-> Incremental integer starting at 1 - Hashtags = Key:
#<value>
- Mentions = Key:
@<value>
The code has been annotated with comments that may help understand more about the specific implementation.
- Users cannot follow themselves
- Two users can't have the same username
- Users cannot follow users that don't exist
- Users cannot retweet a tweet that doesn't exist
Client receives a relevant error message whenever an error occurs