Multithreaded Game Server Suitable
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
This assignment requires you to design and implement a multithreaded game server suitable for two-player games (such as Backgammon, Checkers, Chess, Go, etc.). The server helps to pair up players and to coordinate the exchange of game moves. It does not know anything about the underlying game itself.
The server should be programmed using the C# programming languageLinks to an external site., and needs to be constructed using a synchronous server socketLinks to an external site. from the ground up. Higher-level APIs (such as HTTPListenerLinks to an external site.) cannot be used. Please ask if in doubt.
The server should use HTTP REST as the basis for communication with the game clients. To this end, the following (GET) endpoints are suggested:
/register
This endpoint generates a random username for a player, registers this name, and returns to the user the registered name. The player is required to pass this username in all subsequent transactions for identification.
/pairme?player={username}
This endpoint attempts to pair the given player with another player. It returns a game record (or a suitable subset of it). The game record is a tuple containing a game ID, game state, username of the first player, user name of the second player, last move of the first player, and the last move of the second player.
When there is no other player waiting, the game record will contain a newly allocated game ID (which could be a GUID), a game state indicating "wait", and the username of the requesting player as first player. The rest of the elements in the tuple are not defined. When there is a waiting player, the game record will be the game record first created for the waiting player, updated to add the second player and the state indicating "progress". The state "progress" tells both players that the game can now begin.
The endpoint can be invoked by both players as many times as they want before the commencement of the game. This helps the first player to "poll" the state to see if a second player has been paired up.
/mymove?player={username}&id={gameId}&move={move}
This endpoint, when used during the game's "progress", will supply the user's move to the server. The "last move" of the player in the corresponding game record will be updated with this supplied move.
/theirmove?player={username}&id={gameId}
This endpoint, when used during the game's "progress", will collect the other player's move from the server. The game server will supply the "last move" of the other player from the game record corresponding to the given game ID.
/quit?player={username}&id={gameId}
This endpoint notes to the server the intention of the player to quit the game. The server will remove the game record corresponding to the given game ID. Attempt by the players to access the game record (for example, to get a move) will fail after the record is removed.
You may wish to implement other endpoints for diagnostic or informational purposes (e.g., a /debug endpoint or a /version endpoint). You may also wish to implement a /favicon.ico endpoint that supplies to the caller the "favicon" — this is particularly useful for browser-based clients.
You need to take appropriate actions when errors are encountered (e.g., invalid endpoints, malformed endpoints, invalid parameters to endpoints, etc.).
Typically, a single thread will handle a single player's endpoint interactions. The server, for the sake of efficiency, should keep the connection alive to handle the player's requests in the same thread. However, it is possible that the client may, from time to time, close the connection. For example, a browser will close the connection if it deems the connection inactive for a period of time. The server should be able to gracefully handle this scenario and continue to serve the client (potentially using a new thread).
Think about what information is shared among the threads and avoid potential race conditions efficiently using appropriate concurrency controls. You should not persist any of the information, meaning that, the information is kept only in nonpersistent memory and lost if the server is restarted.
The server should be a command-line application using .NET 7, and should be runnable with a standard .NET 7 installation (no third-party components are admissible). It should be able support browser-based game clients.
Print the client IP and port number to the console when a connection is established. Also the URL the client accesses along with the thread ID print to the console. See Appendix that illustrates a sample log.
Testing
You need to come up with an appropriate testing strategy for verifying the correctness of the server. One way to do this could be to build a browser-based client for a chosen two-player game.
At the bare minimum, your server should be testable using TelnetLinks to an external site.. A server that cannot be tested using Telnet will NOT attract any marks.
Report
Your submission should include a short report in the IEEE two-column style. The report should discuss the problem, explore alternatives, critically analyse your choices, design (which may include the specification), and implementation, and present an evaluation of your work. The report should include appropriate references. It should also have an appendix outlining what you learnt doing the assignment and any fedback or reflections you may want to share.
Submission
The complete source code of the server along with build files should be submitted. Solution that do not compile or run will attract ZERO marks, and we will not be able to entertain any source code modifications after submission. You need to include in the submission instructions for compilation and usage. Your submission should not include any
binary content (such as DLL and EXE files).
The report should be submitted as a PDF.
A browser-based client can only include three files: an HTML file, a JavaScript file, and a CSS file. Small images are okay too. Disuss with us the submission requirements if you want to develop a non-browser based client.
Submission is to the Assignment Dropbox, and there are naming and size requirements to note:
Grading
Development of the server, testing strategy, and report — all to a high-standard — is likely to gain you a grade in the B range. Development of a concrete client for a chosen two-player game, again to a high-standard, is likely to gain you a grade in the A range.
Development Hints
There is an example in https://docs.microsoft.com/en-us/dotnet/framework/network-programming/synchronous-server-socket-example The simplest way to try this is to use Telnet (this is a generic socket client, and all OSes come with one, you may need to find out where it is. On Windows it is not installed by default, so you need to go to Windows components and install it). You can telnet to port 11000 (the port that the example uses) to send some data. You will see that the server closes the
connection soon after sending the response, and telnet client will terminate since the server closed the connection. To interact with the server, you need to start a new telnet client every time.
Now change the server so that it does not close the connection soon after sending the response. When you have successfully done this, you can use the same telnet client to send requests to the server and receive responses. This connection is now alive, and this is what HTTP's keep-alive does (loosely speaking, since HTTP has a timeout).
Now that you have a server that keeps the connection alive, test with another concurrent telnet client (while your first one is still active and connected to the server). You would see that the second telnet client would connect to the server but it won't receive any response to requests it sends. The first client is keeping the server busy here.
Try closing the first client and see if the server now responds to the second client. You will see that it won't. This is because the server does not see that the first client has closed the connection. You need to see how to detect this and get the server to be ready to serve the second client when the first client quits.
At this point you have a nice little server that keeps the connection alive and is able to tidy itself up when clients ditch the server.
Now you are ready to get multithreading into the play to make the server service multiple clients concurrently.
Appendix — A sample log of a PoC Game Server
Listening at 127.0.0.1:8080
Connection established with 127.0.0.1:55877
Thread 4 sent response to 127.0.0.1:55877 for /favicon.ico
Connection established with 127.0.0.1:55878
Thread 4 sent response to 127.0.0.1:55877 for /register
Connection established with 127.0.0.1:55887
Thread 3 sent response to 127.0.0.1:55887 for /pairme?player=PhoneBus
Connection established with 127.0.0.1:55888
Connection established with 127.0.0.1:55894
Thread 8 sent response to 127.0.0.1:55894 for /favicon.ico
Connection established with 127.0.0.1:55895
Connection established with 127.0.0.1:55899
Thread 10 sent response to 127.0.0.1:55899 for /register
Thread 10 sent response to 127.0.0.1:55899 for /favicon.ico
Connection established with 127.0.0.1:55900
Thread 8 sent response to 127.0.0.1:55894 for /favicon.ico
Connection established with 127.0.0.1:55908
Thread 12 sent response to 127.0.0.1:55908 for /pairme?player=HomeworkResearch
Connection established with 127.0.0.1:55909
Thread 3 sent response to 127.0.0.1:55887 for /pairme?player=PhoneBus
Thread 3 sent response to 127.0.0.1:55887 for
/mymove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pw1%22,%2 2from%22:%22a2%22,%22to%22:%22a4%22}]
Thread 12 sent response to 127.0.0.1:55908 for
/theirmove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 12 sent response to 127.0.0.1:55908 for
/mymove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pb 1%22,%22from%22:%22a7%22,%22to%22:%22a5%22}]
Thread 5 closing connection with 127.0.0.1:55878 and terminating
Thread 3 sent response to 127.0.0.1:55887 for
/theirmove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 7 closing connection with 127.0.0.1:55888 and terminating
Thread 3 sent response to 127.0.0.1:55887 for
/mymove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pw2%22,%2 2from%22:%22b2%22,%22to%22:%22b4%22}]
Thread 9 closing connection with 127.0.0.1:55895 and terminating
Thread 11 closing connection with 127.0.0.1:55900 and terminating
Thread 12 sent response to 127.0.0.1:55908 for
/theirmove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 13 closing connection with 127.0.0.1:55909 and terminating
Thread 12 sent response to 127.0.0.1:55908 for
/mymove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pb 8%22,%22from%22:%22h7%22,%22to%22:%22h6%22}]
Thread 3 sent response to 127.0.0.1:55887 for
/theirmove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 3 sent response to 127.0.0.1:55887 for
/mymove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pb1%22,%2 2from%22:%22a5%22,%22to%22:%22bin2%22},{%22piece%22:%22Pw2%22,%22from%22:%22b4%22,%22to%22: %22a5%22}]
Thread 12 sent response to 127.0.0.1:55908 for
/theirmove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 12 sent response to 127.0.0.1:55908 for
/mymove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pb 7%22,%22from%22:%22g7%22,%22to%22:%22g5%22}]
Thread 3 sent response to 127.0.0.1:55887 for
/theirmove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 3 sent response to 127.0.0.1:55887 for
/mymove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pw6%22,%2
2from%22:%22f2%22,%22to%22:%22f4%22}]
Thread 12 sent response to 127.0.0.1:55908 for
/theirmove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 12 sent response to 127.0.0.1:55908 for
/mymove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pb 2%22,%22from%22:%22b7%22,%22to%22:%22b6%22}]
Thread 3 sent response to 127.0.0.1:55887 for
/theirmove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 3 sent response to 127.0.0.1:55887 for
/mymove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a&move=[{%22piece%22:%22Pb2%22,%2 2from%22:%22b6%22,%22to%22:%22bin1%22},{%22piece%22:%22Pw2%22,%22from%22:%22a5%22,%22to%22: %22b6%22}]
Thread 12 sent response to 127.0.0.1:55908 for
/theirmove?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 12 sent response to 127.0.0.1:55908 for
/quit?player=HomeworkResearch&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 3 sent response to 127.0.0.1:55887 for
/theirmove?player=PhoneBus&id=7da3122a-6eb0-4db6-8d27-9d8fd6c4cf0a
Thread 4 closing connection with 127.0.0.1:55877 and terminating
Thread 3 closing connection with 127.0.0.1:55887 and terminating
Thread 8 closing connection with 127.0.0.1:55894 and terminating
Thread 10 closing connection with 127.0.0.1:55899 and terminating
Thread 12 closing connection with 127.0.0.1:55908 and terminating
2023-07-16
This assignment requires you to design and implement a multithreaded game server suitable for two-player games (such as Backgammon, Checkers, Chess, Go, etc.).