123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- #if COMBAT_SERVER
- using System;
- using System.Buffers;
- using System.Collections.Generic;
- using System.IO.Compression;
- using System.Net;
- using System.Net.Sockets;
- using System.Net.Sockets.Kcp;
- using System.Threading;
- using Com.Fort23.Protocol.Protobuf;
- using Fort23.UTool;
- using Utility;
- namespace Core.KCPTool
- {
- public class KCPServer : IServer
- {
- private Socket socket;
- private Thread _udpClientThread;
- private byte[] buffer = new byte[2048];
- private ArraySegment<byte> ArraySegment;
- public Map<long, IServerConnection> KcpServerConnections = new Map<long, IServerConnection>();
- private List<CombatSynchronizeRequest> CombatSynchronizeRequests = new List<CombatSynchronizeRequest>();
- // private List<IServerConnection> awaitConnections = new List<IServerConnection>();
- private IServerManager iServerManager;
- private Queue<SendDataBuffer> _sendDataBuffers = new Queue<SendDataBuffer>();
- private long lasetSendTime = 0;
- public KCPServer(int port, IServerManager iServerManager)
- {
- this.iServerManager = iServerManager;
- LogTool.Log("创建UDP链接端口"+port+"__");
- socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.Bind(new IPEndPoint(IPAddress.Any, port));
- ArraySegment = new ArraySegment<byte>(buffer);
- _udpClientThread = new Thread(BeginRecv);
- _udpClientThread.Start();
- }
- public void SocketSendTo(byte[] buffer, EndPoint endPoint)
- {
- // if (_sendDataBuffers.Count > 0)
- {
- // LogTool.Log("发送消息:"+endPoint.GetHashCode());
- SendDataBuffer sendDataBuffer = new SendDataBuffer();
- sendDataBuffer.buffer = buffer;
- sendDataBuffer.endPoint = endPoint;
- _sendDataBuffers.Enqueue(sendDataBuffer);
- }
- // else
- // {
- // SocketSendToForBuffer(buffer, endPoint);
- // }
- }
- private void SocketSendToForBuffer(byte[] buffer, EndPoint endPoint)
- {
- socket.SendTo(buffer, endPoint);
- }
- private byte[] AssembleData(SendDataType sendDataType, byte[] buffer)
- {
- byte[] sendBuff = new byte[buffer.Length + 1];
- sendBuff[0] = (byte)sendDataType;
- Array.Copy(buffer, 0, sendBuff, 1, buffer.Length);
- return sendBuff;
- }
- public bool SendToPlayer(SendDataType sendDataType, CombatSynchronizeType combatSynchronizeType, byte[] buffer,
- long playerId)
- {
- if (KcpServerConnections.Count <= 0)
- {
- return true;
- }
- byte[] sendBuff = AssembleData(sendDataType, buffer);
-
- bool isOk = false;
- lock (KcpServerConnections)
- {
- for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
- {
- if (KcpServerConnections.Value.isConnected)
- {
- isOk = true;
- }
- if (playerId != -1 && KcpServerConnections.Value.playerId != playerId)
- {
- continue;
- }
- KcpServerConnections.Value.SendData(sendBuff, sendBuff.Length);
- }
- }
- return isOk;
- }
- public void AddCombatSynchronizeRequest(CombatSynchronizeRequest combatSynchronizeRequest)
- {
- lock (CombatSynchronizeRequests)
- {
- CombatSynchronizeRequests.Add(combatSynchronizeRequest);
- }
- }
- public CombatSynchronizeRequest[] GetCombatSynchronizeRequest(bool isClear)
- {
- if (CombatSynchronizeRequests.Count <= 0)
- {
- return null;
- }
- lock (CombatSynchronizeRequests)
- {
- CombatSynchronizeRequest[] allData = CombatSynchronizeRequests.ToArray();
- CombatSynchronizeRequests.Clear();
- return allData;
- }
- }
- public bool UpdateKCP()
- {
- bool isConnected = false;
- if (_sendDataBuffers.TryDequeue(out SendDataBuffer sendDataBuffer))
- {
- SocketSendToForBuffer(sendDataBuffer.buffer, sendDataBuffer.endPoint);
- }
- long currTime = DateTime.Now.Ticks;
- if (currTime - lasetSendTime > 50000000)
- {
- lasetSendTime = currTime;
- SendToPlayer(SendDataType.Heartbeat, CombatSynchronizeType.PrepareStart, new byte[1], -1);
- }
- lock (KcpServerConnections)
- {
- for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
- {
- if (KcpServerConnections.Value.isConnected)
- {
- isConnected = true;
- KcpServerConnections.Value.Update();
- }
- }
- }
- // lock (awaitConnections)
- // {
- // for (int i = 0; i < awaitConnections.Count; i++)
- // {
- // awaitConnections[i].Update();
- // }
- // }
- return isConnected;
- }
- public void RecvKCP()
- {
- lock (KcpServerConnections)
- {
- for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
- {
- if (KcpServerConnections.Value.isConnected)
- {
- KcpServerConnections.Value.ReceiveAsync();
- }
- }
- }
- // lock (awaitConnections)
- // {
- // for (int i = 0; i < awaitConnections.Count; i++)
- // {
- // awaitConnections[i].ReceiveAsync();
- // }
- // }
- }
- private async void BeginRecv()
- {
- while (_udpClientThread != null)
- {
- EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
- try
- {
- SocketReceiveFromResult receiveFromResult =
- await socket.ReceiveFromAsync(ArraySegment, SocketFlags.None, newClientEP);
- if (receiveFromResult.ReceivedBytes <= 0)
- {
- Thread.Sleep(10);
- continue;
- }
- newClientEP = receiveFromResult.RemoteEndPoint;
- byte[] data = new byte[receiveFromResult.ReceivedBytes];
- Array.Copy(buffer, 0, data, 0, data.Length);
- if (receiveFromResult.ReceivedBytes == 8) //链接到了
- {
- long playerId = SocketTool.ByteToLong(data);
- CreateNewConnections(newClientEP, playerId);
- continue;
- }
- else
- {
- IServerConnection kcpServerConnection = GetConnection(newClientEP.GetHashCode());
- if (kcpServerConnection == null)
- {
- LogTool.Error("没有找到对应的客户端链接");
- }
- else
- {
- int ok = kcpServerConnection.Input(data);
- }
- }
- }
- catch (Exception e)
- {
- // SocketException socketException = e as SocketException;
- // if (socketException.ErrorCode == 10054)
- // {
- // IServerConnection kcpServerConnection = GetConnection(newClientEP.GetHashCode());
- // if (kcpServerConnection != null) //链接已经断开
- // {
- // kcpServerConnection.isConnected = false;
- // }
- // }
- LogTool.Error(e);
- Thread.Sleep(10);
- // socket.Disconnect();
- }
- }
- }
- public void RemovePlayer(long playerId)
- {
- lock (KcpServerConnections)
- {
- KcpServerConnections.Remove(playerId);
- }
- }
- public IServerConnection GetConnection(long playerId)
- {
- lock (KcpServerConnections)
- {
- for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
- {
- if (playerId != -1 && KcpServerConnections.Value.playerId != playerId)
- {
- continue;
- }
- return KcpServerConnections.Value;
- }
- }
- return null;
- }
- public IServerConnection GetConnection(int connectionId)
- {
- lock (KcpServerConnections)
- {
- for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
- {
- if (connectionId != -1 && KcpServerConnections.Value.connectionID != connectionId)
- {
- continue;
- }
- return KcpServerConnections.Value;
- }
- }
- return null;
- }
- public void RemoveServerConnection(long playerId)
- {
- lock (KcpServerConnections)
- {
- if (KcpServerConnections.TryGetValue(playerId, out IServerConnection serverConnection))
- {
- LogTool.Log("移除成功UDP" + playerId);
- serverConnection.Dispose();
- KcpServerConnections.Remove(playerId);
- }
- }
- }
- public void ConnectionUpdate()
- {
- if (socket != null)
- {
- try
- {
- UpdateKCP();
- RecvKCP();
- }
- catch (Exception e)
- {
- LogTool.Exception(e);
- }
- }
- }
- public async void SendGameFrame(int gameFrame, IServerConnection kcpServerConnection)
- {
- // if (gameFrame > 0)
- {
- LogTool.Log("重传数据开始" + gameFrame);
- int maxCount = iServerManager.GetSendBufferSize();
- for (int i = gameFrame; i < maxCount; i++)
- {
- byte[] _sendBufferdata = iServerManager.GetSendBuffer(i);
- if (_sendBufferdata != null)
- {
- _sendBufferdata = AssembleData(SendDataType.Data, _sendBufferdata);
- kcpServerConnection.SendData(_sendBufferdata, _sendBufferdata.Length);
- await System.Threading.Tasks.Task.Delay(1);
- }
- }
- }
- }
- public void AddServerConnection(long playerId, int gameFrame, IServerConnection kcpServerConnection)
- {
- lock (KcpServerConnections)
- {
- RemoveServerConnection(playerId);
- iServerManager.AddServerConnection(this, kcpServerConnection);
- KcpServerConnections.Add(playerId, kcpServerConnection);
- LogTool.Log("握手成功UDP" + playerId);
- iServerManager.AddServerConnection(this, kcpServerConnection);
- byte[] data = SocketTool.LongToByte(playerId);
- SendToPlayer(SendDataType.ShakeHands, CombatSynchronizeType.PrepareStart, data, playerId);
- }
- // lock (awaitConnections)
- // {
- // awaitConnections.Remove(kcpServerConnection);
- // }
- }
- public IServerConnection CreateNewConnections(EndPoint newClientEP, long playerId)
- {
- // int code = newClientEP.GetHashCode();
- KCPServerConnection kcpServerConnection = new KCPServerConnection(this, (IPEndPoint)newClientEP);
- kcpServerConnection.playerId = playerId;
- kcpServerConnection.connectionID = newClientEP.GetHashCode();
- LogTool.Log("创建新的链接UDP" + newClientEP);
- AddServerConnection(playerId, 0, kcpServerConnection);
- return kcpServerConnection;
- }
- public void Dispose()
- {
- _udpClientThread = null;
- socket?.Dispose();
- socket = null;
- }
- }
- }
- #endif
|