11111
This commit is contained in:
@@ -8,7 +8,6 @@ using HybridCLR.Editor.Settings;
|
|||||||
#endif
|
#endif
|
||||||
using Sirenix.OdinInspector;
|
using Sirenix.OdinInspector;
|
||||||
using Sirenix.OdinInspector.Editor;
|
using Sirenix.OdinInspector.Editor;
|
||||||
using Stary.Evo.InformationSave;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditorInternal;
|
using UnityEditorInternal;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -110,12 +109,7 @@ namespace Stary.Evo.Editor
|
|||||||
gameObj.transform.position = Vector3.zero;
|
gameObj.transform.position = Vector3.zero;
|
||||||
gameObj.transform.rotation = Quaternion.identity;
|
gameObj.transform.rotation = Quaternion.identity;
|
||||||
gameObj.name = domain;
|
gameObj.name = domain;
|
||||||
//创建位置层级
|
|
||||||
GameObject transformInfo = new GameObject("TransformInfo");
|
|
||||||
transformInfo.transform.SetParent(gameObj.transform);
|
|
||||||
transformInfo.transform.position = Vector3.zero;
|
|
||||||
transformInfo.transform.rotation = Quaternion.identity;
|
|
||||||
transformInfo.AddComponent<LocalTransformInfo>();
|
|
||||||
|
|
||||||
|
|
||||||
CreatDirectory($"{resPath}/Prefabs");
|
CreatDirectory($"{resPath}/Prefabs");
|
||||||
|
|||||||
@@ -2,12 +2,11 @@
|
|||||||
"name": "com.stary.evo.editor",
|
"name": "com.stary.evo.editor",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"GUID:d1a793c2b6959e04ea45b972eaa369c8",
|
"com.stary.evo.runtime",
|
||||||
"GUID:c5ecc461727906345a35491a0440694f",
|
"Unity.ScriptableBuildPipeline.Editor",
|
||||||
"GUID:4d1926c9df5b052469a1c63448b7609a",
|
"YooAsset",
|
||||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
"HybridCLR.Editor",
|
||||||
"GUID:9343e3f36d5deca4880d49f48b3fa2b1",
|
"YooAsset.Editor"
|
||||||
"GUID:ec45849e30ba03e4dab386099d8c697b"
|
|
||||||
],
|
],
|
||||||
"includePlatforms": [
|
"includePlatforms": [
|
||||||
"Editor"
|
"Editor"
|
||||||
|
|||||||
+4
-5
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using YooAsset;
|
|
||||||
|
|
||||||
namespace Main
|
namespace Main
|
||||||
{
|
{
|
||||||
@@ -36,9 +35,9 @@ namespace Main
|
|||||||
|
|
||||||
int GetPolLength();
|
int GetPolLength();
|
||||||
}
|
}
|
||||||
public class ClassObjectPool:IClassPool
|
public class GameObjectPool:IClassPool
|
||||||
{
|
{
|
||||||
private AssetHandle poolObject;
|
private GameObject poolObject;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 回收对象的父物体
|
/// 回收对象的父物体
|
||||||
@@ -50,7 +49,7 @@ namespace Main
|
|||||||
//没有回收的个数
|
//没有回收的个数
|
||||||
protected int noRecycleCount;
|
protected int noRecycleCount;
|
||||||
|
|
||||||
public ClassObjectPool(AssetHandle poolObject,Transform recycle)
|
public GameObjectPool(GameObject poolObject,Transform recycle)
|
||||||
{
|
{
|
||||||
this.poolObject = poolObject;
|
this.poolObject = poolObject;
|
||||||
this.recycle = recycle;
|
this.recycle = recycle;
|
||||||
@@ -84,7 +83,7 @@ namespace Main
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
obj= poolObject.InstantiateSync(parent);
|
obj= GameObject.Instantiate(poolObject,parent);
|
||||||
}
|
}
|
||||||
obj.transform.localPosition = Vector3.zero;
|
obj.transform.localPosition = Vector3.zero;
|
||||||
obj.transform.localRotation = Quaternion.identity;
|
obj.transform.localRotation = Quaternion.identity;
|
||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: e9c8fc4371b64e442a7d5b625b412a5a
|
guid: b536b81e1762a6a43ba6ac9aabe950d7
|
||||||
PrefabImporter:
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
using Stary.Evo;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Main
|
||||||
|
{
|
||||||
|
public interface IClientSocketSystem : ISystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 连接
|
||||||
|
/// </summary>
|
||||||
|
void OnConnect(string ip);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向服务端发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">消息类型</param>
|
||||||
|
/// <param name="message">消息内容</param>
|
||||||
|
void Send(SocketEvent type, string message);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 断开连接
|
||||||
|
/// </summary>
|
||||||
|
void DisConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ClientSocketSystem : AbstractSystem, IClientSocketSystem
|
||||||
|
{
|
||||||
|
private SocketClient _socketClient;
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
// 注意由于Unity编译器环境下,游戏开启/关闭只影响主线程的开关,游戏关闭回调时需要通过Close函数来关闭服务端/客户端的线程。
|
||||||
|
if (_socketClient != null) _socketClient.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向服务端发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">消息类型</param>
|
||||||
|
/// <param name="message">消息内容</param>
|
||||||
|
public void Send(SocketEvent type, string message)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(message);
|
||||||
|
_socketClient.Send((ushort)type, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 退出服务端
|
||||||
|
/// </summary>
|
||||||
|
public void DisConnect()
|
||||||
|
{
|
||||||
|
// 踢出连接
|
||||||
|
_socketClient.DisConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnConnect(string ip)
|
||||||
|
{
|
||||||
|
_socketClient = new SocketClient(ip, 10000);
|
||||||
|
|
||||||
|
|
||||||
|
_socketClient.Connect(() =>
|
||||||
|
{
|
||||||
|
Debug.Log("连接成功");
|
||||||
|
_socketClient.OnReceive += OnReceive;
|
||||||
|
// _client.DisConnect();
|
||||||
|
}, () => { Debug.Log("连接失败"); });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Connect()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接收客户端消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">指定客户端</param>
|
||||||
|
/// <param name="data">消息数据</param>
|
||||||
|
private void OnReceive(SocketDataPack data)
|
||||||
|
{
|
||||||
|
Debug.LogFormat("接收到数据>>>{0} {1}", (SocketEvent)data.Type, data.Buff.Length);
|
||||||
|
|
||||||
|
switch ((SocketEvent)data.Type)
|
||||||
|
{
|
||||||
|
case SocketEvent.ServerMessage:
|
||||||
|
Debug.LogFormat("接收到服务器数据 >>> {0}", Encoding.UTF8.GetString(data.Data));
|
||||||
|
var message = Encoding.UTF8.GetString(data.Data);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SocketEvent.ClientDisconn:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string GetLocalIPv4()
|
||||||
|
{
|
||||||
|
return Dns.GetHostEntry(Dns.GetHostName())
|
||||||
|
.AddressList.First(f => f.AddressFamily == AddressFamily.InterNetwork)
|
||||||
|
.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cf683938375f4ecf8f186b6f27cc1090
|
||||||
|
timeCreated: 1753945542
|
||||||
+165
@@ -0,0 +1,165 @@
|
|||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Stary.Evo;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Server
|
||||||
|
{
|
||||||
|
public interface IServerSocketSystem : ISystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 连接服务器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ip"></param>
|
||||||
|
void OnConnect(string ip = "");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向指定客户端发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">指定客户端</param>
|
||||||
|
/// <param name="type">消息类型</param>
|
||||||
|
/// <param name="message">消息内容</param>
|
||||||
|
void Send(Socket client, SocketEvent type, string message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向所有客户端发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">消息类型</param>
|
||||||
|
/// <param name="message">消息内容</param>
|
||||||
|
void SendAllClient(SocketEvent type, ResultEntity message);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 踢出指定客户端
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">指定客户端</param>
|
||||||
|
void KickOut(Socket client);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 踢出所有客户端
|
||||||
|
/// </summary>
|
||||||
|
void KickOutAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ServerSocketSystem : AbstractSystem, IServerSocketSystem
|
||||||
|
{
|
||||||
|
private SocketServer _socketServer;
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
// 注意由于Unity编译器环境下,游戏开启/关闭只影响主线程的开关,游戏关闭回调时需要通过Close函数来关闭服务端/客户端的线程。
|
||||||
|
if (_socketServer != null) _socketServer.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向指定客户端发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">指定客户端</param>
|
||||||
|
/// <param name="type">消息类型</param>
|
||||||
|
/// <param name="message">消息内容</param>
|
||||||
|
public void Send(Socket client, SocketEvent type, string message)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(message);
|
||||||
|
_socketServer.Send(client, (ushort)type, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向所有客户端发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">消息类型</param>
|
||||||
|
/// <param name="message">消息内容</param>
|
||||||
|
public void SendAllClient(SocketEvent type, ResultEntity message)
|
||||||
|
{
|
||||||
|
Debug.Log("SendAllClient向客户端发送消息:" + JsonConvert.SerializeObject(message));
|
||||||
|
foreach (var item in _socketServer.ClientInfoDic)
|
||||||
|
{
|
||||||
|
message.SetDeviceCode(item.Value.IP);
|
||||||
|
Debug.Log("向客户端发送消息:" + ResultEntity.ToEntityString(message));
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(ResultEntity.ToEntityString(message));
|
||||||
|
_socketServer.Send(item.Key, (ushort)type, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 服务器踢出客户端
|
||||||
|
/// </summary>
|
||||||
|
public void KickOut(Socket client)
|
||||||
|
{
|
||||||
|
// 踢出连接
|
||||||
|
_socketServer.KickOut(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 服务器踢出客户端
|
||||||
|
/// </summary>
|
||||||
|
public void KickOutAll()
|
||||||
|
{
|
||||||
|
// 踢出连接
|
||||||
|
foreach (var item in _socketServer.ClientInfoDic.Keys)
|
||||||
|
_socketServer.KickOutAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnConnect(string ip = "")
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(ip))
|
||||||
|
ip = "0.0.0.0";
|
||||||
|
_socketServer = new SocketServer(ip, 10000);
|
||||||
|
_socketServer.OnReceive += OnReceive;
|
||||||
|
_socketServer.OnConnect += OnConnect;
|
||||||
|
_socketServer.OnDisconnect += OnDisconnect;
|
||||||
|
_socketServer.OnHeadTimeOut += OnHeadTimeOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnConnect(Socket client)
|
||||||
|
{
|
||||||
|
var endPoint = client.RemoteEndPoint as IPEndPoint;
|
||||||
|
var clientIp = endPoint?.Address.ToString() ?? "未知IP";
|
||||||
|
this.SendEvent(ServerPanelType.QueryClient,
|
||||||
|
clientIp, RSSI.Good);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisconnect(Socket client)
|
||||||
|
{
|
||||||
|
var endPoint = client.RemoteEndPoint as IPEndPoint;
|
||||||
|
var clientIp = endPoint?.Address.ToString() ?? "未知IP";
|
||||||
|
this.SendEvent(ServerPanelType.QueryClient,
|
||||||
|
clientIp, RSSI.Not);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnHeadTimeOut(Socket client)
|
||||||
|
{
|
||||||
|
var endPoint = client.RemoteEndPoint as IPEndPoint;
|
||||||
|
var clientIp = endPoint?.Address.ToString() ?? "未知IP";
|
||||||
|
this.SendEvent(ServerPanelType.QueryClient,
|
||||||
|
clientIp, RSSI.Bad);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接收客户端消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">指定客户端</param>
|
||||||
|
/// <param name="data">消息数据</param>
|
||||||
|
private void OnReceive(Socket client, SocketDataPack data)
|
||||||
|
{
|
||||||
|
Debug.LogFormat("[{0}]接收到数据>>>{1} {2}", client.LocalEndPoint, (SocketEvent)data.Type, data.Buff.Length);
|
||||||
|
|
||||||
|
switch ((SocketEvent)data.Type)
|
||||||
|
{
|
||||||
|
case SocketEvent.ScTest:
|
||||||
|
Debug.LogFormat("接收到测试数据 >>> {0}", Encoding.UTF8.GetString(data.Data));
|
||||||
|
break;
|
||||||
|
case SocketEvent.ClientDisconn:
|
||||||
|
Debug.LogFormat("客户端断开连接 >>> {0}", client.LocalEndPoint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 83370f66e6954f62a28b9e38c266819a
|
||||||
|
timeCreated: 1753940317
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 588ac15fc35e4262979673d60d5360d5
|
||||||
|
timeCreated: 1753941532
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e1043c3356e14496b3692c245bfb461b
|
||||||
|
timeCreated: 1753941548
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
namespace Server
|
||||||
|
{
|
||||||
|
public enum ServerOpenSceneSchemaType
|
||||||
|
{
|
||||||
|
BirdView, //鸟瞰
|
||||||
|
Spot //临场
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ServerOpenSceneType
|
||||||
|
{
|
||||||
|
Unit1, //场景1
|
||||||
|
Unit2, //场景2
|
||||||
|
Unit3, //场景3
|
||||||
|
Unit4 //场景4
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ServerPanelType
|
||||||
|
{
|
||||||
|
OpenScene, //打开场景
|
||||||
|
ControlSchema, //控制场景开关
|
||||||
|
QueryClient //查询客户端
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 信号强度
|
||||||
|
/// </summary>
|
||||||
|
public enum RSSI
|
||||||
|
{
|
||||||
|
Good,
|
||||||
|
Bad,
|
||||||
|
Not
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cab61756e91e4736afde89c57340b821
|
||||||
|
timeCreated: 1753941563
|
||||||
+105
@@ -0,0 +1,105 @@
|
|||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Server
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public struct ResultCodeEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 状态码ServerPanelType
|
||||||
|
/// </summary>
|
||||||
|
private string code { get; set; }
|
||||||
|
|
||||||
|
private object message { get; set; }
|
||||||
|
|
||||||
|
private ResultCodeEntity(string code, object message)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string Code()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Message()
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly ResultCodeEntity OpenScene = new(ServerPanelType.OpenScene.ToString(), "");
|
||||||
|
public static readonly ResultCodeEntity ControlSchema = new(ServerPanelType.ControlSchema.ToString(), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct ResultEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 状态码ServerPanelType
|
||||||
|
/// </summary>
|
||||||
|
public string code { get; set; }
|
||||||
|
|
||||||
|
public string deviceCode { get; set; }
|
||||||
|
|
||||||
|
public object message { get; set; }
|
||||||
|
|
||||||
|
public void SetDeviceCode(string deviceCode)
|
||||||
|
{
|
||||||
|
this.deviceCode = deviceCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DeviceCode()
|
||||||
|
{
|
||||||
|
return deviceCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMessage(object message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ResultEntity(string code, string deviceCode, object message)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
this.deviceCode = deviceCode;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultEntity(ResultCodeEntity resultCode, string deviceCode)
|
||||||
|
{
|
||||||
|
code = resultCode.Code();
|
||||||
|
this.deviceCode = deviceCode;
|
||||||
|
message = resultCode.Message();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ToEntityString(ResultEntity entity)
|
||||||
|
{
|
||||||
|
var data = JsonConvert.SerializeObject(entity, Formatting.Indented);
|
||||||
|
return JsonConvert.SerializeObject(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResultEntity SetResultCode(ResultCodeEntity resultCode, string deviceCode)
|
||||||
|
{
|
||||||
|
var result = new ResultEntity(resultCode, deviceCode);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResultEntity SetResultCode(ResultCodeEntity resultCode, object message)
|
||||||
|
{
|
||||||
|
var result = new ResultEntity(resultCode, "");
|
||||||
|
result.message = message;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResultEntity SetResultCode(ResultCodeEntity resultCode, string deviceCode, object message)
|
||||||
|
{
|
||||||
|
var result = new ResultEntity(resultCode, deviceCode);
|
||||||
|
result.message = message;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 41f092961d2c4f33a0d0e980158dd89a
|
||||||
|
timeCreated: 1753941907
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Server
|
||||||
|
{
|
||||||
|
public struct ServerOpenSceneEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ServerOpenSceneType
|
||||||
|
/// </summary>
|
||||||
|
public string serverOpenSceneType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ServerOpenSceneSchemaType
|
||||||
|
/// </summary>
|
||||||
|
public string serverOpenSceneSchemaType;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fbb30584a7ca4dd7afadf941cb67692e
|
||||||
|
timeCreated: 1753941679
|
||||||
@@ -0,0 +1,371 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Threading;
|
||||||
|
using UnityEngine;
|
||||||
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Socket客户端
|
||||||
|
/// </summary>
|
||||||
|
public class SocketClient
|
||||||
|
{
|
||||||
|
private const int TIMEOUT_CONNECT = 3000; // 连接超时时间 毫秒
|
||||||
|
private const int TIMEOUT_SEND = 3000; // 发送超时时间 毫秒
|
||||||
|
private const int TIMEOUT_RECEIVE = 3000; //接收超时时间 毫秒
|
||||||
|
|
||||||
|
private const int HEAD_OFFSET = 2000; //心跳包发送间隔 毫秒
|
||||||
|
private const int RECONN_MAX_SUM = 3; //最大重连次数
|
||||||
|
private readonly DataBuffer _dataBuffer = new();
|
||||||
|
|
||||||
|
|
||||||
|
private readonly string _ip;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主线程
|
||||||
|
/// </summary>
|
||||||
|
private readonly SynchronizationContext _mainThread;
|
||||||
|
|
||||||
|
private readonly int _port;
|
||||||
|
private readonly int HEARTBEAT_TIMEOUT = 5000;
|
||||||
|
|
||||||
|
private Socket _client;
|
||||||
|
private Timer _connTimeoutTimer;
|
||||||
|
private Timer _headTimer;
|
||||||
|
private Timer _heartbeatTimeoutTimer;
|
||||||
|
|
||||||
|
private bool _isConnect;
|
||||||
|
private bool _isReconnect;
|
||||||
|
|
||||||
|
|
||||||
|
private long _lastHeartbeatResponseTime;
|
||||||
|
private Thread _receiveThread;
|
||||||
|
|
||||||
|
public SocketClient(string ip, int port)
|
||||||
|
{
|
||||||
|
_mainThread = SynchronizationContext.Current;
|
||||||
|
|
||||||
|
_ip = ip;
|
||||||
|
_port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action OnConnectSuccess; // 连接成功回调
|
||||||
|
public event Action OnConnectError; // 连接失败回调
|
||||||
|
public event Action OnDisconnect; // 断开回调
|
||||||
|
public event Action<SocketDataPack> OnReceive; // 接收报文回调
|
||||||
|
public event Action<SocketDataPack> OnSend; // 发送报文回调
|
||||||
|
public event Action<SocketException> OnError; // 异常捕获回调
|
||||||
|
public event Action<int> OnReConnectSuccess; // 重连成功回调
|
||||||
|
public event Action<int> OnReConnectError; // 单次重连失败回调
|
||||||
|
public event Action<int> OnReconnecting; // 单次重连中回调
|
||||||
|
|
||||||
|
public void Connect(Action success = null, Action error = null)
|
||||||
|
{
|
||||||
|
OnDisconnect += () => { Debug.Log("UnityEvo:断开连接"); };
|
||||||
|
|
||||||
|
OnReceive += dataPack => { Debug.LogFormat("UnityEvo:接收数据>>>{0}", (SocketEvent)dataPack.Type); };
|
||||||
|
OnSend += dataPack => { Debug.LogFormat("UnityEvo:发送数据>>>{0}", (SocketEvent)dataPack.Type); };
|
||||||
|
OnError += ex => { Debug.LogFormat("UnityEvo:出现异常>>>{0}", ex); };
|
||||||
|
OnReConnectSuccess += num => { Debug.LogFormat("UnityEvo:第{0}次重连成功", num); };
|
||||||
|
OnReConnectError += num => { Debug.LogFormat("UnityEvo:第{0}次重连失败", num); };
|
||||||
|
OnReconnecting += num => { Debug.LogFormat("UnityEvo:正在进行第{0}次重连", num); };
|
||||||
|
|
||||||
|
void OnTrigger(bool flag)
|
||||||
|
{
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
PostMainThreadAction(success);
|
||||||
|
PostMainThreadAction(OnConnectSuccess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PostMainThreadAction(error);
|
||||||
|
PostMainThreadAction(OnConnectError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_connTimeoutTimer != null)
|
||||||
|
{
|
||||||
|
_connTimeoutTimer.Stop();
|
||||||
|
_connTimeoutTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建套接字
|
||||||
|
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, TIMEOUT_SEND);
|
||||||
|
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, TIMEOUT_RECEIVE);
|
||||||
|
var ipAddress = IPAddress.Parse(_ip); //解析IP地址
|
||||||
|
var ipEndpoint = new IPEndPoint(ipAddress, _port);
|
||||||
|
var result = _client.BeginConnect(ipEndpoint, iar =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var client = (Socket)iar.AsyncState;
|
||||||
|
client.EndConnect(iar);
|
||||||
|
|
||||||
|
_isConnect = true;
|
||||||
|
// 开始发送心跳包
|
||||||
|
_headTimer = new Timer(HEAD_OFFSET);
|
||||||
|
_headTimer.AutoReset = true;
|
||||||
|
_headTimer.Elapsed += delegate { Send((ushort)SocketEvent.ClientHead); };
|
||||||
|
_headTimer.Start();
|
||||||
|
|
||||||
|
// 初始化心跳超时检测
|
||||||
|
_lastHeartbeatResponseTime = GetNowTime();
|
||||||
|
_heartbeatTimeoutTimer = new Timer(HEARTBEAT_TIMEOUT);
|
||||||
|
_heartbeatTimeoutTimer.AutoReset = true;
|
||||||
|
_heartbeatTimeoutTimer.Elapsed += (sender, e) =>
|
||||||
|
{
|
||||||
|
// 检测是否超时未收到服务端心跳响应
|
||||||
|
ReceiveHead();
|
||||||
|
};
|
||||||
|
_heartbeatTimeoutTimer.Start();
|
||||||
|
|
||||||
|
// 开始接收数据
|
||||||
|
_receiveThread = new Thread(ReceiveEvent);
|
||||||
|
_receiveThread.IsBackground = true;
|
||||||
|
_receiveThread.Start();
|
||||||
|
|
||||||
|
OnTrigger(true);
|
||||||
|
}
|
||||||
|
catch (SocketException ex)
|
||||||
|
{
|
||||||
|
OnTrigger(false);
|
||||||
|
}
|
||||||
|
}, _client); //异步连接
|
||||||
|
|
||||||
|
_connTimeoutTimer = new Timer(TIMEOUT_CONNECT);
|
||||||
|
_connTimeoutTimer.AutoReset = false;
|
||||||
|
_connTimeoutTimer.Elapsed += delegate { OnTrigger(false); };
|
||||||
|
_connTimeoutTimer.Start();
|
||||||
|
}
|
||||||
|
catch (SocketException ex)
|
||||||
|
{
|
||||||
|
OnTrigger(false);
|
||||||
|
// throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 断线重连
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="num"></param>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
public void ReConnect(int num = RECONN_MAX_SUM, int index = 0)
|
||||||
|
{
|
||||||
|
_isReconnect = true;
|
||||||
|
|
||||||
|
num--;
|
||||||
|
index++;
|
||||||
|
if (num < 0)
|
||||||
|
{
|
||||||
|
onDisconnect();
|
||||||
|
_isReconnect = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PostMainThreadAction(OnReconnecting, index);
|
||||||
|
Connect(() =>
|
||||||
|
{
|
||||||
|
PostMainThreadAction(OnReConnectSuccess, index);
|
||||||
|
_isReconnect = false;
|
||||||
|
}, () =>
|
||||||
|
{
|
||||||
|
PostMainThreadAction(OnReConnectError, index);
|
||||||
|
ReConnect(num, index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send(ushort e, byte[] buff = null, Action<SocketDataPack> onTrigger = null)
|
||||||
|
{
|
||||||
|
buff = buff ?? new byte[] { };
|
||||||
|
var dataPack = new SocketDataPack(e, buff);
|
||||||
|
var data = dataPack.Buff;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_client.BeginSend(data, 0, data.Length, SocketFlags.None, asyncSend =>
|
||||||
|
{
|
||||||
|
var c = (Socket)asyncSend.AsyncState;
|
||||||
|
c.EndSend(asyncSend);
|
||||||
|
PostMainThreadAction(onTrigger, dataPack);
|
||||||
|
PostMainThreadAction(OnSend, dataPack);
|
||||||
|
}, _client);
|
||||||
|
}
|
||||||
|
catch (SocketException ex)
|
||||||
|
{
|
||||||
|
onError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 线程内接收数据的函数
|
||||||
|
/// </summary>
|
||||||
|
private void ReceiveEvent()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!_isConnect) break;
|
||||||
|
if (_client.Available <= 0) continue;
|
||||||
|
var rbytes = new byte[8 * 1024];
|
||||||
|
var len = _client.Receive(rbytes);
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
_dataBuffer.AddBuffer(rbytes, len); // 将收到的数据添加到缓存器中
|
||||||
|
if (_dataBuffer.TryUnpack(out var dataPack)) // 尝试解包
|
||||||
|
{
|
||||||
|
//新增:处理服务器心跳响应
|
||||||
|
if (dataPack.Type == (ushort)SocketEvent.ServerHead)
|
||||||
|
_lastHeartbeatResponseTime = GetNowTime(); // 更新心跳响应时间戳
|
||||||
|
else if (dataPack.Type == (ushort)SocketEvent.ServerKickout)
|
||||||
|
// 服务端踢出
|
||||||
|
onDisconnect();
|
||||||
|
else if (dataPack.Type == (ushort)SocketEvent.ServerMessage)
|
||||||
|
// 收到消息
|
||||||
|
PostMainThreadAction(OnReceive, dataPack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (len == 0)
|
||||||
|
{
|
||||||
|
// 服务端正常关闭连接
|
||||||
|
onDisconnect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SocketException ex)
|
||||||
|
{
|
||||||
|
onError(ex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 业务逻辑 - 客户端主动断开
|
||||||
|
/// </summary>
|
||||||
|
public void DisConnect()
|
||||||
|
{
|
||||||
|
Send((ushort)SocketEvent.ClientDisconn);
|
||||||
|
onDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接收到心跳包
|
||||||
|
/// </summary>
|
||||||
|
private void ReceiveHead()
|
||||||
|
{
|
||||||
|
var now = GetNowTime();
|
||||||
|
var offset = now - _lastHeartbeatResponseTime;
|
||||||
|
Debug.Log("客户端更新服务端心跳时间戳 >>>" + GetNowTime() + " 间隔>>>" + offset);
|
||||||
|
if (GetNowTime() - _lastHeartbeatResponseTime > HEARTBEAT_TIMEOUT)
|
||||||
|
onError(new SocketException((int)SocketError.TimedOut));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缓存数据清理
|
||||||
|
/// </summary>
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
if (!_isConnect) return;
|
||||||
|
_isConnect = false;
|
||||||
|
if (_headTimer != null)
|
||||||
|
{
|
||||||
|
_headTimer.Stop();
|
||||||
|
_headTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停止并释放心跳超时检测定时器
|
||||||
|
if (_heartbeatTimeoutTimer != null)
|
||||||
|
{
|
||||||
|
_heartbeatTimeoutTimer.Stop();
|
||||||
|
_heartbeatTimeoutTimer.Dispose(); // 释放资源
|
||||||
|
_heartbeatTimeoutTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (_receiveThread != null)
|
||||||
|
// {
|
||||||
|
// _receiveThread.Abort();
|
||||||
|
// _receiveThread = null;
|
||||||
|
// }
|
||||||
|
if (_connTimeoutTimer != null)
|
||||||
|
{
|
||||||
|
_connTimeoutTimer.Stop();
|
||||||
|
_connTimeoutTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_client != null)
|
||||||
|
{
|
||||||
|
_client.Close();
|
||||||
|
_client = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误回调
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void onError(SocketException ex)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
PostMainThreadAction(OnError, ex);
|
||||||
|
|
||||||
|
if (!_isReconnect) ReConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 断开回调
|
||||||
|
/// </summary>
|
||||||
|
private void onDisconnect()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
PostMainThreadAction(OnDisconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通知主线程回调
|
||||||
|
/// </summary>
|
||||||
|
private void PostMainThreadAction(Action action)
|
||||||
|
{
|
||||||
|
_mainThread.Post(o =>
|
||||||
|
{
|
||||||
|
var e = (Action)o.GetType().GetProperty("action")?.GetValue(o);
|
||||||
|
if (e != null) e();
|
||||||
|
}, new { action });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PostMainThreadAction<T>(Action<T> action, T arg1)
|
||||||
|
{
|
||||||
|
_mainThread.Post(o =>
|
||||||
|
{
|
||||||
|
var e = (Action<T>)o.GetType().GetProperty("action")?.GetValue(o);
|
||||||
|
var t1 = (T)o.GetType().GetProperty("arg1")?.GetValue(o);
|
||||||
|
if (e != null) e(t1);
|
||||||
|
}, new { action, arg1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostMainThreadAction<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
|
||||||
|
{
|
||||||
|
_mainThread.Post(o =>
|
||||||
|
{
|
||||||
|
var e = (Action<T1, T2>)o.GetType().GetProperty("action")?.GetValue(o);
|
||||||
|
var t1 = (T1)o.GetType().GetProperty("arg1")?.GetValue(o);
|
||||||
|
var t2 = (T2)o.GetType().GetProperty("arg2")?.GetValue(o);
|
||||||
|
if (e != null) e(t1, t2);
|
||||||
|
}, new { action, arg1, arg2 });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前时间戳
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private long GetNowTime()
|
||||||
|
{
|
||||||
|
var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||||||
|
return Convert.ToInt64(ts.TotalMilliseconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[CreateAssetMenu(menuName = "Evo/SocketDataEntity")]
|
||||||
|
public class SocketDataEntity : ScriptableObject
|
||||||
|
{
|
||||||
|
public string serverIP;
|
||||||
|
public bool isConnected;
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 0f9c387bd15b741b2a7451be23c992ae
|
guid: 4ff6a39b61576884089bacd431abb4a8
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/// <summary>
|
||||||
|
/// 网络事件协议ID枚举
|
||||||
|
/// </summary>
|
||||||
|
public enum SocketEvent
|
||||||
|
{
|
||||||
|
ClientHead = 0x0001, //心跳包
|
||||||
|
ServerHead = 0x0006, //服务端心跳包
|
||||||
|
ClientDisconn = 0x0002, //客户端主动断开
|
||||||
|
ServerKickout = 0x0003, //服务端踢出
|
||||||
|
|
||||||
|
ServerMessage = 0x0004, //服务端发送消息
|
||||||
|
ClientMessage = 0x0005, //客户端发送消息
|
||||||
|
|
||||||
|
ScTest = 0x1001 //测试用
|
||||||
|
}
|
||||||
+83
-107
@@ -1,44 +1,36 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Timers;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
public class SocketInfo
|
public class SocketInfo
|
||||||
{
|
{
|
||||||
|
public long HeadTime;
|
||||||
public string IP;
|
public string IP;
|
||||||
public Thread ReceiveThread;
|
public Thread ReceiveThread;
|
||||||
public long HeadTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Socket服务端
|
/// Socket服务端
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SocketServer
|
public class SocketServer
|
||||||
{
|
{
|
||||||
|
private const int HEAD_TIMEOUT = 5000; // 心跳超时 毫秒
|
||||||
|
private readonly DataBuffer _dataBuffer = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 主线程
|
/// 主线程
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly SynchronizationContext _mainThread;
|
private readonly SynchronizationContext _mainThread;
|
||||||
|
|
||||||
|
|
||||||
private const int HEAD_TIMEOUT = 5000; // 心跳超时 毫秒
|
|
||||||
private const int HEAD_CHECKTIME = 5000; // 心跳包超时检测 毫秒
|
|
||||||
|
|
||||||
public readonly Dictionary<Socket, SocketInfo> ClientInfoDic = new Dictionary<Socket, SocketInfo>();
|
|
||||||
|
|
||||||
private readonly Socket _server;
|
private readonly Socket _server;
|
||||||
private System.Timers.Timer _headCheckTimer;
|
|
||||||
private readonly DataBuffer _dataBuffer = new DataBuffer();
|
|
||||||
|
|
||||||
public event Action<Socket> OnConnect; //客户端建立连接回调
|
public readonly Dictionary<Socket, SocketInfo> ClientInfoDic = new();
|
||||||
public event Action<Socket> OnDisconnect; // 客户端断开连接回调
|
|
||||||
public event Action<Socket, SocketDataPack> OnReceive; // 接收报文回调
|
|
||||||
public event Action<Socket, SocketDataPack> OnSend; // 发送报文回调
|
|
||||||
|
|
||||||
|
private Timer _headCheckTimer;
|
||||||
// 目前捕获异常将触发OnDisconnect回调 暂不单独处理
|
// 目前捕获异常将触发OnDisconnect回调 暂不单独处理
|
||||||
// public event Action<SocketException> OnError; // 异常捕获回调
|
// public event Action<SocketException> OnError; // 异常捕获回调
|
||||||
|
|
||||||
@@ -46,20 +38,17 @@ public class SocketServer
|
|||||||
|
|
||||||
public SocketServer(string ip, int port)
|
public SocketServer(string ip, int port)
|
||||||
{
|
{
|
||||||
OnConnect += (client) =>
|
OnConnect += client => { Debug.LogFormat("UnityEvo:连接成功 >> IP:{0}", client.LocalEndPoint); };
|
||||||
|
OnDisconnect += client =>
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.LogFormat("UnityEvo:连接成功 >> IP:{0}", client.LocalEndPoint.ToString());
|
if (ClientInfoDic.TryGetValue(client, out var value))
|
||||||
};
|
|
||||||
OnDisconnect += (client) =>
|
|
||||||
{
|
|
||||||
if(ClientInfoDic.TryGetValue(client, out var value))
|
|
||||||
Debug.LogFormat("UnityEvo:连接断开 >> IP:{0}", value.IP);
|
Debug.LogFormat("UnityEvo:连接断开 >> IP:{0}", value.IP);
|
||||||
};
|
};
|
||||||
|
|
||||||
_mainThread = SynchronizationContext.Current;
|
_mainThread = SynchronizationContext.Current;
|
||||||
|
|
||||||
_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
IPAddress ipAddress = IPAddress.Parse(ip); //解析IP地址
|
var ipAddress = IPAddress.Parse(ip); //解析IP地址
|
||||||
_server.Bind(new IPEndPoint(ipAddress, port)); //绑定IP地址:端口
|
_server.Bind(new IPEndPoint(ipAddress, port)); //绑定IP地址:端口
|
||||||
|
|
||||||
_server.Listen(10); //设定最多10个排队连接请求
|
_server.Listen(10); //设定最多10个排队连接请求
|
||||||
@@ -69,69 +58,75 @@ public class SocketServer
|
|||||||
connectThread.Start();
|
connectThread.Start();
|
||||||
|
|
||||||
// 心跳包定时检测
|
// 心跳包定时检测
|
||||||
_headCheckTimer = new System.Timers.Timer(HEAD_CHECKTIME);
|
_headCheckTimer = new Timer(HEAD_TIMEOUT);
|
||||||
_headCheckTimer.AutoReset = true;
|
_headCheckTimer.AutoReset = true;
|
||||||
_headCheckTimer.Elapsed += delegate(object sender, ElapsedEventArgs args) { CheckHeadTimeOut(); };
|
_headCheckTimer.Elapsed += delegate { CheckHeadTimeOut(); };
|
||||||
_headCheckTimer.Start();
|
_headCheckTimer.Start();
|
||||||
Debug.Log($"SocketServer Start: {ip}:{port}");
|
Debug.Log($"SocketServer Start: {ip}:{port}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public event Action<Socket> OnConnect; //客户端建立连接回调
|
||||||
/// 监听客户端连接
|
public event Action<Socket> OnDisconnect; // 客户端断开连接回调
|
||||||
/// </summary>
|
public event Action<Socket, SocketDataPack> OnReceive; // 接收报文回调
|
||||||
|
public event Action<Socket, SocketDataPack> OnSend; // 发送报文回调
|
||||||
|
|
||||||
|
public event Action<Socket> OnHeadTimeOut; // 心跳包收到超时回调
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 监听客户端连接
|
||||||
|
/// </summary>
|
||||||
private void ListenClientConnect()
|
private void ListenClientConnect()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_isValid) break;
|
if (!_isValid) break;
|
||||||
Socket client = _server.Accept();
|
var client = _server.Accept();
|
||||||
IPEndPoint ipEndPoint = (IPEndPoint)client.RemoteEndPoint;
|
var ipEndPoint = (IPEndPoint)client.RemoteEndPoint;
|
||||||
Thread receiveThread = new Thread(ReceiveEvent);
|
var receiveThread = new Thread(ReceiveEvent);
|
||||||
ClientInfoDic.Add(client,
|
ClientInfoDic.Add(client,
|
||||||
new SocketInfo() { IP = ipEndPoint.Address.ToString(), ReceiveThread = receiveThread, HeadTime = GetNowTime() });
|
new SocketInfo
|
||||||
|
{ IP = ipEndPoint.Address.ToString(), ReceiveThread = receiveThread, HeadTime = GetNowTime() });
|
||||||
receiveThread.Start(client);
|
receiveThread.Start(client);
|
||||||
|
|
||||||
PostMainThreadAction<Socket>(OnConnect, client);
|
PostMainThreadAction(OnConnect, client);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前时间戳
|
/// 获取当前时间戳
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private long GetNowTime()
|
private long GetNowTime()
|
||||||
{
|
{
|
||||||
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||||||
return Convert.ToInt64(ts.TotalMilliseconds);
|
return Convert.ToInt64(ts.TotalMilliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(Socket client, UInt16 e, byte[] buff = null, Action<SocketDataPack> onTrigger = null)
|
public void Send(Socket client, ushort e, byte[] buff = null, Action<SocketDataPack> onTrigger = null)
|
||||||
{
|
{
|
||||||
SendMessage(client, e, buff, onTrigger);
|
SendMessage(client, e, buff, onTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void SendMessage(Socket client, UInt16 e, byte[] buff = null, Action<SocketDataPack> onTrigger = null)
|
|
||||||
|
private void SendMessage(Socket client, ushort e, byte[] buff = null, Action<SocketDataPack> onTrigger = null)
|
||||||
{
|
{
|
||||||
buff = buff ?? new byte[] { };
|
buff = buff ?? new byte[] { };
|
||||||
var dataPack = new SocketDataPack(e, buff);
|
var dataPack = new SocketDataPack(e, buff);
|
||||||
var data = dataPack.Buff;
|
var data = dataPack.Buff;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
client.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback((asyncSend) =>
|
client.BeginSend(data, 0, data.Length, SocketFlags.None, asyncSend =>
|
||||||
{
|
{
|
||||||
Socket c = (Socket)asyncSend.AsyncState;
|
var c = (Socket)asyncSend.AsyncState;
|
||||||
c.EndSend(asyncSend);
|
c.EndSend(asyncSend);
|
||||||
PostMainThreadAction<SocketDataPack>(onTrigger, dataPack);
|
PostMainThreadAction(onTrigger, dataPack);
|
||||||
PostMainThreadAction<Socket, SocketDataPack>(OnSend, client, dataPack);
|
PostMainThreadAction(OnSend, client, dataPack);
|
||||||
}), client);
|
}, client);
|
||||||
}
|
}
|
||||||
catch (SocketException ex)
|
catch (SocketException ex)
|
||||||
{
|
{
|
||||||
@@ -141,42 +136,41 @@ public class SocketServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 线程内接收数据的函数
|
/// 线程内接收数据的函数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ReceiveEvent(object client)
|
private void ReceiveEvent(object client)
|
||||||
{
|
{
|
||||||
Socket tsocket = (Socket)client;
|
var tsocket = (Socket)client;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!_isValid) return;
|
if (!_isValid) return;
|
||||||
if (!ClientInfoDic.ContainsKey(tsocket))
|
if (!ClientInfoDic.ContainsKey(tsocket)) return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] rbytes = new byte[8 * 1024];
|
var rbytes = new byte[8 * 1024];
|
||||||
int len = tsocket.Receive(rbytes);
|
var len = tsocket.Receive(rbytes);
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
_dataBuffer.AddBuffer(rbytes, len); // 将收到的数据添加到缓存器中
|
_dataBuffer.AddBuffer(rbytes, len); // 将收到的数据添加到缓存器中
|
||||||
if (_dataBuffer.TryUnpack(out var dataPack)) // 尝试解包
|
if (_dataBuffer.TryUnpack(out var dataPack)) // 尝试解包
|
||||||
{
|
{
|
||||||
if (dataPack.Type == (UInt16)SocketEvent.ClientHead)
|
if (dataPack.Type == (ushort)SocketEvent.ClientHead)
|
||||||
{
|
{
|
||||||
// 接收到心跳包
|
// 接收到心跳包
|
||||||
ReceiveHead(tsocket);
|
ReceiveHead(tsocket);
|
||||||
|
//返回客户端心跳
|
||||||
|
Send(tsocket, (ushort)SocketEvent.ServerHead);
|
||||||
}
|
}
|
||||||
else if (dataPack.Type == (UInt16)SocketEvent.ClientDisconn)
|
else if (dataPack.Type == (ushort)SocketEvent.ClientDisconn)
|
||||||
{
|
|
||||||
// 客户端断开连接
|
// 客户端断开连接
|
||||||
|
{
|
||||||
CloseClient(tsocket);
|
CloseClient(tsocket);
|
||||||
}
|
}
|
||||||
else if (dataPack.Type == (UInt16)SocketEvent.ClientMessage)
|
else if (dataPack.Type == (ushort)SocketEvent.ClientMessage)
|
||||||
{
|
|
||||||
// 收到消息
|
// 收到消息
|
||||||
PostMainThreadAction<Socket, SocketDataPack>(OnReceive, tsocket, dataPack);
|
{
|
||||||
|
PostMainThreadAction(OnReceive, tsocket, dataPack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,76 +193,64 @@ public class SocketServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 接收到心跳包
|
/// 接收到心跳包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ReceiveHead(Socket client)
|
private void ReceiveHead(Socket client)
|
||||||
{
|
{
|
||||||
SocketInfo info;
|
SocketInfo info;
|
||||||
if (ClientInfoDic.TryGetValue(client, out info))
|
if (ClientInfoDic.TryGetValue(client, out info))
|
||||||
{
|
{
|
||||||
long now = GetNowTime();
|
var now = GetNowTime();
|
||||||
long offset = now - info.HeadTime;
|
var offset = now - info.HeadTime;
|
||||||
UnityEngine.Debug.Log("更新心跳时间戳 >>>" + now + " 间隔>>>" + offset);
|
Debug.Log("更新心跳时间戳 >>>" + now + " 间隔>>>" + offset);
|
||||||
if (offset > HEAD_TIMEOUT)
|
if (offset > HEAD_TIMEOUT)
|
||||||
{
|
|
||||||
// 心跳包收到但超时逻辑
|
// 心跳包收到但超时逻辑
|
||||||
}
|
OnHeadTimeOut?.Invoke(client);
|
||||||
|
|
||||||
info.HeadTime = now;
|
info.HeadTime = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检测心跳包超时
|
/// 检测心跳包超时
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void CheckHeadTimeOut()
|
private void CheckHeadTimeOut()
|
||||||
{
|
{
|
||||||
var tempList = new List<Socket>();
|
var tempList = new List<Socket>();
|
||||||
foreach (var socket in ClientInfoDic.Keys)
|
foreach (var socket in ClientInfoDic.Keys) tempList.Add(socket);
|
||||||
{
|
|
||||||
tempList.Add(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var socket in tempList)
|
foreach (var socket in tempList)
|
||||||
{
|
{
|
||||||
var info = ClientInfoDic[socket];
|
var info = ClientInfoDic[socket];
|
||||||
long now = GetNowTime();
|
var now = GetNowTime();
|
||||||
long offset = now - info.HeadTime;
|
var offset = now - info.HeadTime;
|
||||||
if (offset > HEAD_TIMEOUT)
|
if (offset > HEAD_TIMEOUT)
|
||||||
{
|
|
||||||
// 心跳包超时
|
// 心跳包超时
|
||||||
KickOut(socket);
|
KickOut(socket);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void KickOut(Socket client)
|
public void KickOut(Socket client)
|
||||||
{
|
{
|
||||||
// 踢出连接
|
// 踢出连接
|
||||||
Send(client, (UInt16)SocketEvent.ServerKickout, null, (dataPack) => { CloseClient(client); });
|
Send(client, (ushort)SocketEvent.ServerKickout, null, dataPack => { CloseClient(client); });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void KickOutAll()
|
public void KickOutAll()
|
||||||
{
|
{
|
||||||
var tempList = new List<Socket>();
|
var tempList = new List<Socket>();
|
||||||
foreach (var socket in ClientInfoDic.Keys)
|
foreach (var socket in ClientInfoDic.Keys) tempList.Add(socket);
|
||||||
{
|
|
||||||
tempList.Add(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var socket in tempList)
|
foreach (var socket in tempList) KickOut(socket);
|
||||||
{
|
|
||||||
KickOut(socket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 清理客户端连接
|
/// 清理客户端连接
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="client"></param>
|
/// <param name="client"></param>
|
||||||
private void CloseClient(Socket client)
|
private void CloseClient(Socket client)
|
||||||
{
|
{
|
||||||
PostMainThreadAction<Socket>((socket) =>
|
PostMainThreadAction(socket =>
|
||||||
{
|
{
|
||||||
if (OnDisconnect != null) OnDisconnect(socket);
|
if (OnDisconnect != null) OnDisconnect(socket);
|
||||||
ClientInfoDic.Remove(socket);
|
ClientInfoDic.Remove(socket);
|
||||||
@@ -277,7 +259,7 @@ public class SocketServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 关闭
|
/// 关闭
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
@@ -285,15 +267,9 @@ public class SocketServer
|
|||||||
_isValid = false;
|
_isValid = false;
|
||||||
// if (_connectThread != null) _connectThread.Abort();
|
// if (_connectThread != null) _connectThread.Abort();
|
||||||
var tempList = new List<Socket>();
|
var tempList = new List<Socket>();
|
||||||
foreach (var socket in ClientInfoDic.Keys)
|
foreach (var socket in ClientInfoDic.Keys) tempList.Add(socket);
|
||||||
{
|
|
||||||
tempList.Add(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var socket in tempList)
|
foreach (var socket in tempList) CloseClient(socket);
|
||||||
{
|
|
||||||
CloseClient(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_headCheckTimer != null)
|
if (_headCheckTimer != null)
|
||||||
{
|
{
|
||||||
@@ -319,31 +295,31 @@ public class SocketServer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void PostMainThreadAction(Action action)
|
private void PostMainThreadAction(Action action)
|
||||||
{
|
{
|
||||||
_mainThread.Post(new SendOrPostCallback((o) =>
|
_mainThread.Post(o =>
|
||||||
{
|
{
|
||||||
Action e = (Action)o.GetType().GetProperty("action")?.GetValue(o);
|
var e = (Action)o.GetType().GetProperty("action")?.GetValue(o);
|
||||||
if (e != null) e();
|
if (e != null) e();
|
||||||
}), new { action = action });
|
}, new { action });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PostMainThreadAction<T>(Action<T> action, T arg1)
|
private void PostMainThreadAction<T>(Action<T> action, T arg1)
|
||||||
{
|
{
|
||||||
_mainThread.Post(new SendOrPostCallback((o) =>
|
_mainThread.Post(o =>
|
||||||
{
|
{
|
||||||
Action<T> e = (Action<T>)o.GetType().GetProperty("action")?.GetValue(o);
|
var e = (Action<T>)o.GetType().GetProperty("action")?.GetValue(o);
|
||||||
T t1 = (T)o.GetType().GetProperty("arg1")?.GetValue(o);
|
var t1 = (T)o.GetType().GetProperty("arg1")?.GetValue(o);
|
||||||
if (e != null) e(t1);
|
if (e != null) e(t1);
|
||||||
}), new { action = action, arg1 = arg1 });
|
}, new { action, arg1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostMainThreadAction<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
|
public void PostMainThreadAction<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
|
||||||
{
|
{
|
||||||
_mainThread.Post(new SendOrPostCallback((o) =>
|
_mainThread.Post(o =>
|
||||||
{
|
{
|
||||||
Action<T1, T2> e = (Action<T1, T2>)o.GetType().GetProperty("action")?.GetValue(o);
|
var e = (Action<T1, T2>)o.GetType().GetProperty("action")?.GetValue(o);
|
||||||
T1 t1 = (T1)o.GetType().GetProperty("arg1")?.GetValue(o);
|
var t1 = (T1)o.GetType().GetProperty("arg1")?.GetValue(o);
|
||||||
T2 t2 = (T2)o.GetType().GetProperty("arg2")?.GetValue(o);
|
var t2 = (T2)o.GetType().GetProperty("arg2")?.GetValue(o);
|
||||||
if (e != null) e(t1, t2);
|
if (e != null) e(t1, t2);
|
||||||
}), new { action = action, arg1 = arg1, arg2 = arg2 });
|
}, new { action, arg1, arg2 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+19
-20
@@ -1,51 +1,50 @@
|
|||||||
using System.Collections;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class SocketClientMain : MonoBehaviour
|
public class SocketClientMain : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
private SocketClient _client;
|
||||||
private string ip = "127.0.0.1";
|
private string ip = "127.0.0.1";
|
||||||
private int port = 8080;
|
private int port = 8080;
|
||||||
private SocketClient _client;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_client = new SocketClient("192.168.31.67", 6854);
|
_client = new SocketClient("192.168.31.67", 6854);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_client.Connect(() =>
|
_client.Connect(() =>
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.Log("连接成功");
|
Debug.Log("连接成功");
|
||||||
|
|
||||||
// _client.DisConnect();
|
// _client.DisConnect();
|
||||||
}, () => { UnityEngine.Debug.Log("连接失败"); });
|
}, () => { Debug.Log("连接失败"); });
|
||||||
}
|
|
||||||
|
|
||||||
public void StartConnect(string ip = "", int port = 0)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (Input.GetKeyDown(KeyCode.A))
|
if (Input.GetKeyDown(KeyCode.A))
|
||||||
{
|
{
|
||||||
var bytes = System.Text.Encoding.UTF8.GetBytes("我是测试数据");
|
var bytes = Encoding.UTF8.GetBytes("我是测试数据");
|
||||||
_client.Send((System.UInt16)SocketEvent.ScTest, bytes);
|
_client.Send((ushort)SocketEvent.ScTest, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.D))
|
if (Input.GetKeyDown(KeyCode.D)) _client.DisConnect();
|
||||||
{
|
|
||||||
_client.DisConnect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
// 注意由于Unity编译器环境下,游戏开启/关闭只影响主线程的开关,游戏关闭回调时需要通过Close函数来关闭服务端/客户端的线程。
|
// 注意由于Unity编译器环境下,游戏开启/关闭只影响主线程的开关,游戏关闭回调时需要通过Close函数来关闭服务端/客户端的线程。
|
||||||
if (_client != null)
|
if (_client != null) _client.Close();
|
||||||
{
|
}
|
||||||
_client.Close();
|
|
||||||
}
|
public void StartConnect(string ip = "", int port = 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendServer(SocketEvent socketEvent, string message)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(message);
|
||||||
|
_client.Send((ushort)socketEvent, bytes);
|
||||||
|
Debug.LogFormat("客户端发送数据 >>> {0}", message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+12
-16
@@ -1,45 +1,41 @@
|
|||||||
using System.Collections;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class SocketServerMain : MonoBehaviour
|
public class SocketServerMain : MonoBehaviour
|
||||||
{
|
{
|
||||||
SocketServer _server;
|
private SocketServer _server;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_server = new SocketServer("192.168.31.67", 6854);
|
_server = new SocketServer("192.168.31.67", 6854);
|
||||||
|
|
||||||
_server.OnReceive += (client, data) =>
|
_server.OnReceive += (client, data) =>
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.LogFormat("[{0}]接收到数据>>>{1} {2}", client.LocalEndPoint.ToString(), (SocketEvent)data.Type, data.Buff.Length);
|
Debug.LogFormat("[{0}]接收到数据>>>{1} {2}", client.LocalEndPoint, (SocketEvent)data.Type, data.Buff.Length);
|
||||||
|
|
||||||
switch ((SocketEvent)data.Type)
|
switch ((SocketEvent)data.Type)
|
||||||
{
|
{
|
||||||
case SocketEvent.ScTest:
|
case SocketEvent.ScTest:
|
||||||
UnityEngine.Debug.LogFormat("接收到测试数据 >>> {0}", System.Text.Encoding.UTF8.GetString(data.Data));
|
Debug.LogFormat("接收到测试数据 >>> {0}", Encoding.UTF8.GetString(data.Data));
|
||||||
|
break;
|
||||||
|
case SocketEvent.ClientDisconn:
|
||||||
|
Debug.LogFormat("客户端断开连接 >>> {0}", client.LocalEndPoint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (Input.GetKeyDown(KeyCode.A))
|
if (Input.GetKeyDown(KeyCode.A))
|
||||||
{
|
|
||||||
// 踢出连接
|
// 踢出连接
|
||||||
foreach (var item in _server.ClientInfoDic.Keys)
|
foreach (var item in _server.ClientInfoDic.Keys)
|
||||||
{
|
|
||||||
_server.KickOutAll();
|
_server.KickOutAll();
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
// 注意由于Unity编译器环境下,游戏开启/关闭只影响主线程的开关,游戏关闭回调时需要通过Close函数来关闭服务端/客户端的线程。
|
// 注意由于Unity编译器环境下,游戏开启/关闭只影响主线程的开关,游戏关闭回调时需要通过Close函数来关闭服务端/客户端的线程。
|
||||||
if (_server != null)
|
if (_server != null) _server.Close();
|
||||||
{
|
|
||||||
_server.Close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,9 +2,7 @@
|
|||||||
"name": "com.stary.evo.runtime",
|
"name": "com.stary.evo.runtime",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
"UniTask"
|
||||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
|
||||||
"GUID:5c01796d064528144a599661eaab93a6"
|
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "com.staryevo.main",
|
"name": "com.staryevo.main",
|
||||||
"version": "1.3.33",
|
"version": "2.0.0",
|
||||||
"displayName": "00.StaryEvo",
|
"displayName": "00.StaryEvo",
|
||||||
"description": "This is an Framework package(后台服务器版本,端口9527)",
|
"description": "This is an Framework package(后台服务器版本,端口9527)",
|
||||||
"unity": "2021.3",
|
"unity": "2021.3",
|
||||||
@@ -15,9 +15,7 @@
|
|||||||
"url": "http://192.168.31.100:8088/framework/xosmopluginlibrary.git#02.InformationSave"
|
"url": "http://192.168.31.100:8088/framework/xosmopluginlibrary.git#02.InformationSave"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"com.cysharp.unitask": "2.5.10",
|
"com.cysharp.unitask": "2.5.10"
|
||||||
"com.tuyoogame.yooasset": "2.3.7",
|
|
||||||
"com.staryevo.informationsave": "1.x.x"
|
|
||||||
},
|
},
|
||||||
"samples": [
|
"samples": [
|
||||||
{
|
{
|
||||||
|
|||||||
+30
-3
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using Stary.Evo.Editor;
|
using Stary.Evo.Editor;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -12,13 +13,26 @@ namespace Stary.Evo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[HideInInspector]
|
[HideInInspector]
|
||||||
private SerializedProperty domain;
|
private SerializedProperty domain;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 序列化属性,在OnEnable中获取
|
||||||
|
/// </summary>
|
||||||
|
[HideInInspector]
|
||||||
|
private SerializedProperty loadDomain;
|
||||||
private string[] domainNames;
|
private string[] domainNames;
|
||||||
|
|
||||||
|
private string[] loadDomainNames;
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
domain = serializedObject.FindProperty("domain");
|
domain = serializedObject.FindProperty("domain");
|
||||||
|
loadDomain = serializedObject.FindProperty("loadDomain");
|
||||||
domainNames = CreatAssetWindow.GetCreatDomainAllName();
|
domainNames = CreatAssetWindow.GetCreatDomainAllName();
|
||||||
|
|
||||||
|
// 创建新数组,长度+1并在第0位插入null
|
||||||
|
// 创建新数组,长度+1并在第0位插入null
|
||||||
|
loadDomainNames = new string[domainNames.Length + 1];
|
||||||
|
loadDomainNames[0]="null"; // 第0位添加null
|
||||||
|
Array.Copy(domainNames, 0, loadDomainNames, 1, domainNames.Length); // 复制原始元素到新数组从索引1开始
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnInspectorGUI()
|
public override void OnInspectorGUI()
|
||||||
@@ -35,8 +49,6 @@ namespace Stary.Evo
|
|||||||
// 更新选择的域名
|
// 更新选择的域名
|
||||||
domain.stringValue = domainNames[selectedIndex];
|
domain.stringValue = domainNames[selectedIndex];
|
||||||
|
|
||||||
serializedObject.ApplyModifiedProperties();
|
|
||||||
|
|
||||||
HybridClREntrance hybridClREntrance = target as HybridClREntrance;
|
HybridClREntrance hybridClREntrance = target as HybridClREntrance;
|
||||||
if (GUILayout.Button("打开Domain"))
|
if (GUILayout.Button("打开Domain"))
|
||||||
{
|
{
|
||||||
@@ -46,6 +58,21 @@ namespace Stary.Evo
|
|||||||
{
|
{
|
||||||
hybridClREntrance.CloseDomain();
|
hybridClREntrance.CloseDomain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//loaddoamin绘制
|
||||||
|
// 获取当前选中的索引
|
||||||
|
|
||||||
|
|
||||||
|
int loadDomainSelectedIndex = System.Array.IndexOf(loadDomainNames, loadDomain.stringValue);
|
||||||
|
if (loadDomainSelectedIndex < 0) loadDomainSelectedIndex = 0; // 默认选中第一个
|
||||||
|
|
||||||
|
// 绘制下拉选择框
|
||||||
|
loadDomainSelectedIndex = EditorGUILayout.Popup("LoadDomain", loadDomainSelectedIndex, loadDomainNames);
|
||||||
|
|
||||||
|
// 更新选择的域名
|
||||||
|
loadDomain.stringValue = loadDomainNames[loadDomainSelectedIndex];
|
||||||
|
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "RKTools.Editor",
|
"name": "com.staryevo.tools.editor",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"GUID:10c9b58b77ad42b4193e2a393b1a9899",
|
"GUID:f3fa071c399c4383a9ff8115e53dfefc",
|
||||||
"GUID:044184040b21c434b8aee6f2a3424c06"
|
"GUID:044184040b21c434b8aee6f2a3424c06"
|
||||||
],
|
],
|
||||||
"includePlatforms": [
|
"includePlatforms": [
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fe35d1ee624b481c9d9a1504254bacdd
|
||||||
|
timeCreated: 1756795325
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user