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