自动重连和内存流优化

This commit is contained in:
sin365 2023-12-14 18:15:04 +08:00
parent 902c7859ee
commit 4f9cb4d22d
25 changed files with 310 additions and 141 deletions

View File

@ -1,5 +1,4 @@
using Google.Protobuf; using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using HunterProtobufCore; using HunterProtobufCore;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
@ -37,9 +36,11 @@ namespace HaoYueNet.ClientNetwork
private System.Timers.Timer _heartTimer; private System.Timers.Timer _heartTimer;
public void Init(string IP, int port, bool bBindReuseAddress = false,int bBindport = 0) public static string LastConnectIP;
{ public static int LastConnectPort;
public bool Init(string IP, int port, bool bBindReuseAddress = false,int bBindport = 0)
{
LogOut("==>初始化网络核心"); LogOut("==>初始化网络核心");
RevIndex = MaxRevIndexNum; RevIndex = MaxRevIndexNum;
@ -52,10 +53,12 @@ namespace HaoYueNet.ClientNetwork
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, Convert.ToInt32(bBindport)); IPEndPoint ipe = new IPEndPoint(IPAddress.Any, Convert.ToInt32(bBindport));
client.Bind(ipe); client.Bind(ipe);
} }
Connect(IP, port); LastConnectIP = IP;
LastConnectPort = port;
return Connect(IP, port);
} }
public bool Connect(string IP, int port) bool Connect(string IP, int port)
{ {
//带回调的 //带回调的
try try
@ -246,10 +249,12 @@ namespace HaoYueNet.ClientNetwork
OnReceiveData(_c2s.HunterNetCoreCmdID, _c2s.HunterNetCoreERRORCode, _c2s.HunterNetCoreData.ToArray()); OnReceiveData(_c2s.HunterNetCoreCmdID, _c2s.HunterNetCoreERRORCode, _c2s.HunterNetCoreData.ToArray());
} }
MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
private void Recive(object o) private void Recive(object o)
{ {
var client = o as Socket; var client = o as Socket;
MemoryStream memoryStream = new MemoryStream();//开辟一个内存流 //MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
while (true) while (true)
{ {
@ -278,8 +283,6 @@ namespace HaoYueNet.ClientNetwork
while (true) while (true)
{ {
if (effective > 0)//如果接受到的消息不为0不为空 if (effective > 0)//如果接受到的消息不为0不为空
{ {
int HeadLength = 0;//包头长度(包头+包体) int HeadLength = 0;//包头长度(包头+包体)
@ -296,16 +299,29 @@ namespace HaoYueNet.ClientNetwork
//↓↓↓↓↓↓↓↓ ↓↓↓ //↓↓↓↓↓↓↓↓ ↓↓↓
if (getData.Length - StartIndex < HeadLength || HeadLength == -1) if (getData.Length - StartIndex < HeadLength || HeadLength == -1)
{ {
/*
memoryStream.Close();//关闭内存流 memoryStream.Close();//关闭内存流
memoryStream.Dispose();//释放内存资源 memoryStream.Dispose();//释放内存资源
memoryStream = new MemoryStream();//创建新的内存流 memoryStream = new MemoryStream();//创建新的内存流
*/
//流复用的方式 不用重新new申请
memoryStream.Position = 0;
memoryStream.SetLength(0);
memoryStream.Write(getData, StartIndex, getData.Length - StartIndex);//从新将接受的消息写入内存流 memoryStream.Write(getData, StartIndex, getData.Length - StartIndex);//从新将接受的消息写入内存流
break; break;
} }
else else
{ {
//把头去掉,就可以吃了,蛋白质是牛肉的六倍 //把头去掉,就可以吃了,蛋白质是牛肉的六倍
DataCallBackReady(getData.Skip(StartIndex+4).Take(HeadLength-4).ToArray()); //DataCallBackReady(getData.Skip(StartIndex+4).Take(HeadLength-4).ToArray());
//改为Array.Copy 提升效率
int CoreLenght = HeadLength - 4;
byte[] retData = new byte[CoreLenght];
Array.Copy(getData, StartIndex + 4, retData, 0, CoreLenght);
DataCallBackReady(retData);
StartIndex += HeadLength;//当读取一条完整的数据后,读取数据的起始下标应为当前接受到的消息体的长度(当前数据的尾部或下一条消息的首部) StartIndex += HeadLength;//当读取一条完整的数据后,读取数据的起始下标应为当前接受到的消息体的长度(当前数据的尾部或下一条消息的首部)
} }
} }

View File

@ -1,5 +1,4 @@
using Google.Protobuf; using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using HunterProtobufCore; using HunterProtobufCore;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
@ -252,10 +251,11 @@ namespace HaoYueNet.ClientNetwork
OnDataCallBack(_c2s.HunterNetCoreCmdID, _c2s.HunterNetCoreERRORCode, _c2s.HunterNetCoreData.ToArray()); OnDataCallBack(_c2s.HunterNetCoreCmdID, _c2s.HunterNetCoreERRORCode, _c2s.HunterNetCoreData.ToArray());
} }
MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
private void Recive(object o) private void Recive(object o)
{ {
var client = o as Socket; var client = o as Socket;
MemoryStream memoryStream = new MemoryStream();//开辟一个内存流 //MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
while (true) while (true)
{ {
@ -302,21 +302,33 @@ namespace HaoYueNet.ClientNetwork
//↓↓↓↓↓↓↓↓ ↓↓↓ //↓↓↓↓↓↓↓↓ ↓↓↓
if (getData.Length - StartIndex < HeadLength || HeadLength == -1) if (getData.Length - StartIndex < HeadLength || HeadLength == -1)
{ {
/*
memoryStream.Close();//关闭内存流 memoryStream.Close();//关闭内存流
memoryStream.Dispose();//释放内存资源 memoryStream.Dispose();//释放内存资源
memoryStream = new MemoryStream();//创建新的内存流 memoryStream = new MemoryStream();//创建新的内存流
*/
//流复用的方式 不用重新new申请
memoryStream.Position = 0;
memoryStream.SetLength(0);
memoryStream.Write(getData, StartIndex, getData.Length - StartIndex);//从新将接受的消息写入内存流 memoryStream.Write(getData, StartIndex, getData.Length - StartIndex);//从新将接受的消息写入内存流
break; break;
} }
else else
{ {
//把头去掉,就可以吃了,蛋白质是牛肉的六倍 //把头去掉,就可以吃了,蛋白质是牛肉的六倍
DataCallBackReady(getData.Skip(StartIndex+4).Take(HeadLength-4).ToArray()); //DataCallBackReady(getData.Skip(StartIndex+4).Take(HeadLength-4).ToArray());
//改为Array.Copy 提升效率
int CoreLenght = HeadLength - 4;
byte[] retData = new byte[CoreLenght];
Array.Copy(getData, StartIndex + 4, retData, 0, CoreLenght);
DataCallBackReady(retData);
StartIndex += HeadLength;//当读取一条完整的数据后,读取数据的起始下标应为当前接受到的消息体的长度(当前数据的尾部或下一条消息的首部) StartIndex += HeadLength;//当读取一条完整的数据后,读取数据的起始下标应为当前接受到的消息体的长度(当前数据的尾部或下一条消息的首部)
} }
} }
} }
} }
} }

View File

@ -6,13 +6,12 @@
#region Designer generated code #region Designer generated code
using pb = global::Google.Protobuf; using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection; using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic; namespace HunterProtobufCore
namespace HunterProtobufCore { {
/// <summary>Holder for reflection information generated from protobuf_HunterNetCore.proto</summary> /// <summary>Holder for reflection information generated from protobuf_HunterNetCore.proto</summary>
public static partial class ProtobufHunterNetCoreReflection { public static partial class ProtobufHunterNetCoreReflection {
#region Descriptor #region Descriptor
/// <summary>File descriptor for protobuf_HunterNetCore.proto</summary> /// <summary>File descriptor for protobuf_HunterNetCore.proto</summary>

View File

@ -249,10 +249,12 @@ namespace HaoYueNet.ClientNetworkNet4x
OnReceiveData(_c2s.HunterNetCoreCmdID, _c2s.HunterNetCoreERRORCode, _c2s.HunterNetCoreData.ToArray()); OnReceiveData(_c2s.HunterNetCoreCmdID, _c2s.HunterNetCoreERRORCode, _c2s.HunterNetCoreData.ToArray());
} }
MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
private void Recive(object o) private void Recive(object o)
{ {
var client = o as Socket; var client = o as Socket;
MemoryStream memoryStream = new MemoryStream();//开辟一个内存流 //MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
while (true) while (true)
{ {
@ -281,8 +283,6 @@ namespace HaoYueNet.ClientNetworkNet4x
while (true) while (true)
{ {
if (effective > 0)//如果接受到的消息不为0不为空 if (effective > 0)//如果接受到的消息不为0不为空
{ {
int HeadLength = 0;//包头长度(包头+包体) int HeadLength = 0;//包头长度(包头+包体)
@ -299,16 +299,29 @@ namespace HaoYueNet.ClientNetworkNet4x
//↓↓↓↓↓↓↓↓ ↓↓↓ //↓↓↓↓↓↓↓↓ ↓↓↓
if (getData.Length - StartIndex < HeadLength || HeadLength == -1) if (getData.Length - StartIndex < HeadLength || HeadLength == -1)
{ {
/*
memoryStream.Close();//关闭内存流 memoryStream.Close();//关闭内存流
memoryStream.Dispose();//释放内存资源 memoryStream.Dispose();//释放内存资源
memoryStream = new MemoryStream();//创建新的内存流 memoryStream = new MemoryStream();//创建新的内存流
*/
//流复用的方式 不用重新new申请
memoryStream.Position = 0;
memoryStream.SetLength(0);
memoryStream.Write(getData, StartIndex, getData.Length - StartIndex);//从新将接受的消息写入内存流 memoryStream.Write(getData, StartIndex, getData.Length - StartIndex);//从新将接受的消息写入内存流
break; break;
} }
else else
{ {
//把头去掉,就可以吃了,蛋白质是牛肉的六倍 //把头去掉,就可以吃了,蛋白质是牛肉的六倍
DataCallBackReady(getData.Skip(StartIndex + 4).Take(HeadLength - 4).ToArray()); //DataCallBackReady(getData.Skip(StartIndex+4).Take(HeadLength-4).ToArray());
//改为Array.Copy 提升效率
int CoreLenght = HeadLength - 4;
byte[] retData = new byte[CoreLenght];
Array.Copy(getData, StartIndex + 4, retData, 0, CoreLenght);
DataCallBackReady(retData);
StartIndex += HeadLength;//当读取一条完整的数据后,读取数据的起始下标应为当前接受到的消息体的长度(当前数据的尾部或下一条消息的首部) StartIndex += HeadLength;//当读取一条完整的数据后,读取数据的起始下标应为当前接受到的消息体的长度(当前数据的尾部或下一条消息的首部)
} }
} }

View File

@ -31,16 +31,16 @@ namespace HaoYueNet.ClientNetworkNet4x
private static int MaxSendIndexNum = 3; private static int MaxSendIndexNum = 3;
//响应倒计时计数 //响应倒计时计数
private static int RevIndex=0; private static int RevIndex = 0;
//发送倒计时计数 //发送倒计时计数
private static int SendIndex=0; private static int SendIndex = 0;
//计时器间隔 //计时器间隔
private static int TimerInterval = 3000; private static int TimerInterval = 3000;
private System.Timers.Timer _heartTimer; private System.Timers.Timer _heartTimer;
public void Init(string IP, int port, bool bBindReuseAddress = false,int bBindport = 0) public void Init(string IP, int port, bool bBindReuseAddress = false, int bBindport = 0)
{ {
LogOut("==>初始化网络核心"); LogOut("==>初始化网络核心");
@ -255,15 +255,16 @@ namespace HaoYueNet.ClientNetworkNet4x
OnDataCallBack(_c2s.HunterNetCoreCmdID, _c2s.HunterNetCoreERRORCode, _c2s.HunterNetCoreData.ToArray()); OnDataCallBack(_c2s.HunterNetCoreCmdID, _c2s.HunterNetCoreERRORCode, _c2s.HunterNetCoreData.ToArray());
} }
MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
private void Recive(object o) private void Recive(object o)
{ {
var client = o as Socket; var client = o as Socket;
MemoryStream memoryStream = new MemoryStream();//开辟一个内存流 //MemoryStream memoryStream = new MemoryStream();//开辟一个内存流
while (true) while (true)
{ {
byte[] buffer = new byte[1024 * 1024 * 2]; byte[] buffer = new byte[1024 * 1024 * 2];
int effective=0; int effective = 0;
try try
{ {
effective = client.Receive(buffer); effective = client.Receive(buffer);
@ -272,7 +273,7 @@ namespace HaoYueNet.ClientNetworkNet4x
continue; continue;
} }
} }
catch(Exception ex) catch (Exception ex)
{ {
//远程主机强迫关闭了一个现有的连接 //远程主机强迫关闭了一个现有的连接
OnCloseReady(); OnCloseReady();
@ -305,21 +306,33 @@ namespace HaoYueNet.ClientNetworkNet4x
//↓↓↓↓↓↓↓↓ ↓↓↓ //↓↓↓↓↓↓↓↓ ↓↓↓
if (getData.Length - StartIndex < HeadLength || HeadLength == -1) if (getData.Length - StartIndex < HeadLength || HeadLength == -1)
{ {
/*
memoryStream.Close();//关闭内存流 memoryStream.Close();//关闭内存流
memoryStream.Dispose();//释放内存资源 memoryStream.Dispose();//释放内存资源
memoryStream = new MemoryStream();//创建新的内存流 memoryStream = new MemoryStream();//创建新的内存流
*/
//流复用的方式 不用重新new申请
memoryStream.Position = 0;
memoryStream.SetLength(0);
memoryStream.Write(getData, StartIndex, getData.Length - StartIndex);//从新将接受的消息写入内存流 memoryStream.Write(getData, StartIndex, getData.Length - StartIndex);//从新将接受的消息写入内存流
break; break;
} }
else else
{ {
//把头去掉,就可以吃了,蛋白质是牛肉的六倍 //把头去掉,就可以吃了,蛋白质是牛肉的六倍
DataCallBackReady(getData.Skip(StartIndex+4).Take(HeadLength-4).ToArray()); //DataCallBackReady(getData.Skip(StartIndex+4).Take(HeadLength-4).ToArray());
//改为Array.Copy 提升效率
int CoreLenght = HeadLength - 4;
byte[] retData = new byte[CoreLenght];
Array.Copy(getData, StartIndex + 4, retData, 0, CoreLenght);
DataCallBackReady(retData);
StartIndex += HeadLength;//当读取一条完整的数据后,读取数据的起始下标应为当前接受到的消息体的长度(当前数据的尾部或下一条消息的首部) StartIndex += HeadLength;//当读取一条完整的数据后,读取数据的起始下标应为当前接受到的消息体的长度(当前数据的尾部或下一条消息的首部)
} }
} }
} }
} }
} }

View File

@ -6,13 +6,12 @@
#region Designer generated code #region Designer generated code
using pb = global::Google.Protobuf; using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection; using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic; namespace HunterProtobufCore
namespace HunterProtobufCore { {
/// <summary>Holder for reflection information generated from protobuf_HunterNetCore.proto</summary> /// <summary>Holder for reflection information generated from protobuf_HunterNetCore.proto</summary>
public static partial class ProtobufHunterNetCoreReflection { public static partial class ProtobufHunterNetCoreReflection {
#region Descriptor #region Descriptor
/// <summary>File descriptor for protobuf_HunterNetCore.proto</summary> /// <summary>File descriptor for protobuf_HunterNetCore.proto</summary>

View File

@ -1,10 +1,5 @@
using System; using System.Net;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text;
namespace HaoYueNet.ServerNetwork namespace HaoYueNet.ServerNetwork
{ {
@ -38,13 +33,15 @@ namespace HaoYueNet.ServerNetwork
/// <summary> /// <summary>
/// 数据缓存区 /// 数据缓存区
/// </summary> /// </summary>
public List<byte> Buffer { get; set; } //public List<byte> Buffer { get; set; }
public MemoryStream memoryStream { get; set; }
public AsyncUserToken() public AsyncUserToken()
{ {
this.Buffer = new List<byte>(); //this.Buffer = new List<byte>();
this.memoryStream = new MemoryStream();
} }
/// <summary> /// <summary>
/// 响应倒计时计数 /// 响应倒计时计数
/// </summary> /// </summary>

View File

@ -1,8 +1,4 @@
using System; using System.Net.Sockets;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
namespace HaoYueNet.ServerNetwork namespace HaoYueNet.ServerNetwork
{ {

View File

@ -1,15 +1,7 @@
using Google.Protobuf; using Google.Protobuf;
using HunterProtobufCore; using HunterProtobufCore;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text;
using System.Threading;
using static Google.Protobuf.Reflection.FieldOptions.Types;
namespace HaoYueNet.ServerNetwork namespace HaoYueNet.ServerNetwork
@ -185,7 +177,7 @@ namespace HaoYueNet.ServerNetwork
// post accepts on the listening socket // post accepts on the listening socket
StartAccept(null); StartAccept(null);
OutNetLog("监听:" + listenSocket.AddressFamily.ToString()); OutNetLog("监听:" + listenSocket.LocalEndPoint.ToString());
_heartTimer = new System.Timers.Timer(); _heartTimer = new System.Timers.Timer();
_heartTimer.Interval = TimerInterval; _heartTimer.Interval = TimerInterval;
@ -338,7 +330,12 @@ namespace HaoYueNet.ServerNetwork
// Get the socket for the accepted client connection and put it into the // Get the socket for the accepted client connection and put it into the
//ReadEventArg object user token //ReadEventArg object user token
SocketAsyncEventArgs readEventArgs = m_Receivepool.Pop(); SocketAsyncEventArgs readEventArgs = m_Receivepool.Pop();
AsyncUserToken userToken = (AsyncUserToken)readEventArgs.UserToken; //TODO readEventArgs.UserToken这里的 UserToken 有可能是空
AsyncUserToken userToken;
if (readEventArgs.UserToken == null)
readEventArgs.UserToken = new AsyncUserToken();
userToken = (AsyncUserToken)readEventArgs.UserToken;
userToken.Socket = e.AcceptSocket; userToken.Socket = e.AcceptSocket;
userToken.ConnectTime = DateTime.Now; userToken.ConnectTime = DateTime.Now;
userToken.Remote = e.AcceptSocket.RemoteEndPoint; userToken.Remote = e.AcceptSocket.RemoteEndPoint;
@ -381,39 +378,68 @@ namespace HaoYueNet.ServerNetwork
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{ {
//读取数据 //读取数据
byte[] data = new byte[e.BytesTransferred]; //byte[] data = new byte[e.BytesTransferred];
Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred); //Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred);
lock (token.Buffer) //lock (token.Buffer)
lock(token.memoryStream)
{ {
token.Buffer.AddRange(data); //token.Buffer.AddRange(data);
token.memoryStream.Write(e.Buffer, e.Offset, e.BytesTransferred);
} }
do do
{ {
//如果包头不完整 //如果包头不完整
if (token.Buffer.Count < 4) //if (token.Buffer.Count < 4)
if (token.memoryStream.Length < 4)
break; break;
//判断包的长度 //判断包的长度
byte[] lenBytes = token.Buffer.GetRange(0, 4).ToArray(); //byte[] lenBytes = token.Buffer.GetRange(0, 4).ToArray();
//int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4;
//if (packageLen > token.Buffer.Count - 4)
//{ //长度不够时,退出循环,让程序继续接收
// break;
//}
long FristBeginPos = token.memoryStream.Position;
byte[] lenBytes = new byte[4];
token.memoryStream.Seek(0, SeekOrigin.Begin);
token.memoryStream.Read(lenBytes,0,4);
int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4; int packageLen = BitConverter.ToInt32(lenBytes, 0) - 4;
if (packageLen > token.Buffer.Count - 4) if (packageLen > token.memoryStream.Length - 4)
{ //长度不够时,退出循环,让程序继续接收 { //长度不够时,退出循环,让程序继续接收
break; break;
} }
//包够长时,则提取出来,交给后面的程序去处理 //包够长时,则提取出来,交给后面的程序去处理
byte[] rev = token.Buffer.GetRange(4, packageLen).ToArray(); //byte[] rev = token.Buffer.GetRange(4, packageLen).ToArray();
byte[] rev = new byte[packageLen];
token.memoryStream.Seek(4, SeekOrigin.Begin);
token.memoryStream.Read(rev, 0, packageLen);
////从数据池中移除这组数据
//lock (token.Buffer)
//{
// token.Buffer.RemoveRange(0, packageLen + 4);
//}
token.memoryStream.Seek(FristBeginPos, SeekOrigin.Begin);
//从数据池中移除这组数据 //从数据池中移除这组数据
lock (token.Buffer) lock (token.memoryStream)
{ {
token.Buffer.RemoveRange(0, packageLen + 4); int numberOfBytesToRemove = packageLen + 4;
byte[] buf = token.memoryStream.GetBuffer();
Buffer.BlockCopy(buf, numberOfBytesToRemove, buf, 0, (int)token.memoryStream.Length - numberOfBytesToRemove);
token.memoryStream.SetLength(token.memoryStream.Length - numberOfBytesToRemove);
} }
DataCallBackReady(token, rev); DataCallBackReady(token, rev);
//这里API处理完后,并没有返回结果,当然结果是要返回的,却不是在这里, 这里的代码只管接收. //这里API处理完后,并没有返回结果,当然结果是要返回的,却不是在这里, 这里的代码只管接收.
//若要返回结果,可在API处理中调用此类对象的SendMessage方法,统一打包发送.不要被微软的示例给迷惑了. //若要返回结果,可在API处理中调用此类对象的SendMessage方法,统一打包发送.不要被微软的示例给迷惑了.
} while (token.Buffer.Count > 4); //} while (token.Buffer.Count > 4);
} while (token.memoryStream.Length > 4);
//继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明 //继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
if (!token.Socket.ReceiveAsync(e)) if (!token.Socket.ReceiveAsync(e))

View File

@ -33,6 +33,20 @@ while (true)
} }
App.chat.SendChatMsg(CmdArr[1]); App.chat.SendChatMsg(CmdArr[1]);
break; break;
case "at":
//test
string guid = Guid.NewGuid().ToString();
App.login.Login(guid);
while (true)
{
if (!App.networkHelper.GetClientSocket().Connected)
return;
Thread.Sleep(10);
App.chat.SendChatMsg(guid);
}
//test end
break;
case "socket": case "socket":
{ {
Socket socket = App.networkHelper.GetClientSocket(); Socket socket = App.networkHelper.GetClientSocket();

View File

@ -1,9 +1,4 @@
using System; using ClientCore.Manager;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ClientCore.Manager;
using ClientCore.Network; using ClientCore.Network;
namespace ClientCore namespace ClientCore
@ -18,6 +13,7 @@ namespace ClientCore
public static NetworkHelper networkHelper; public static NetworkHelper networkHelper;
public static AppLogin login; public static AppLogin login;
public static AppChat chat; public static AppChat chat;
public static UserDataManager user;
public static void Init(string IP, int port) public static void Init(string IP, int port)
{ {
@ -25,6 +21,7 @@ namespace ClientCore
networkHelper = new NetworkHelper(); networkHelper = new NetworkHelper();
login = new AppLogin(); login = new AppLogin();
chat = new AppChat(); chat = new AppChat();
user = new UserDataManager();
networkHelper.Init(IP, port); networkHelper.Init(IP, port);
} }
} }

View File

@ -1,10 +1,4 @@
using System; namespace ClientCore.Common
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClientCore.Common
{ {
public static class Helper public static class Helper
{ {

View File

@ -1,10 +1,4 @@
using System; namespace ClientCore.Event
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClientCore.Event
{ {
public enum EEvent public enum EEvent
{ {

View File

@ -1,11 +1,4 @@
using System; namespace ClientCore.Event
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClientCore.Event
{ {
public class EventData public class EventData
{ {

View File

@ -1,10 +1,15 @@
using AxibugProtobuf; using AxibugProtobuf;
using ClientCore.Common;
using ClientCore.Network; using ClientCore.Network;
namespace ClientCore.Manager namespace ClientCore.Manager
{ {
public class AppLogin public class AppLogin
{ {
public AppLogin()
{
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdLogin, RecvLoginMsg);
}
public void Login(string Account) public void Login(string Account)
{ {
Protobuf_Login msg = new Protobuf_Login() Protobuf_Login msg = new Protobuf_Login()
@ -14,5 +19,20 @@ namespace ClientCore.Manager
}; };
App.networkHelper.SendToServer((int)CommandID.CmdLogin, NetworkHelper.Serizlize(msg)); App.networkHelper.SendToServer((int)CommandID.CmdLogin, NetworkHelper.Serizlize(msg));
} }
public void RecvLoginMsg(byte[] reqData)
{
Protobuf_Login_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Login_RESP>(reqData);
if (msg.Status == LoginResultStatus.Ok)
{
App.log.Debug("登录成功");
App.user.InitMainUserData(msg);
}
else
{
App.log.Debug("登录失败");
}
}
} }
} }

View File

@ -0,0 +1,57 @@
using AxibugProtobuf;
namespace ClientCore.Manager
{
public class UserDataBase
{
public long UID { get; set; }
public string Account { get; set; }
}
public class MainUserDataBase : UserDataBase
{
public bool IsLoggedIn { get; set; } = false;
}
public class UserDataManager
{
public UserDataManager()
{
//注册重连成功事件,以便后续自动登录
App.networkHelper.OnReConnected += OnReConnected;
}
MainUserDataBase user = new MainUserDataBase();
public bool IsLoggedIn => user.IsLoggedIn;
public void InitMainUserData(string UName)
{
user.Account = UName;
user.IsLoggedIn = true;
//以及其他数据初始化
//...
}
/// <summary>
/// 登出
/// </summary>
public void LoginOutData()
{
user.IsLoggedIn = false;
//以及其他数据清理
//...
}
/// <summary>
/// 当重连成功
/// </summary>
public void OnReConnected()
{
//如果之前已登录,则重新登录
if (user.IsLoggedIn)
{
App.login.Login(user.Account);
}
}
}
}

View File

@ -13,6 +13,10 @@ namespace ClientCore.Network
/// </summary> /// </summary>
public class NetworkHelper : NetworkHelperCore public class NetworkHelper : NetworkHelperCore
{ {
/// <summary>
/// 网络库调试日志输出
/// </summary>
public event OnLogOutHandler OnLogOut;
public NetworkHelper() public NetworkHelper()
{ {
//指定接收服务器数据事件 //指定接收服务器数据事件
@ -24,14 +28,34 @@ namespace ClientCore.Network
OnLogOut += NetworkDeBugLog; OnLogOut += NetworkDeBugLog;
} }
public delegate void OnReConnectedHandler();
/// <summary>
/// 重连成功事件
/// </summary>
public event OnReConnectedHandler OnReConnected;
/// <summary>
/// 是否自动重连
/// </summary>
public bool bAutoReConnect = true;
/// <summary>
/// 重连尝试时间
/// </summary>
const int ReConnectTryTime = 1000;
public void NetworkConnected(bool IsConnect) public void NetworkConnected(bool IsConnect)
{ {
NetworkDeBugLog($"NetworkConnected:{IsConnect}");
if (IsConnect) if (IsConnect)
NetworkDeBugLog("服务器连接成功"); {
}
else else
{ {
NetworkDeBugLog("服务器连接失败"); //连接失败
//to do 重连逻辑 NetworkDeBugLog("连接失败!");
//自动重连开关
if (bAutoReConnect)
ReConnect();
} }
} }
@ -39,7 +63,6 @@ namespace ClientCore.Network
{ {
//用于Unity内的输出 //用于Unity内的输出
//Debug.Log("NetCoreDebug >> "+str); //Debug.Log("NetCoreDebug >> "+str);
Console.WriteLine("NetCoreDebug >> " + str); Console.WriteLine("NetCoreDebug >> " + str);
} }
@ -70,6 +93,39 @@ namespace ClientCore.Network
public void OnConnectClose() public void OnConnectClose()
{ {
NetworkDeBugLog("OnConnectClose"); NetworkDeBugLog("OnConnectClose");
//自动重连开关
if (bAutoReConnect)
ReConnect();
}
bool bInReConnecting = false;
/// <summary>
/// 自动重连
/// </summary>
void ReConnect()
{
if (bInReConnecting)
return;
bInReConnecting = true;
bool bflagDone = false;
do
{
//等待时间
Thread.Sleep(ReConnectTryTime);
App.log.Debug($"尝试自动重连{LastConnectIP}:{LastConnectPort}……");
//第一步
if (Init(LastConnectIP, LastConnectPort))
{
App.log.Debug($"自动重连成功!");
bflagDone = true;
App.log.Debug($"触发重连后的自动逻辑!");
OnReConnected?.Invoke();
}
} while (!bflagDone);
bInReConnecting = false;
} }
} }
} }

View File

@ -1,5 +1,4 @@
using ServerCore; using ServerCore.Manager;
using ServerCore.Manager;
ServerManager.InitServer(23846); ServerManager.InitServer(23846);

View File

@ -1,10 +1,4 @@
using System; namespace ServerCore.Common
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServerCore.Common
{ {
public static class Helper public static class Helper
{ {

View File

@ -1,10 +1,4 @@
using System; namespace ServerCore.Event
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServerCore.Event
{ {
public enum EEvent public enum EEvent
{ {

View File

@ -1,10 +1,4 @@
using ServerCore.Manager; using ServerCore.Manager;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServerCore.Event namespace ServerCore.Event
{ {

View File

@ -15,7 +15,7 @@ namespace ServerCore.Manager
public void RecvPlayerChatMsg(Socket sk, byte[] reqData) public void RecvPlayerChatMsg(Socket sk, byte[] reqData)
{ {
ClientInfo _c = ServerManager.g_ClientMgr.GetClientForSocket(sk); ClientInfo _c = ServerManager.g_ClientMgr.GetClientForSocket(sk);
ServerManager.g_Log.Debug("收到新的登录请求"); ServerManager.g_Log.Debug("收到聊天消息请求");
Protobuf_ChatMsg msg = ProtoBufHelper.DeSerizlize<Protobuf_ChatMsg>(reqData); Protobuf_ChatMsg msg = ProtoBufHelper.DeSerizlize<Protobuf_ChatMsg>(reqData);
byte[] respData = ProtoBufHelper.Serizlize(new Protobuf_ChatMsg_RESP() byte[] respData = ProtoBufHelper.Serizlize(new Protobuf_ChatMsg_RESP()
{ {

View File

@ -1,5 +1,5 @@
using System.Net; using ServerCore.NetWork;
using ServerCore.NetWork; using System.Net;
namespace ServerCore.Manager namespace ServerCore.Manager
{ {

View File

@ -1,7 +1,5 @@
using AxibugProtobuf; using HaoYueNet.ServerNetwork;
using HaoYueNet.ServerNetwork;
using ServerCore.Manager; using ServerCore.Manager;
using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
namespace ServerCore.NetWork namespace ServerCore.NetWork

View File

@ -1,11 +1,5 @@
using ServerCore.Manager; using ServerCore.Manager;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ServerCore.NetWork namespace ServerCore.NetWork
{ {