Step by step Game server development (2) Complete login, chat, and step by step game

Source: Internet
Author: User
Tags sendmsg

Step by step Game server development (2) Complete login, chat, and step by step game

I know that many of you don't want to read this article in the blog Park, but this is the beginning of my series of articles. Please forgive me.

Multithreading, thread actuator (For details, refer to), socket communication (For details, refer)

My blog-related article test code, example, full svn address. Http://code.taobao.org/svn/flynetwork_csharp/trunk/Flynetwork/BlogTest)

Provides all source code functional blocks. I hope you can provide valuable comments.

Mo Qian completed the complete functions of the multi-threaded auxiliary class library (or bugs may need to be fixed or optimized later), and socket completed the tcp and http service listening functions, udp and websocket are still in perfect state.

If you want to complete this auxiliary class library with me, contact me to activate svn authorization.

Therefore, the source code is provided for free. You are welcome to join the project, regardless of the individual, enterprise, or commercial use. The only requirement is to keep the following words. Thank you for your cooperation ~!

1 /**
2  * 
3 * @author stumbled programmer
4 * @Blog http://www.cnblogs.com/ty408/
5 * @mail 492794628@qq.com
6 * @phone 13882122019
7 *
8  */
 

Okay to start our topic

In the development of server projects, the most important thing is the login problem or the authorization problem.

We first create a console program

Reference to my two libraries Sz.Network.SocketPool, Sz.Network.ThreadPool are socket help library thread help library.

Sz means stumble. Please excuse me. I like this code-named "Falling Programmer"

We first create a message processor MessagePool

 

1 public class MessagePool: ISocketPool 2 {3 public void ActiveSocket (IOSession client) 4 {5} 6 7 public void CloseSocket (IOSession client) 8 {9 10} 11 12 public void ReadMessage (IOSession client, SocketMessage message) 13 {14 15 } 16 17 18 public void ActiveHttp (HttpClient client, string bind, Dictionary <string, string> parms) 19 {20 if (bind.Equals ("/ test /")) 21 {22 ThreadManager.GetInstance.AddTask (ServerManager.LoginThreadID , new LoginHttpHandler (client, parms)); 23} 24} 25 26 public void IOSessionException (IOSession client, Exception exception) 27 {28 Logger.Error ("Internal Error", exception); 29} 30 31 public void HttpException (HttpClient client, Exception exception) 32 {33 Logger.Error ("Internal Error", exception); 34} 35} View Code
 

 

Then add in the mian function

1 Sz.Network.SocketPool.ListenersBox.GetInstance.SetParams (new MessagePool (), typeof (MarshalEndian));
2 Sz.Network.SocketPool.ListenersBox.GetInstance.Start ("tcp: *: 9527", "http: // *: 8001 / test /");
In this way, we started the server monitoring, here is a brief introduction to why I created two monitoring of tcp and http?

 

This is because of experience and working relationship, because I am committed to game development, the server needs to create two tcp usually used for normal communication, and http listening login module, or some non-essential data exchange and third parties Login authorization needs to be enabled. Also because http is a short connection, there is no need to save the communication object, which reduces system consumption and TCP order of magnitude consumption.


If you do not understand, you can not join http monitoring. Look directly at the socket of tcp.

1 [2015-04-15 18: 12: 09: 899: Info] Start Listen Tcp Socket-> 0.0.0.0:9527
2 [2015-04-15 18: 12: 09: 906: Info] Start Listen Http Socket-> 0.0.0.0:8001/test/
Run the program and output.

The monitoring of tcp and http is turned on. Let's ignore the role of http for now.

We started to prepare for the development of the login module. Students all knew that the first thing to face when logging in was the problem of multiple simultaneous logins.

If lock is added to prevent multiple logins at the same time, then the server is bound to freeze. Factors such as low throughput. Then we consider adding this piece to a separate thread surprise handling. That is to help log in and log out, put in the same thread processing. It is possible to prevent multiple simultaneous logins without locking.

Next we need to take a thread from the Sz.Network.ThreadPool library

public static readonly long LoginThreadID = ThreadManager.GetInstance.GetThreadModel ("Login Processor");
Used to control login and logout

 

 

Create a CloseTcpHandler to handle the link port handler needs to inherit TaskBase under Sz.Network.ThreadPool

 

1 public class CloseTcpHandler: TaskBase 2 {3 4 IOSession client; 5 SocketMessage message; 6 7 public CloseTcpHandler (IOSession client) 8: base ("Tcp login processing") 9 {10 this.client = client; 11} 12 13 14 public override void TaskRun () 15 {16 17} 18} View Code
 

Then we modify the MessagePool class

   public void ActiveSocket (IOSession client)
        {
            //client.SendMsg(new SocketMessage (1, System.Text.UTF8Encoding.Default.GetBytes ("Holle Server! client")));
        }

        public void CloseSocket (IOSession client)
        {
            ThreadManager.GetInstance.AddTask (ServerManager.LoginThreadID, new CloseTcpHandler (client));
        }
 

In this way, the disconnection process is handed over to the ServerManager.LoginThreadID thread.

Let's create another LoginTcpHandler to handle the login program. Need to inherit TaskBase under Sz.Network.ThreadPool

 

View Code
 

Modify the MessagePool class to handle login messages

 

 1 public void ReadMessage (IOSession client, SocketMessage message)
 2         {
 3 switch (message.MsgID)
 4 {
 5 case 1: // Login
 6 case 2:
 7 ThreadManager.GetInstance.AddTask (ServerManager.LoginThreadID, new LoginTcpHandler (client, message));
 8 break;
 9 default:
10 Logger.Error ("Unbound Message ID" + message.MsgID);
11 break;
12}
13}
Here is my custom message ID is 1 and 2 one is login and one is logout.

In this way, the login event is also handed over to the ServerManager.LoginThreadID thread

LoginTcpHandler taskrun method

1 public override void TaskRun () 2 {3 using (MemoryStream msReader = new MemoryStream (message.MsgBuffer)) 4 {5 using (System.IO.BinaryReader srReader = new BinaryReader (msReader, UTF8Encoding.Default)) 6 {7 using ( MemoryStream msWriter = new MemoryStream ()) 8 {9 using (System.IO.BinaryWriter srWriter = new BinaryWriter (msWriter, UTF8Encoding.Default)) 10 {11 switch (message.MsgID) 12 {13 case 1: // Login 14 string username = srReader.ReadString (); 15 if (! LoginManager.GetInstance.LoginNames.Contains (username)) 16 {17 LoginManager.GetInstance.LoginNames.Add (username); 18 if (! LoginManager.GetInstance.LoginIPs.ContainsKey (client .ID)) 19 {20 LoginManager.GetInstance.LoginIPs [client.ID] = username; 21 LoginManager.GetInstance.Sessions.Add (client); 22} 23 srWriter.Write (true); 24 srWriter.Write (username + " Log into the chat room "); 25 Logger.Info (client.RemoteEndPoint +" "+ username +" Login successful "); 26 SocketMessage sm = new SocketMessage (message.MsgID, msWriter.GetBuffer ()); 27 Serv erManager.GetInstance.Tell_All (sm); 28} 29 else 30 {31 srWriter.Write (false); 32 srWriter.Write ("Login name is duplicated, please change one"); 33 Logger.Info (client.RemoteEndPoint + "" + username + "Duplicate login name!"); 34 SocketMessage sm = new SocketMessage (message.MsgID, msWriter.GetBuffer ()); 35 client.SendMsg (sm); 36} 37 break; 38 case 2: // logout 39 40 break; 41 default: 42 43 break; 44} 45} 46} 47} 48} 49} View Code

CloseTcpHandler taskrun method

1 public override void TaskRun () 2 {3 if (LoginManager.GetInstance.LoginIPs.ContainsKey (client.ID)) 4 {5 string username = LoginManager.GetInstance.LoginIPs [client.ID]; 6 LoginManager.GetInstance.LoginIPs.Remove (client.ID); 7 LoginManager.GetInstance.LoginIPs.Remove (username); 8 LoginManager.GetInstance.Sessions.Remove (client); 9 using (MemoryStream msWriter = new MemoryStream ()) 10 {11 using (System.IO.BinaryWriter srWriter = new BinaryWriter (msWriter, UTF8Encoding.Default)) 12 {13 srWriter.Write (username + "quit chat room"); 14 SocketMessage sm = new SocketMessage (3, msWriter.GetBuffer ()); /// 3 means to send a message 15 ServerManager.GetInstance.Tell_All (sm); 16} 17 } 18} 19} View Code
 

Since the code is not complete here, if you are interested, you can download the source code to try

 

After starting the two clients, I saw that two links were created and logged in to the server.

Because chat and login are two different modules, in order to improve efficiency, we create a chat thread again

public static readonly long ChatThreadID = ThreadManager.GetInstance.GetThreadModel ("chat processor");

Next we add in the switch of MessagePool's ReadMessage method

case 3: // chat
                    ThreadManager.GetInstance.AddTask (ServerManager.ChatThreadID, new Chat.ChatHandler (client, message));
                    break;
 

In this way, we will process all the chat messages forwarded by ServerManager.ChatThreadID. Even if it is stuck, it will not affect the client's chat sending message and the new client's request to log in.

Here we can also consider grouping and chat grouping functions. For example, private chat, group chat and other group threads are executed.

Creating a ChatHandler needs to inherit TaskBase under Sz.Network.ThreadPool

 

1 public class ChatHandler: TaskBase 2 {3 IOSession client; 4 5 SocketMessage message; 6 7 8 public ChatHandler (IOSession client, SocketMessage message) 9: base ("chat processing task") 10 {11 this.client = client; 12 this .message = message; 13} 14 15 16 public override void TaskRun () 17 {18 using (MemoryStream msWriter = new MemoryStream ()) 19 {20 using (System.IO.BinaryWriter srWriter = new BinaryWriter (msWriter, UTF8Encoding.Default) ) 21 {22 // Build input buffer 23 // Verify login status 24 if (LoginManager.GetInstance.LoginIPs.ContainsKey (client.ID)) 25 {26 string username = LoginManager.GetInstance.LoginIPs [client.ID]; 27 using (MemoryStream msReader = new MemoryStream (message.MsgBuffer)) 28 {29 using (System.IO.BinaryReader srReader = new BinaryReader (msReader, UTF8Encoding.Default)) 30 {31 string msg = srReader.ReadString (); 32 msg = client .RemoteEndPoint + "" + username + "" + msg; 33 Logger.Info (msg); 34 srWriter.Write (msg); 35 SocketMessage sm = new SocketMessage (mess age.MsgID, msWriter.GetBuffer ()); 36 ServerManager.GetInstance.Tell_All (sm); 37} 38} 39} 40 else 41 {42 srWriter.Write ("Not yet logged in"); 43 SocketMessage sm = new SocketMessage (message .MsgID, msWriter.GetBuffer ()); 44 client.SendMsg (sm); 45} 46} 47} 48} 49} View Code
 

Try a message

Here is a simple chat server. After logging in to chat, the client is a wpf program. There is no source code and process posted. If you need or want to study, please download the svn source code and check the situation yourself.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.