Network Client Server

I am trying to create an application that will allow two users on a network to play a prisoner

game dilemma ( http://en.wikipedia.org/wiki/Prisoner%27s_dilemma ).

This mainly includes:

  • The game begins (round 1).
  • Player 1 chooses to either cooperate or betray.
  • Player 2 chooses to either cooperate or betray.
  • Then other solutions are displayed.
  • Round 2 begins
  • Etc.

I did some thought and searching, and I think the application should contain the following:

  • Server class that accepts incoming tcp / ip connections
  • Gui customers (separate program)
  • For each connection (maximum 2) the server will create a new class ConnectedClient. This class will contain information about two gaming machines / identities.
  • The Server class and the ConnectedClient class will connect / sign events for each so that they can warn each other when, for example, a server team ready to be transferred to players, or players transferred their inputs to the server.

I am not sure if it is best to use a single thread for work or work or multi-threading. A single thread will obviously be simpler, but I'm not sure if this is possible for this situation - I never made an application before requiring a TCP / IP connection, and I'm not sure that you can listen to two incoming connections on one stream.

I found the following guide on the Internet, but it seems that it opens two clients on two streams, and they communicate directly with each other - bypassing the server (which I will need to control the logic of the game): http://www.codeproject.com/Articles / 429144 / Simple-Instant-Messenger-with-SSL-Encryption-in-Cs

I am very interested and I will be grateful for any advice on how you are going to implement the application (mainly the server class).

I hope I have clearly explained my intentions. Thanks in advance.

+6
source share
3 answers

My first tip is to forget about TCP / IP and sockets here. You can definitely do this with this technology stack, but you will also have a lot of headache realizing everything you want. And the reason is that this technology is too low for this class of tasks. I would go with tcp / ip and sockets just for academic interest, or I need huge control over the message, or if I have very high performance requirements.

So my second tip is to look at WCF technology. Do not be afraid if you have not used it before. It is not that difficult. And if you were ready to use sockets for your application, you can handle WCF specifically. For your task, you can create a basic relationship using 1-2 hours from scratch using any WCF tutorial.

So, I would create a WCF server service that will have some API functions containing your business logic. It can be hosted on Windows, IIS, or even a console application. And your clients will use this WCF service, calling their functions such as it, from another local class in your project. WCF can also help you do the events you want (although this is a slightly more advanced topic). And you can even forget about the threads here, most things will work out of the box.

+8
source

First, as others have said, separate your game logic as much as you can, so the basic functionality will not depend too much on your communications infrastructure.

For communication, WCF can do the job. You can force your customers to send a request for a service hosted on IIS, authenticate / authenticate, and open a two-way channel, from where your service can push the results and link the start of new rounds.

As soon as one client connects, it waits for another. When this happens, it notifies the first client using the Duplex Channel callback and waits for it to be selected. Then he asks the second user, waiting for his answer. When it comes to, it notifies the result to both and restarts the game.

Going a little deeper into the implementation:

You will have a service with some operations (e.g. Register, PushDecision, if necessary). You will also define a callback interface, with operations that your service will have to click on the client (NotifyResult, RequestDecision, again, these are examples). You then create proxies for your clients that map to your service operations and implement callback operations so that they display events and raise them when the service clicks messages.

Use case:

Client A creates a proxy, calls a register on the server. The server receives the call, registers the cyclone, and stores the callback object in state. A duplex connection will be established. What does it mean? This means that (if you use PollingDuplexBinding, as you probably want), now the proxy in client A will make long polling requests to the server, checking if there is a callback message. If not, then it means long polls again. If there is, it calls the callback method in the proxy server, passing the data that the server clicks. The callback method in the proxy will typically raise an event or execute a delegate that you can select.

Client B connects (calls the register), does the same as for A, and the server, noticing that two clients are connected, requests A's response to its stored callback. This can happen during processing of a B-register call, or it can be launched to execute in a new thread (or, better, run in ThreadPool or run a new Task ) in a register B call.

Client A will receive a server callback requesting its selection. He can then notify the user and get a choice through the user interface. A new call is made on the server (for example, PushDecision). The server receives the choice of client A, requests B in the same way. After he has both answers, he calculates the result and pushes the result to the Clients.

The advantage of using Duplex channels with PollingDuplex with WPF is that since it uses long polling, there is no need to use ports other than 80.

This is by no means the final implementation, it is just a small guide to give you some ideas, and not just give you some vague advice. Of course, there can be many other ways to do this with WCF.

We can first assume that the application can only process two users at a time, and then, if you want, you can scale, which makes your service maintain some form of state with a mapping table with blocked access as another example.

Some thoughts on WCF: there is a simple way to start development using WCF using Visual Studio tools (svcutil), but I don't like this approach. You are not familiar with the WCF infrastructure, you are attached to the verbose magic with which it generates your proxies, and you lose flexibility, especially in special scenarios such as duplex polling, which you might want to use.

In another way, that is, manually creating your services and your proxies is not so difficult, and it becomes very interesting if you understand what can be done with it. In this regard, I can give you one piece of advice: do everything possible so that your proxy operations use Async Pattern based on tasks (you can see various ways to implement proxy operations here ). This will make your code much cleaner and more direct in combination with the new C # async / waitait keywords , and your user interface will be a joy to implement.

I can recommend some links to get you started. Some of them are old, but very didactic.

  • There used to be a fantastic WCF article in this link , but it seems to be disabled now. Fortunately, I found the content available there in the file for this link .
  • This covers your hosting options.
  • WCF Infrastructure Topics: Link
  • Duplex Services Topics: Link Link Link
  • Async task-based themes: link link link
+4
source

Well, one piece of advice I can give you if you insist that all users exchange data through the server and you want your application to scale:

  • Separate your logic (understanding every part of the logic you want to build on the server)

  • Make your classes so that it can handle multiple users per transaction

  • Use IOCP whenever possible

  • it depends on the structure of your application, if you need authentication and user profiles, etc. you can present WCF or any web service to the user and hide your actual action in the background (it will cost you performance but it may be the only suitable solution that you have), so you can have your authentication system at the top parts of the logic of your server and pipelined logic of actions in the back. ie users get authentication in order to have access to the services provided by the server, but these services convey all the users and process as many as possible at the same time - if you do not need authentication, you can directly contact the logic of your server and you can use the completion ports on request user - there is a lot of work to do here.

+1
source

All Articles