Server端架构

  • Server:创建TCP的socket,监听客户端的连接。当一个客户端连接server的时候,server会单独创建一个client用来维护跟某一个客户端的连接,进行一个收发消息。client会有多个,一个客户端对应一个client,所以说后续不同的请求是通过client来调用controller进行处理。server会对client做一个管理,管理所里客户端的连接(为了优化对数据库的访问速度我们创建多个连接,如果只使用一个连接所有客户端都用一个连接查询起来就会慢,所以我们创建多个连接,一个client一个controller,connHelper放到client这边。)client会通过ConnHelper去建立一个连接,这样的话一个客户端就是一个连接,当客户端不需要的时候我们就对它进行一个销毁,跟数据库的连接也销毁掉。我们每次来一个请求client会去调用controller,controller会去调用DAO,接着DAO会去操作有需要跟数据库操作的话会操作数据库。(DAO有需要跟数据库做连接的时候就会从client这边来进行取得跟客户端的连接就是mysqlconnection)
  • Controller:用来处理客户端的请求的,发送到server,server会调用相应的controller来进行处理。controller有很多个,处理不同的客户端的连接和请求(设置一个controller处理多个请求,如果一对一那controller会过多)。定义一个枚举类型去判断是由哪个controller来进行的处理。在处理的过程中可能涉及到数据库相关,就是DAO层交互。
  • ControllerManger用来管理我们当前服务器端有哪些controller
  • DAO:data access object,数据访问对象是一个面向对象的数据库接口。其实就是用来操作数据库的。DAO层要处理数据库要和两类打交道,一类是Model;另一类是ConnHelper。
  • Model:就是模型——数据库模型。跟我们数据库里的表是对应着的,一个model类对应一个数据库表。
  • ConnHelper:工具类,用来连接数据库的,建立mysqlConnect 。
  • Message是为client服务的,使用Message来解析消息。

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Net.Sockets;
 5 using System.Net;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace GameServer.Server
10 {
11      class Server
12     {
13         //定义一些变量存储一些东西
14         private IPEndPoint _ipEndPoint;
15         private Socket serverSocket;
16         private List<Client> clientList;//把所有的客户端都管理起来,创建一个list集合
17                                         //给他提供一个空的构造方法,后期进行一个设置
18         public Server()
19         {
20 
21         }
22         //给他提供一个带参数的构造方法,我们开启服务端的时候需要ip和端口号。
23         public Server(string ipStr, int port)
24         {
25             SetIpAndPort(ipStr, port);
26         }
27         //set方法设置IP和端口号
28         public void SetIpAndPort(string ipStr, int port)
29         {
30             _ipEndPoint = new IPEndPoint(IPAddress.Parse(ipStr), port);
31         }
32         //进行启动server端,启动监听
33         public void Start()
34         {
35             serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
36             serverSocket.Bind(_ipEndPoint);
37             serverSocket.Listen(0);
38             serverSocket.BeginAccept(AcceptCallBack, null);
39         }
40         //使用异步的方式调用多个客户端的连接
41         private void AcceptCallBack(IAsyncResult ar)
42         {
43             Socket clientSocket = serverSocket.EndAccept(ar);//得到跟客户端的连接,接收到客户端的连接
44             Client client = new Client(clientSocket, this);
45             client.Start();
46             clientList.Add(client);
47 
48         }
49         public void RemoveClient(Client client)
50         {
51             //多个客户端可能都要去访问clientList去进行移除,把他锁定了之后再进行移除,防止多线程同时访问共享的clientList矛盾异常
52             lock (clientList)
53             {
54                 clientList.Remove(client);
55 
56             }
57 
58         }
59     }
60 }
 1 using Microsoft.VisualBasic;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Net.Sockets;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace GameServer.Server
10 {
11    
12         //专门用来处理与客户端的通信问题
13         class Client
14         {
15             private Socket clientSocket;
16             private Server server;//这边可能会与server交互,也需要持有一下
17             private Message msg=new Message();
18 
19             //给他提供一个空的构造方法,后期进行一个设置
20             public Client() { }
21             public Client(Socket clientSocket, Server server)
22             {
23                 this.clientSocket = clientSocket;
24                 this.server = server;
25             }
26             //表示开启监听
27             public void Start()
28             {
29                 clientSocket.BeginReceive(msg.Data, msg.StartIndex, msg.RemainSize, SocketFlags.None, ReceiveCallBack, null);//读取的时候要送到msg里面
30             }
31             private void ReceiveCallBack(IAsyncResult ar)
32             {
33                 try
34                 {
35                     int count = clientSocket.EndReceive(ar);//首先要接收数据的长度
36                     if (count == 0)
37                     {
38                         Close();
39                     }
40                 //todo  处理接收到的数据
41                 msg.ReadMessage(count);//进行消息的读取,读到消息之后转给controller去处理,然后由controller来决定需要做什么事情。
42                 Start();
43                 }
44                 catch (Exception e)
45                 {
46                     Console.WriteLine(e);
47                     Close();
48                 }
49             }
50             //专门断开连接的方法
51             private void Close()
52             {
53                 if (clientSocket != null)
54                     clientSocket.Close();
55                 server.RemoveClient(this);
56             }
57         }
58 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace GameServer.Server
 8 {
 9     class Message
10     {
11         private byte[] data = new byte[1024];
12         private int startIndex = 0;//我们存取了多少个字节的数据在数组里面
13 
14         //public void AddCount(int count)
15         //{
16         //    startIndex += count;
17         //}
18         public byte[] Data
19         {
20             get { return data; }
21         }
22         public int StartIndex
23         {
24             get { return startIndex; }
25         }
26         public int RemainSize
27         {
28             get { return data.Length - startIndex; }
29         }
30         /// <summary>
31         /// 解析数据或者叫做读取数据
32         /// </summary>
33         public void ReadMessage(int newDataAmount)
34         {
35             startIndex += newDataAmount;
36             while (true)
37             {
38                 if (startIndex <= 4) return;
39                 int count = BitConverter.ToInt32(data, 0);
40                 if ((startIndex - 4) >= count)
41                 {
42                     Console.WriteLine(startIndex);
43                     Console.WriteLine(count);
44                     string s = Encoding.UTF8.GetString(data, 4, count);
45                     Console.WriteLine("解析出来一条数据:" + s);
46                     Array.Copy(data, count + 4, data, 0, startIndex - 4 - count);
47                     startIndex -= (count + 4);
48                 }
49                 else
50                 {
51                     break;
52                 }
53             }
54         }
55     }
56 
57 }

 

 

 

 

 

posted @ 2024-07-31 09:19  花生的小福蝶  阅读(41)  评论(0)    收藏  举报