封装服务器Socket

This commit is contained in:
Mili 2022-11-21 23:43:51 +08:00
parent 68ed8b5d76
commit 00504d65da
22 changed files with 539 additions and 106 deletions

View File

@ -16,11 +16,11 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <typeparam name="T">Entity类</typeparam> /// <typeparam name="T">Entity类</typeparam>
/// <param name="objs">构造函数的参数</param> /// <param name="objs">构造函数的参数</param>
/// <returns></returns> /// <returns></returns>
public static object? GetInstance<T>(params object[]? objs) public static T? GetInstance<T>(params object[]? objs)
{ {
if (!IsEntity<T>()) return null; if (!IsEntity<T>()) return default;
object? instance = null; object? instance = null;
if (objs is null || objs.Length == 0) return instance; if (objs is null || objs.Length == 0) return (T?)instance;
if (typeof(T) == typeof(Entity.User)) if (typeof(T) == typeof(Entity.User))
{ {
instance = Api.Factory.UserFactory.GetInstance("Mili"); instance = Api.Factory.UserFactory.GetInstance("Mili");
@ -29,7 +29,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
{ {
} }
return instance; return (T?)instance;
} }
/// <summary> /// <summary>
@ -41,11 +41,11 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <typeparam name="T">Entity类</typeparam> /// <typeparam name="T">Entity类</typeparam>
/// <param name="objs">构造函数的参数</param> /// <param name="objs">构造函数的参数</param>
/// <returns></returns> /// <returns></returns>
public static object New<T>(params object[]? objs) public static T New<T>(params object[]? objs)
{ {
object instance = General.EntityInstance; object instance = General.EntityInstance;
if (!IsEntity<T>()) return instance; if (!IsEntity<T>()) return (T)instance;
if (objs is null || objs.Length == 0) return instance; if (objs is null || objs.Length == 0) return (T)instance;
if (typeof(T) == typeof(Entity.User)) if (typeof(T) == typeof(Entity.User))
{ {
instance = Api.Factory.UserFactory.GetInstance("Mili"); instance = Api.Factory.UserFactory.GetInstance("Mili");
@ -54,7 +54,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
{ {
} }
return instance; return (T)instance;
} }
/// <summary> /// <summary>

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Milimoe.FunGame.Core.Library.Common.Network;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Interface.Base
{
public interface ISocket
{
public System.Net.Sockets.Socket Instance { get; }
public int Runtime { get; }
public string ServerIP { get; }
public int ServerPort { get; }
public string ServerName { get; }
public string ServerNotice { get; }
public int HeartBeatFaileds { get; }
public bool Connected
{
get
{
return Instance != null && Instance.Connected;
}
}
public bool Receiving { get; }
public bool SendingHeartBeat { get; }
public SocketResult Send(SocketMessageType type, params object[] objs);
public object[] Receive();
public void Close();
public void StartReceiving(Task t);
}
}

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Service;
namespace Milimoe.FunGame.Core.Library.Common.Network
{
public class ClientSocket : ISocket
{
public System.Net.Sockets.Socket Instance { get; }
public int Runtime { get; } = (int)SocketRuntimeType.Server;
public string ServerIP { get; } = "";
public int ServerPort { get; } = 0;
public string ServerName { get; } = "";
public string ServerNotice { get; } = "";
public string ClientIP { get; } = "";
public string ClientName { get; private set; } = "";
public int HeartBeatFaileds { get; private set; } = 0;
public bool Connected
{
get
{
return Instance != null && Instance.Connected;
}
}
public bool Receiving { get; private set; } = false;
public bool SendingHeartBeat { get; private set; } = false;
private Task? ReceivingTask;
public ClientSocket(System.Net.Sockets.Socket Instance, int ServerPort, string ClientIP, string ClientName)
{
this.Instance= Instance;
this.ServerPort = ServerPort;
this.ClientIP = ClientIP;
this.ClientName = ClientName;
}
public void Close()
{
StopReceiving();
Instance?.Close();
}
public object[] Receive()
{
object[] result = SocketManager.Receive(Instance);
if (result.Length != 2) throw new System.Exception("收到错误的返回信息。");
return result;
}
public SocketResult Send(SocketMessageType type, params object[] objs)
{
if (Instance != null)
{
if (SocketManager.Send(Instance, type, objs) == SocketResult.Success)
{
return SocketResult.Success;
}
else return SocketResult.Fail;
}
return SocketResult.NotSent;
}
public void StartReceiving(Task t)
{
Receiving = true;
ReceivingTask = t;
}
public void StopReceiving()
{
Receiving = false;
ReceivingTask?.Wait(1);
ReceivingTask = null;
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Library.Common.Network
{
[Serializable]
internal class JsonObject
{
internal SocketMessageType MessageType { get; } = SocketMessageType.Unknown;
internal object[] Parameters { get; }
internal string JsonString { get; }
internal JsonObject(SocketMessageType MessageType, object[] Parameters)
{
this.MessageType = MessageType;
this.Parameters = Parameters;
this.JsonString = JsonSerializer.Serialize(this);
}
internal static string GetString(SocketMessageType MessageType, object[] Parameters)
{
return new JsonObject(MessageType, Parameters).JsonString;
}
internal static JsonObject? GetObject(string JsonString)
{
return JsonSerializer.Deserialize<JsonObject>(JsonString);
}
}
}

View File

@ -0,0 +1,77 @@
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Service;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Milimoe.FunGame.Core.Library.Common.Network
{
public class ServerSocket : ISocket
{
public System.Net.Sockets.Socket Instance { get; }
public int Runtime { get; } = (int)SocketRuntimeType.Server;
public string ServerIP { get; } = "";
public int ServerPort { get; } = 0;
public string ServerName { get; } = "";
public string ServerNotice { get; } = "";
public int HeartBeatFaileds { get; private set; } = 0;
public bool Connected
{
get
{
return Instance != null && Instance.Connected;
}
}
public bool Receiving { get; private set; } = false;
public bool SendingHeartBeat { get; private set; } = false;
private ServerSocket(System.Net.Sockets.Socket Instance, int ServerPort)
{
this.Instance = Instance;
this.ServerPort = ServerPort;
}
public ServerSocket StartListening(int Port = 22222, int MaxConnection = 20)
{
System.Net.Sockets.Socket? socket = SocketManager.StartListening(Port, MaxConnection);
if (socket != null) return new ServerSocket(socket, Port);
else throw new System.Exception("无法创建监听,请重新启动服务器再试。");
}
public ClientSocket Accept()
{
object[] result = SocketManager.Accept();
if (result != null && result.Length == 2)
{
string ClientIP = (string)result[0];
System.Net.Sockets.Socket Client = (System.Net.Sockets.Socket)result[1];
return new ClientSocket(Client, ServerPort, ClientIP, ClientIP);
}
throw new System.Exception("无法获取客户端信息。");
}
public SocketResult Send(SocketMessageType type, params object[] objs)
{
throw new System.Exception("监听Socket不能用于发送信息。");
}
public object[] Receive()
{
throw new System.Exception("监听Socket不能用于接收信息。");
}
public void Close()
{
Instance?.Close();
}
public void StartReceiving(Task t)
{
throw new System.Exception("监听Socket不能用于接收信息。");
}
}
}

View File

@ -12,7 +12,7 @@ using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Library.Common.Network namespace Milimoe.FunGame.Core.Library.Common.Network
{ {
public class Socket public class Socket : ISocket
{ {
public System.Net.Sockets.Socket Instance { get; } public System.Net.Sockets.Socket Instance { get; }
public int Runtime { get; } = (int)SocketRuntimeType.Client; public int Runtime { get; } = (int)SocketRuntimeType.Client;
@ -50,11 +50,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
else throw new System.Exception("连接到服务器失败。"); else throw new System.Exception("连接到服务器失败。");
} }
public SocketResult Send(SocketMessageType type, string msg = "") public SocketResult Send(SocketMessageType type, params object[] objs)
{ {
if (Instance != null) if (Instance != null)
{ {
if (SocketManager.Send(type, msg) == SocketResult.Success) if (SocketManager.Send(type, objs) == SocketResult.Success)
{ {
return SocketResult.Success; return SocketResult.Success;
} }
@ -63,10 +63,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
return SocketResult.NotSent; return SocketResult.NotSent;
} }
public string[] Receive() public object[] Receive()
{ {
string[] result = SocketManager.Receive(); object[] result = SocketManager.Receive();
if (result[0] == SocketSet.HeartBeat) if (result.Length != 2) throw new System.Exception("收到错误的返回信息。");
if ((string)result[0] == SocketSet.HeartBeat)
{ {
if (WaitHeartBeatReply != null && !WaitHeartBeatReply.IsCompleted) WaitHeartBeatReply.Wait(1); if (WaitHeartBeatReply != null && !WaitHeartBeatReply.IsCompleted) WaitHeartBeatReply.Wait(1);
HeartBeatFaileds = 0; HeartBeatFaileds = 0;

View File

@ -7,33 +7,94 @@ using Milimoe.FunGame.Core.Interface.Base;
using System.Collections; using System.Collections;
using System.Net.Sockets; using System.Net.Sockets;
using System.Net; using System.Net;
using System.Text.Json;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Service namespace Milimoe.FunGame.Core.Service
{ {
internal class SocketManager internal class SocketManager
{ {
/// <summary>
/// 客户端专用Socket
/// </summary>
internal static Socket? Socket { get; private set; } = null; internal static Socket? Socket { get; private set; } = null;
/// <summary>
/// 服务器端专用Socket
/// </summary>
internal static Socket? ServerSocket { get; private set; } = null;
/// <summary>
/// 创建服务器监听Socket
/// </summary>
/// <param name="Port">监听端口号</param>
/// <param name="MaxConnection">最大连接数量</param>
/// <returns>服务器端专用Socket</returns>
internal static Socket? StartListening(int Port = 22222, int MaxConnection = 20)
{
try
{
ServerSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ServerEndPoint = new(IPAddress.Any, Port);
ServerSocket.Bind(ServerEndPoint);
ServerSocket.Listen(MaxConnection);
return ServerSocket;
}
catch
{
ServerSocket?.Close();
}
return null;
}
/// <summary>
/// 创建一个监听到客户端Socket
/// </summary>
/// <returns>客户端IP地址[0]和客户端Socket[1]</returns>
internal static object[] Accept()
{
if (ServerSocket is null) return Array.Empty<object>();
Socket Client;
string ClientIP;
try
{
Client = ServerSocket.Accept();
IPEndPoint? ClientIPEndPoint = (IPEndPoint?)Client.RemoteEndPoint;
ClientIP = (ClientIPEndPoint != null) ? ClientIPEndPoint.ToString() : "Unknown";
return new object[] { ClientIP, Client };
}
catch
{
ServerSocket?.Close();
}
return Array.Empty<object>();
}
/// <summary>
/// 创建客户端Socket
/// </summary>
/// <param name="IP">服务器IP地址</param>
/// <param name="Port">服务器监听端口</param>
/// <returns>客户端专用Socket</returns>
internal static Socket? Connect(string IP, int Port = 22222) internal static Socket? Connect(string IP, int Port = 22222)
{ {
Socket? socket = null; Socket? ClientSocket;
EndPoint ServerEndPoint; EndPoint ServerEndPoint;
try try
{ {
socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ClientSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ServerEndPoint = new IPEndPoint(IPAddress.Parse(IP), Port); ServerEndPoint = new IPEndPoint(IPAddress.Parse(IP), Port);
if (ServerEndPoint != null) if (ServerEndPoint != null)
{ {
while (true) while (true)
{ {
if (!socket.Connected) if (!ClientSocket.Connected)
{ {
socket.Connect(ServerEndPoint); ClientSocket.Connect(ServerEndPoint);
if (socket.Connected) if (ClientSocket.Connected)
{ {
Socket = socket; Socket = ClientSocket;
return socket; return Socket;
} }
} }
} }
@ -41,16 +102,23 @@ namespace Milimoe.FunGame.Core.Service
} }
catch catch
{ {
socket?.Close(); Socket?.Close();
} }
return null; return null;
} }
internal static SocketResult Send(SocketMessageType type, string msg) /// <summary>
/// 用于服务器端向客户端Socket发送信息
/// </summary>
/// <param name="ClientSocket">客户端Socket</param>
/// <param name="type">通信类型</param>
/// <param name="objs">参数</param>
/// <returns>通信结果</returns>
internal static SocketResult Send(Socket ClientSocket, SocketMessageType type, object[] objs)
{ {
if (Socket != null) if (ClientSocket != null && objs != null && objs.Length > 0)
{ {
if (Socket.Send(General.DEFAULT_ENCODING.GetBytes(MakeMessage(type, msg))) > 0) if (ClientSocket.Send(General.DEFAULT_ENCODING.GetBytes(Library.Common.Network.JsonObject.GetString(type, objs))) > 0)
{ {
return SocketResult.Success; return SocketResult.Success;
} }
@ -59,9 +127,36 @@ namespace Milimoe.FunGame.Core.Service
return SocketResult.NotSent; return SocketResult.NotSent;
} }
internal static string[] Receive() /// <summary>
/// 用于客户端向服务器Socket发送信息
/// </summary>
/// <param name="type">通信类型</param>
/// <param name="objs">参数</param>
/// <returns>通信结果</returns>
internal static SocketResult Send(SocketMessageType type, object[] objs)
{ {
string[] result = new string[2] { GetTypeString(SocketMessageType.Unknown), "" }; if (objs is null || objs.Length <= 0)
{
objs = new object[] { "" };
}
if (Socket != null)
{
if (Socket.Send(General.DEFAULT_ENCODING.GetBytes(Library.Common.Network.JsonObject.GetString(type, objs))) > 0)
{
return SocketResult.Success;
}
else return SocketResult.Fail;
}
return SocketResult.NotSent;
}
/// <summary>
/// 用于客户端接收服务器信息
/// </summary>
/// <returns>通信类型[0]和参数[1]</returns>
internal static object[] Receive()
{
object[] result = Array.Empty<object>();
if (Socket != null) if (Socket != null)
{ {
// 从服务器接收消息 // 从服务器接收消息
@ -70,34 +165,51 @@ namespace Milimoe.FunGame.Core.Service
if (length > 0) if (length > 0)
{ {
string msg = General.DEFAULT_ENCODING.GetString(buffer, 0, length); string msg = General.DEFAULT_ENCODING.GetString(buffer, 0, length);
result[0] = GetTypeString(GetType(msg)); Library.Common.Network.JsonObject? json = Library.Common.Network.JsonObject.GetObject(msg);
result[1] = GetMessage(msg); if (json != null)
{
result[0] = GetTypeString(json.MessageType);
result[1] = json.Parameters;
}
return result; return result;
} }
} }
return result; return result;
} }
private static int GetType(string msg) /// <summary>
/// 用于服务器接收客户端信息
/// </summary>
/// <param name="ClientSocket">客户端Socket</param>
/// <returns>通信类型[0]和参数[1]</returns>
internal static object[] Receive(Socket ClientSocket)
{ {
int index = msg.IndexOf(';') - 1; object[] result = Array.Empty<object>();
if (index > 0) if (ClientSocket != null)
return Convert.ToInt32(msg[..index]); {
else // 从客户端接收消息
return Convert.ToInt32(msg[..1]); byte[] buffer = new byte[2048];
} int length = ClientSocket.Receive(buffer);
if (length > 0)
private static string GetMessage(string msg) {
{ string msg = General.DEFAULT_ENCODING.GetString(buffer, 0, length);
int index = msg.IndexOf(';') + 1; Library.Common.Network.JsonObject? json = Library.Common.Network.JsonObject.GetObject(msg);
return msg[index..]; if (json != null)
} {
result[0] = GetTypeString(json.MessageType);
private static string MakeMessage(SocketMessageType type, string msg) result[1] = json.Parameters;
{ }
return (int)type + ";" + msg; return result;
}
}
return result;
} }
/// <summary>
/// 将通信类型的枚举转换为字符串
/// </summary>
/// <param name="type">通信类型</param>
/// <returns>等效字符串</returns>
private static string GetTypeString(SocketMessageType type) private static string GetTypeString(SocketMessageType type)
{ {
return type switch return type switch
@ -112,10 +224,5 @@ namespace Milimoe.FunGame.Core.Service
_ => SocketSet.Unknown, _ => SocketSet.Unknown,
}; };
} }
private static string GetTypeString(int type)
{
return GetTypeString((SocketMessageType)type);
}
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -8,6 +9,32 @@ namespace Milimoe.FunGame.Core.Service
{ {
internal class ThreadManager internal class ThreadManager
{ {
internal static int MAX_THREAD { get; } = 20;
private ConcurrentDictionary<string, Task> Threads { get; } = new();
internal Task this[string name]
{
get
{
return Threads[name];
}
}
internal bool Add(string name, Task t)
{
return Threads.TryAdd(name, t);
}
internal bool Remove(string name)
{
return Threads.TryRemove(name, out _);
}
internal void Clear()
{
Threads.Clear();
}
} }
} }

View File

@ -6,7 +6,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>Image\logo.ico</ApplicationIcon> <ApplicationIcon>Images\logo.ico</ApplicationIcon>
<Copyright></Copyright> <Copyright></Copyright>
<PackageIcon>logo.ico</PackageIcon> <PackageIcon>logo.ico</PackageIcon>
<Company>Milimoe</Company> <Company>Milimoe</Company>
@ -31,7 +31,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Content Include="Image\logo.ico" /> <Content Include="Images\logo.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -68,7 +68,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="Image\logo.ico"> <None Update="Images\logo.ico">
<Pack>True</Pack> <Pack>True</Pack>
<PackagePath>\</PackagePath> <PackagePath>\</PackagePath>
</None> </None>

View File

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,4 +1,5 @@
using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Event; using Milimoe.FunGame.Core.Library.Common.Event;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Library.Exception; using Milimoe.FunGame.Core.Library.Exception;
@ -30,18 +31,41 @@ namespace Milimoe.FunGame.Desktop.Model
public bool Login() public bool Login()
{ {
try
{
if (Socket != null && Socket.Send(SocketMessageType.Login, "Mili", "OK") == SocketResult.Success)
return true;
}
catch (Exception e)
{
Main?.GetMessage(e.GetStackTrace());
}
return false; return false;
} }
public bool Logout() public bool Logout()
{ {
try
{
//Socket?.Send(SocketMessageType.Logout, "");
}
catch (Exception e)
{
Main?.GetMessage(e.GetStackTrace());
}
return false; return false;
} }
public void Disconnect() public void Disconnect()
{ {
try
{
Socket?.Send(SocketMessageType.Disconnect, "");
}
catch (Exception e)
{
Main?.GetMessage(e.GetStackTrace());
}
} }
public bool GetServerConnection() public bool GetServerConnection()
@ -85,6 +109,11 @@ namespace Milimoe.FunGame.Desktop.Model
} }
while (true) while (true)
{ {
if (Others.Config.FunGame_isRetrying)
{
Main?.GetMessage("正在连接服务器,请耐心等待。");
return ConnectResult.CanNotConnect;
}
if (!Others.Config.FunGame_isConnected) if (!Others.Config.FunGame_isConnected)
{ {
CurrentRetryTimes++; CurrentRetryTimes++;
@ -104,17 +133,29 @@ namespace Milimoe.FunGame.Desktop.Model
// 发送连接请求 // 发送连接请求
if (Socket.Send(SocketMessageType.Connect) == SocketResult.Success) if (Socket.Send(SocketMessageType.Connect) == SocketResult.Success)
{ {
// 接收连接回应 Task t = Task.Factory.StartNew(() =>
if (Receiving() == SocketMessageType.Connect)
{ {
Main?.UpdateUI(MainControllerSet.Connected); if (Receiving() == SocketMessageType.Connect)
return ConnectResult.Success; {
} Main?.GetMessage("连接服务器成功请登录账号以体验FunGame。");
Main?.UpdateUI(MainControllerSet.Connected);
StartReceiving();
return ConnectResult.Success;
}
return ConnectResult.ConnectFailed;
});
t.Wait(5000);
Main?.GetMessage("ERROR: 连接超时,远程服务器没有回应。", false);
} }
Socket?.Close(); Socket?.Close();
return ConnectResult.CanNotConnect; return ConnectResult.ConnectFailed;
} }
} }
else
{
Main?.GetMessage("已连接至服务器,请勿重复连接。");
return ConnectResult.CanNotConnect;
}
} }
} }
catch (Exception e) catch (Exception e)
@ -125,19 +166,6 @@ namespace Milimoe.FunGame.Desktop.Model
return ConnectResult.ConnectFailed; return ConnectResult.ConnectFailed;
} }
public void StartReceiving()
{
ReceivingTask = Task.Factory.StartNew(() =>
{
Thread.Sleep(100);
while (Socket != null && Socket.Connected)
{
Receiving();
}
});
Socket?.StartReceiving(ReceivingTask);
}
public bool Close() public bool Close()
{ {
try try
@ -161,13 +189,26 @@ namespace Milimoe.FunGame.Desktop.Model
return true; return true;
} }
private string[] GetServerMessage() private void StartReceiving()
{
ReceivingTask = Task.Factory.StartNew(() =>
{
Thread.Sleep(100);
while (Socket != null && Socket.Connected)
{
Receiving();
}
});
Socket?.StartReceiving(ReceivingTask);
}
private object[] GetServerMessage()
{ {
if (Socket != null && Socket.Connected) if (Socket != null && Socket.Connected)
{ {
return Socket.Receive(); return Socket.Receive();
} }
return new string[2] { SocketSet.Unknown, "" }; return new object[2] { SocketSet.Unknown, Array.Empty<object>() };
} }
private SocketMessageType Receiving() private SocketMessageType Receiving()
@ -176,17 +217,21 @@ namespace Milimoe.FunGame.Desktop.Model
SocketMessageType result = SocketMessageType.Unknown; SocketMessageType result = SocketMessageType.Unknown;
try try
{ {
string[] ServerMessage = GetServerMessage(); object[] ServerMessage = GetServerMessage();
string type = ServerMessage[0]; string type = (string)ServerMessage[0];
string msg = ServerMessage[1]; object[] objs = (object[])ServerMessage[1];
string msg = "";
switch (type) switch (type)
{ {
case SocketSet.GetNotice: case SocketSet.GetNotice:
result = SocketMessageType.GetNotice; result = SocketMessageType.GetNotice;
if (objs.Length > 0) msg = (string)objs[0];
Config.FunGame_Notice = msg; Config.FunGame_Notice = msg;
break; break;
case SocketSet.Connect: case SocketSet.Connect:
result = SocketMessageType.Connect; result = SocketMessageType.Connect;
if (objs.Length > 0) msg = (string)objs[0];
string[] strings = msg.Split(';'); string[] strings = msg.Split(';');
string ServerName = strings[0]; string ServerName = strings[0];
string ServerNotice = strings[1]; string ServerNotice = strings[1];
@ -196,14 +241,35 @@ namespace Milimoe.FunGame.Desktop.Model
// 设置等待登录的黄灯 // 设置等待登录的黄灯
Main?.UpdateUI(MainControllerSet.WaitLoginAndSetYellow); Main?.UpdateUI(MainControllerSet.WaitLoginAndSetYellow);
break; break;
case SocketSet.Login: case SocketSet.Login:
result = SocketMessageType.Login;
break; break;
case SocketSet.CheckLogin: case SocketSet.CheckLogin:
result = SocketMessageType.CheckLogin;
if (objs.Length > 0) msg = (string)objs[0];
Main?.GetMessage(msg);
Main?.UpdateUI(MainControllerSet.SetUser, true, TimeType.TimeOnly, new object[] { Factory.New<User>(msg) });
break; break;
case SocketSet.Logout: case SocketSet.Logout:
break; break;
case SocketSet.Disconnect: case SocketSet.Disconnect:
result = SocketMessageType.Disconnect;
if (objs.Length > 0) msg = (string)objs[0];
Main?.GetMessage(msg);
Main?.UpdateUI(MainControllerSet.Disconnected);
Close();
break; break;
case SocketSet.HeartBeat:
result = SocketMessageType.HeartBeat;
if (Usercfg.LoginUser != null)
Main?.UpdateUI(MainControllerSet.SetGreenAndPing);
break;
case SocketSet.Unknown: case SocketSet.Unknown:
default: default:
break; break;
@ -211,7 +277,10 @@ namespace Milimoe.FunGame.Desktop.Model
} }
catch (Exception e) catch (Exception e)
{ {
// 报错中断服务器连接
Main?.GetMessage(e.GetStackTrace(), false); Main?.GetMessage(e.GetStackTrace(), false);
Main?.UpdateUI(MainControllerSet.Disconnected);
Close();
} }
return result; return result;
} }

View File

@ -40,7 +40,7 @@ namespace Milimoe.FunGame.Desktop.Others
*/ */
public static string SERVER_IPADRESS { get; set; } = ""; // 服务器IP地址 public static string SERVER_IPADRESS { get; set; } = ""; // 服务器IP地址
public static int SERVER_PORT { get; set; } = 0; // 服务器端口号 public static int SERVER_PORT { get; set; } = 0; // 服务器端口号
public static Encoding DEFAULT_ENCODING { get; set; } = Encoding.UTF8; public static Encoding DEFAULT_ENCODING { get; } = Core.Library.Constant.General.DEFAULT_ENCODING;
/** /**
* FunGame Configs * FunGame Configs

View File

@ -12,7 +12,7 @@ namespace Milimoe.FunGame.Desktop.Others
/** /**
* *
*/ */
public static User? LoginUser = null; // 已登录的用户 public static User? LoginUser { get; set; } = null; // 已登录的用户
public static string LoginUserName = ""; // 已登录用户名 public static string LoginUserName { get; set; } = ""; // 已登录用户名
} }
} }

View File

@ -119,30 +119,30 @@
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="back" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="back" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Image\back.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Images\back.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="exit" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="exit" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Image\exit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Images\exit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="green" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="green" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Image\green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Images\green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="LanaPixel" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="LanaPixel" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\LanaPixel.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>..\Resources\LanaPixel.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
<data name="logo" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="logo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Image\logo.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Images\logo.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="min" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="min" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Image\min.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Images\min.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="red" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="red" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Image\red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Images\red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="send" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="send" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Image\send.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Images\send.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="yellow" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="yellow" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Image\yellow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Images\yellow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
</root> </root>

View File

@ -60,6 +60,7 @@ namespace Milimoe.FunGame.Desktop.UI
GetFunGameConfig(); // 获取FunGame配置 GetFunGameConfig(); // 获取FunGame配置
// 创建一个UI控制器 // 创建一个UI控制器
MainController = new MainController(this); MainController = new MainController(this);
// 窗口句柄创建后,进行委托
Task.Factory.StartNew(() => Task.Factory.StartNew(() =>
{ {
while (true) while (true)
@ -69,11 +70,10 @@ namespace Milimoe.FunGame.Desktop.UI
break; break;
} }
} }
// 窗口句柄创建后,进行委托
void action() void action()
{ {
if (Config.FunGame_isAutoConnect) if (Config.FunGame_isAutoConnect)
MainController.Do<bool>(MainControllerSet.Connected); MainController.Do<object>(MainControllerSet.GetServerConnection);
} }
InvokeUpdateUI(action); InvokeUpdateUI(action);
}); });
@ -90,7 +90,7 @@ namespace Milimoe.FunGame.Desktop.UI
/// <param name="time"></param> /// <param name="time"></param>
/// <param name="timetype"></param> /// <param name="timetype"></param>
/// <param name="objs"></param> /// <param name="objs"></param>
public void UpdateUI(string? updatetype, bool time = false, TimeType timetype = TimeType.TimeOnly, object[]? objs = null) public void UpdateUI(string? updatetype, bool time = true, TimeType timetype = TimeType.TimeOnly, object[]? objs = null)
{ {
void action() void action()
{ {
@ -162,18 +162,19 @@ namespace Milimoe.FunGame.Desktop.UI
Task.Run(() => Task.Run(() =>
{ {
Thread.Sleep(5000); Thread.Sleep(5000);
if (Others.Config.FunGame_isAutoRetry) MainController?.Do<bool>(MainControllerSet.Connect); // 再次判断是否开启自动重连 if (Others.Config.FunGame_isAutoRetry) MainController?.Do<object>(MainControllerSet.Connect); // 再次判断是否开启自动重连
}); });
if (time) if (time)
throw new Exception(DateTimeUtility.GetNowShortTime() + "\nERROR连接服务器失败5秒后自动尝试重连。"); WritelnGameInfo(DateTimeUtility.GetDateTimeToString(timetype) + "\n连接服务器失败5秒后自动尝试重连。");
else else
throw new Exception("ERROR连接服务器失败5秒后自动尝试重连。"); WritelnGameInfo("连接服务器失败5秒后自动尝试重连。");
} }
else else
if (time) if (time)
throw new Exception(DateTimeUtility.GetNowShortTime() + "\nERROR无法连接至服务器,请检查你的网络连接。"); WritelnGameInfo(DateTimeUtility.GetDateTimeToString(timetype) + "\n无法连接至服务器,请检查你的网络连接。");
else else
throw new Exception("ERROR无法连接至服务器请检查你的网络连接。"); WritelnGameInfo("无法连接至服务器,请检查你的网络连接。");
break;
case Others.MainControllerSet.Disconnect: case Others.MainControllerSet.Disconnect:
Others.Config.FunGame_isAutoRetry = false; Others.Config.FunGame_isAutoRetry = false;
@ -199,7 +200,7 @@ namespace Milimoe.FunGame.Desktop.UI
Task.Run(() => Task.Run(() =>
{ {
Thread.Sleep(1000); Thread.Sleep(1000);
MainController?.Do<bool>(MainControllerSet.Connect); MainController?.Do<object>(MainControllerSet.Connect);
}); });
} }
break; break;
@ -292,10 +293,10 @@ namespace Milimoe.FunGame.Desktop.UI
string isAutoLogin = INIHelper.ReadINI("Config", "AutoLogin"); string isAutoLogin = INIHelper.ReadINI("Config", "AutoLogin");
if (isAutoConncet != null && !isAutoConncet.Equals("") && (isAutoConncet.Equals("false") || isAutoConncet.Equals("true"))) if (isAutoConncet != null && !isAutoConncet.Equals("") && (isAutoConncet.Equals("false") || isAutoConncet.Equals("true")))
Others.Config.FunGame_isAutoConnect = Convert.ToBoolean(isAutoConncet); Others.Config.FunGame_isAutoConnect = Convert.ToBoolean(isAutoConncet);
else throw new Exception("ERROR: 读取配置文件出错,参数格式不正确"); else throw new Exception("读取配置文件出错,参数格式不正确");
if (isAutoLogin != null && !isAutoLogin.Equals("") && (isAutoLogin.Equals("false") || isAutoLogin.Equals("true"))) if (isAutoLogin != null && !isAutoLogin.Equals("") && (isAutoLogin.Equals("false") || isAutoLogin.Equals("true")))
Others.Config.FunGame_isAutoLogin = Convert.ToBoolean(isAutoLogin); Others.Config.FunGame_isAutoLogin = Convert.ToBoolean(isAutoLogin);
else throw new Exception("ERROR: 读取配置文件出错,参数格式不正确"); else throw new Exception("读取配置文件出错,参数格式不正确");
} }
else else
{ {
@ -1251,7 +1252,7 @@ namespace Milimoe.FunGame.Desktop.UI
if (!Others.Config.FunGame_isRetrying) if (!Others.Config.FunGame_isRetrying)
{ {
NOW_CONNECTEDRETRY = -1; NOW_CONNECTEDRETRY = -1;
MainController?.Do<bool>(MainControllerSet.Connect); MainController?.Do<object>(MainControllerSet.Connect);
} }
else else
WritelnGameInfo(">> 你不能在连接服务器的同时重试连接!"); WritelnGameInfo(">> 你不能在连接服务器的同时重试连接!");
@ -1304,7 +1305,7 @@ namespace Milimoe.FunGame.Desktop.UI
Others.Constant.SERVER_IPADRESS = ip; Others.Constant.SERVER_IPADRESS = ip;
Others.Constant.SERVER_PORT = port; Others.Constant.SERVER_PORT = port;
NOW_CONNECTEDRETRY = -1; NOW_CONNECTEDRETRY = -1;
MainController?.Do<bool>(MainControllerSet.Connect); MainController?.Do<object>(MainControllerSet.Connect);
} }
else if (ErrorType == Core.Library.Constant.ErrorType.IsNotIP) ShowMessage.ErrorMessage("这不是一个IP地址"); else if (ErrorType == Core.Library.Constant.ErrorType.IsNotIP) ShowMessage.ErrorMessage("这不是一个IP地址");
else if (ErrorType == Core.Library.Constant.ErrorType.IsNotPort) ShowMessage.ErrorMessage("这不是一个端口号!\n正确范围1~65535"); else if (ErrorType == Core.Library.Constant.ErrorType.IsNotPort) ShowMessage.ErrorMessage("这不是一个端口号!\n正确范围1~65535");