Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XGame
|
||||
{
|
||||
public class TerrainManager : MonoBehaviour
|
||||
{
|
||||
public static TerrainManager m_Instance = null;
|
||||
|
||||
//string heightMap = "res/scene/ground/create/height01.png";
|
||||
//string mixMap = "res/scene/ground/create/mix03.png";//"res/scene/ground/create/mix01.tga";
|
||||
string[] baseMap = { "res/scene/ground/mat/Ground_005_T.png", "res/scene/ground/mat/Ground_007_T.png",
|
||||
"res/scene/ground/mat/Ground_G003_T.png", "res/scene/ground/mat/Ground_003_T.tga" };
|
||||
string[] normalMap = { "res/scene/ground/mat/Ground_005_M.tga", "res/scene/ground/mat/Ground_G001_M.tga",
|
||||
"res/scene/ground/mat/Ground_G003_M.tga", "res/scene/ground/mat/Ground_003_M.tga" };
|
||||
|
||||
private TerrainObject m_TerrainObject;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
m_Instance = this;
|
||||
Debug.Log("TerrainManager Awake");
|
||||
}
|
||||
|
||||
public static IEnumerator Init()
|
||||
{
|
||||
if(m_Instance == null)
|
||||
Debug.Log("TerrainManager m_Instance == null");
|
||||
yield return m_Instance.LocalInit();
|
||||
}
|
||||
|
||||
private IEnumerator LocalInit()
|
||||
{
|
||||
m_TerrainObject = new TerrainObject();
|
||||
//yield return m_TerrainObject.CreateGroundObjectFromPic(0, 0, heightMap, mixMap, baseMap, normalMap, gameObject.transform);
|
||||
yield break;
|
||||
}
|
||||
|
||||
//heightMap 高度图
|
||||
//mixMap 混合图
|
||||
//baseMap 基础地表纹理图列表 4-16张
|
||||
|
||||
public static IEnumerator coCreateMap(string heightMap, string mixMap, string[] baseMap, Action<UnityEngine.Object[]> action)
|
||||
{
|
||||
List<UnityEngine.Object> result = new List<UnityEngine.Object>();
|
||||
yield return XResLoader.coLoadAllRes(new string[] { heightMap, mixMap }, typeof(GameObject), objs =>
|
||||
{
|
||||
if (objs == null || objs[0] == null)
|
||||
{
|
||||
Debug.Log($"Load heightMap, mixMap Failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(objs[0]);//heightMap
|
||||
result.Add(objs[1]);//mixMap
|
||||
}
|
||||
});
|
||||
yield return XResLoader.coLoadAllRes(baseMap, typeof(GameObject), objs =>
|
||||
{
|
||||
if (objs == null || objs[0] == null)
|
||||
{
|
||||
Debug.Log($"Load heightMap, mixMap Failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < objs.Length; ++i)
|
||||
{
|
||||
result.Add(objs[i]);//baseMap
|
||||
}
|
||||
}
|
||||
});
|
||||
action(result.ToArray());
|
||||
}
|
||||
|
||||
void LoadGround(float xpos, float zpos)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 801b8e092355f2c498ccec7520699259
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,394 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using XLua;
|
||||
using static XLua.LuaEnv;
|
||||
|
||||
namespace XGame
|
||||
{
|
||||
public class LuaManager : MonoBehaviour
|
||||
{
|
||||
public static LuaEnv m_LuaEnv = null;// new LuaEnv();
|
||||
public static LuaEnv.CustomLoader m_CustomLoader;
|
||||
|
||||
private const string LUA_SUFFIX = ".lua";
|
||||
private const string BYTES_SUFFIX = ".bytes";
|
||||
private const float INTERVAL = 1.0f;
|
||||
|
||||
//private bool m_bStart = false;
|
||||
private float m_Timestamp = 0;
|
||||
|
||||
public static LuaManager m_Instance = null;
|
||||
|
||||
//系统lua
|
||||
private AssetBundle m_LuaAB = null;
|
||||
private LuaTable m_LuaMain = null;
|
||||
private Action m_MainUpdate = null;
|
||||
private Action m_MainLateUpdate = null;
|
||||
private Action m_MainLogicUpdate = null;
|
||||
private Action m_MainGUI = null;
|
||||
private Action m_MainQuit = null;
|
||||
//XWorld lua
|
||||
private Dictionary<string, AssetBundle> m_LuaXWABs = new Dictionary<string, AssetBundle>();//xid, ab
|
||||
private string m_curXID;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_Instance = this;
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
}
|
||||
private IEnumerator LoadBaseLuaAB()
|
||||
{
|
||||
yield return XResLoader.GetFileDataOrigin("XWorld","bs.unity3d", (uwr) =>
|
||||
{
|
||||
if (uwr == null)
|
||||
{
|
||||
Debug.LogError($"Load AB Error: bs.unity3d");
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] decrypt = AESManager.Decrypt(uwr.downloadHandler.data);//bs.unity3d
|
||||
m_LuaAB = AssetBundle.LoadFromMemory(decrypt);
|
||||
Debug.Log("m_LuaAB Load OK!");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//Key : local或xid
|
||||
public IEnumerator LoadAB(string Path, string Xid = null)
|
||||
{
|
||||
yield return XResLoader.coLoadFile(Path, (data) =>
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
Debug.LogError($"Load AB Error: {Path}");
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] decrypt = AESManager.Decrypt(data);//bs.unity3d
|
||||
AssetBundle ab = AssetBundle.LoadFromMemory(decrypt);
|
||||
if (Xid != null)
|
||||
m_LuaXWABs[Xid] = ab;
|
||||
else
|
||||
m_LuaXWABs[GlobalData.CurNode] = ab;
|
||||
|
||||
}
|
||||
});
|
||||
yield break;
|
||||
}
|
||||
|
||||
public void ReleaseLua(string Xid)
|
||||
{
|
||||
if (Xid == null)
|
||||
{//基础Lua,可能不需要即时释放
|
||||
//释放lua
|
||||
//。。。
|
||||
//m_LuaAB.Unload(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_LuaXWABs.ContainsKey(Xid))
|
||||
{
|
||||
AssetBundle ab = null;
|
||||
if(m_LuaXWABs.TryGetValue(Xid, out ab))
|
||||
{
|
||||
ab.Unload(true);
|
||||
m_LuaXWABs.Remove(Xid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private IEnumerator LocalInit()
|
||||
{
|
||||
|
||||
m_CustomLoader = (ref string path) =>
|
||||
{//加载器 默认先从基础文件找,然后再去当前库找
|
||||
string originalFixedPath = path.Replace('.', '/');
|
||||
string fixedPath = originalFixedPath.ToLower();
|
||||
//Debug.Log($"Base Loader : {fixedPath}");
|
||||
|
||||
byte[] content = null;
|
||||
#if UNITY_EDITOR
|
||||
//编辑器查找底层lua本地文件
|
||||
if (File.Exists($"assets/lua/{fixedPath}.lua"))
|
||||
{
|
||||
content = System.IO.File.ReadAllBytes($"assets/lua/{fixedPath}.lua");
|
||||
if (content != null)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
TextAsset textAsset;
|
||||
|
||||
//然后查找底层ab
|
||||
//根据文件路径在Assets/lua/路径里(或者luabytes里)加载lua
|
||||
//先加载系统lua文件
|
||||
string luaPath = $"assets/l/{fixedPath}.bytes";
|
||||
if (m_LuaAB != null)
|
||||
{
|
||||
textAsset = m_LuaAB.LoadAsset<TextAsset>(luaPath);//
|
||||
|
||||
if (textAsset != null)
|
||||
{
|
||||
content = textAsset.bytes;
|
||||
return content;
|
||||
//Debug.LogError($"lua {path} not found!");
|
||||
}
|
||||
}
|
||||
//Debug.LogError($"m_LuaAB {luaPath} not found!");
|
||||
//非系统lua则寻找节点lua
|
||||
//编辑器找本地
|
||||
#if UNITY_EDITOR
|
||||
//编辑器查找节点lua本地文件
|
||||
//luaPath = $"assets/{GlobalData.CurNode}/script/{fixedPath}.lua";
|
||||
luaPath = $"{Application.dataPath}/../../Lua/{fixedPath}.lua";
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
content = System.IO.File.ReadAllBytes(luaPath);
|
||||
if (content != null)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
luaPath = $"{Application.dataPath}/lua/{originalFixedPath}.lua";
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
content = System.IO.File.ReadAllBytes(luaPath);
|
||||
if (content != null)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
luaPath = $"{Application.dataPath}/lua/{fixedPath}.lua";
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
content = System.IO.File.ReadAllBytes(luaPath);
|
||||
if (content != null)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
luaPath = $"{Application.dataPath}/../../{originalFixedPath}.lua";
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
content = System.IO.File.ReadAllBytes(luaPath);
|
||||
if (content != null)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
luaPath = $"{Application.dataPath}/../../{fixedPath}.lua";
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
content = System.IO.File.ReadAllBytes(luaPath);
|
||||
if (content != null)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
luaPath = $"assets/l/{fixedPath}.bytes";
|
||||
//Debug.Log($"lua {path} size:{textAsset.bytes.Length}!");
|
||||
AssetBundle luaAB = null;
|
||||
|
||||
if (m_curXID != null && m_LuaXWABs.ContainsKey(m_curXID))
|
||||
{
|
||||
luaAB = m_LuaXWABs[m_curXID];
|
||||
if (luaAB != null)
|
||||
{
|
||||
textAsset = m_LuaAB.LoadAsset<TextAsset>(luaPath);//
|
||||
if (textAsset != null)
|
||||
{
|
||||
return textAsset.bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var ab in m_LuaXWABs)
|
||||
{
|
||||
if (ab.Value != null && ab.Value != luaAB)
|
||||
{
|
||||
textAsset = m_LuaAB.LoadAsset<TextAsset>(luaPath);//
|
||||
if (textAsset != null)
|
||||
{
|
||||
return textAsset.bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
yield return RestartLua();
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
public IEnumerator RestartLua()
|
||||
{
|
||||
if (m_LuaEnv != null)
|
||||
{
|
||||
m_LuaEnv.Dispose();
|
||||
m_LuaEnv = null;
|
||||
if (m_LuaAB != null)
|
||||
{
|
||||
m_LuaAB.Unload(true);
|
||||
m_LuaAB = null;
|
||||
}
|
||||
m_LuaMain = null;
|
||||
m_MainUpdate = null;
|
||||
m_MainLateUpdate = null;
|
||||
m_MainLogicUpdate = null;
|
||||
m_MainGUI = null;
|
||||
m_MainQuit = null;
|
||||
GC.Collect();
|
||||
}
|
||||
//修改默认加载位置xid或local
|
||||
m_LuaEnv = new LuaEnv();//*/
|
||||
if (m_LuaAB == null)
|
||||
{
|
||||
Debug.Log("Init m_LuaAB");
|
||||
yield return LoadBaseLuaAB();
|
||||
}
|
||||
m_LuaEnv.AddLoader(m_CustomLoader);
|
||||
//默认函数
|
||||
m_LuaEnv.Global.Set("XWorldGetTime", (System.Func<double>)Utility.XWorldGetTime);
|
||||
Debug.Log($"LuaManager Init 'XWMain' {m_LuaEnv.Memroy}KB");
|
||||
|
||||
//无需使用lua
|
||||
yield break;
|
||||
//默认lua入口文件
|
||||
m_LuaEnv.DoString("require'XWBaseLua.XWMain'");
|
||||
Debug.Log("require'XWBaseLua.XWMain'");
|
||||
m_LuaMain = m_LuaEnv.Global.Get<LuaTable>("XWMain");
|
||||
if (m_LuaMain == null)
|
||||
{
|
||||
Debug.LogError("Error: Lua 'Main' Not Found !");
|
||||
yield break;
|
||||
}
|
||||
//m_LuaEnv.DoString("_G.Main=nil");//全局的置空
|
||||
Action initFunc = m_LuaMain.Get<Action>("XWInit");
|
||||
if (initFunc != null)
|
||||
{
|
||||
initFunc();
|
||||
}
|
||||
//m_LuaEnv.DoString("MaPlayerPrefsin.Init()");
|
||||
m_MainUpdate = m_LuaMain.Get<Action>("XWUpdate");
|
||||
m_MainLateUpdate = m_LuaMain.Get<Action>("XWLateUpdate");
|
||||
m_MainLogicUpdate = m_LuaMain.Get<Action>("XWFixedUpdate");
|
||||
m_MainGUI = m_LuaMain.Get<Action>("XWGUI");
|
||||
m_MainQuit = m_LuaMain.Get<Action>("XWQuit");
|
||||
//Debug.Log($"'Main' Loaded {m_LuaEnv.Memroy}KB");
|
||||
//m_bStart = true;
|
||||
|
||||
//加载默认节点
|
||||
string xid = XData.GetString("XWorldID");
|
||||
//默认加载Lua开发模块
|
||||
//Action<string> AddModule = m_LuaMain.Get<Action<string>>("AddModule");
|
||||
//AddModule("client/client");
|
||||
#if UNITY_EDITOR
|
||||
|
||||
#endif
|
||||
yield break;
|
||||
}
|
||||
|
||||
public static IEnumerator Init()
|
||||
{
|
||||
yield return m_Instance.LocalInit();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
float now = Time.time;
|
||||
if (m_MainUpdate != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_MainUpdate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
if (!(now > m_Timestamp + INTERVAL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_Timestamp = now;
|
||||
if(m_LuaEnv != null)
|
||||
m_LuaEnv.Tick();
|
||||
}
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (m_MainLateUpdate != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_MainLateUpdate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void FixedUpdate()
|
||||
{ //
|
||||
if (m_MainLogicUpdate != null)
|
||||
{
|
||||
m_MainLogicUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (m_MainGUI != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_MainGUI();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DoString(string sLuaString)
|
||||
{
|
||||
m_LuaEnv.DoString(sLuaString);
|
||||
}
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
if(m_MainQuit != null)
|
||||
m_MainQuit();
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
//热更新lua
|
||||
private void OnLuaFileChange(string filePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filePath) || !filePath.EndsWith(LUA_SUFFIX, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//重载文件
|
||||
//filePath = filePath.Replace('\\', '/');
|
||||
//int startIndex = filePath.IndexOf(LuaEditorBaseUrl) + 7;
|
||||
//filePath = filePath.Substring(startIndex, filePath.Length - startIndex - LUA_SUFFIX.Length);
|
||||
//Invoke("ToolManager.ReloadLuaFile", filePath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 077d0e0d320bc3d41866b4ef3c249888
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,90 @@
|
||||
|
||||
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using XLua;
|
||||
using System.IO;
|
||||
|
||||
class LuaServer : MonoBehaviour
|
||||
{
|
||||
public static LuaEnv m_LuaEnv = new LuaEnv();
|
||||
|
||||
private Thread _thread;
|
||||
private bool _isThreadRunning;
|
||||
private string _result;
|
||||
private float _timeBegin = 0;
|
||||
|
||||
void Start()
|
||||
{
|
||||
//初始化
|
||||
m_LuaEnv.AddLoader((ref string path) =>
|
||||
{//加载器 默认先从基础文件找,然后再去当前库找
|
||||
string fixedPath = path.Replace('.', '/');
|
||||
//Debug.Log($"Base Loader : {fixedPath}");
|
||||
|
||||
#if UNITY_EDITOR
|
||||
byte[] content = null;
|
||||
//编辑器查找底层lua本地文件
|
||||
if (File.Exists($"assets/lua/{fixedPath}.lua"))
|
||||
{
|
||||
content = System.IO.File.ReadAllBytes($"assets/lua/{fixedPath}.lua");
|
||||
if (content != null)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
string luaPath = $"../Lua/{fixedPath}.lua";
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
content = System.IO.File.ReadAllBytes(luaPath);
|
||||
if (content != null)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return null;
|
||||
});
|
||||
m_LuaEnv.DoString("require'server/xwserver'");
|
||||
|
||||
// 启动子线程
|
||||
_thread = new Thread(Run);
|
||||
_isThreadRunning = true;
|
||||
_thread.Start();
|
||||
|
||||
_timeBegin = Time.realtimeSinceStartup;
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
// 在主线程中处理子线程的结果
|
||||
if (!_isThreadRunning && _result != null)
|
||||
{
|
||||
Debug.Log("Result from thread: " + _result);
|
||||
_result = null; // 清除结果,避免重复处理
|
||||
}
|
||||
}
|
||||
|
||||
void Run()
|
||||
{
|
||||
// 模拟耗时操作
|
||||
while (_thread != null)
|
||||
{
|
||||
Thread.Sleep(66);
|
||||
if (Time.realtimeSinceStartup - _timeBegin > 60)//60秒退出
|
||||
{
|
||||
_result = "Work completed!";
|
||||
_isThreadRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
// 确保在销毁时停止子线程
|
||||
if (_thread != null && _thread.IsAlive)
|
||||
{
|
||||
_thread.Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3539fd3d393cf014e89a926abd9a95ba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
//节点运行
|
||||
class NodeRunner
|
||||
{
|
||||
int Start(string NodeName)
|
||||
{ //打开对应游戏节点
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Close(int NodeID)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ac8b7067c1411149aa2001c879a8c69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec896450a5a2cd54b9eed305afae7ae7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,719 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using UnityEngine;
|
||||
using System.Net.WebSockets;
|
||||
using System.Threading;
|
||||
using UnityEngine.Networking.PlayerConnection;
|
||||
using System.Text;
|
||||
using UnityWebSocket;
|
||||
using WebSocketState = System.Net.WebSockets.WebSocketState;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace XGame
|
||||
{
|
||||
public class XWebSocket
|
||||
{
|
||||
private IWebSocket m_WebSocket;//第三方webGL库
|
||||
string m_Url;
|
||||
|
||||
private Socket m_TcpSocket = null;
|
||||
private Thread m_TcpThread = null;
|
||||
private bool m_UseTcp = false;
|
||||
private readonly object m_BufferLock = new object();
|
||||
|
||||
private Action<XWebSocket, string> m_Callback = null;
|
||||
|
||||
public ClientWebSocket m_wSocket;
|
||||
public CancellationToken m_Token;
|
||||
private bool m_bRun = false;
|
||||
private byte[] m_byteBuffer = new byte[65536];
|
||||
private byte[] m_byteTemp = new byte[4096];
|
||||
|
||||
private ArraySegment<byte> m_bufSegment;
|
||||
private int m_bufCurPos = 0;
|
||||
|
||||
//float heartTime = 0;
|
||||
//float receiveMsgTime = 0;
|
||||
//float reconnectCount = 0;
|
||||
|
||||
public bool IsConected()
|
||||
{
|
||||
if (m_bRun && ((m_UseTcp && m_TcpSocket != null) || (!m_UseTcp && m_WebSocket != null)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
public int GetRecvSize() { lock (m_BufferLock) { return m_bufCurPos; } }
|
||||
|
||||
public bool isDataRecv() { lock (m_BufferLock) { return (m_bufCurPos > 0) ? true : false; } }
|
||||
|
||||
public void Connect(string url, Action<XWebSocket, string> callback)
|
||||
{
|
||||
m_Url = url;
|
||||
m_Callback = callback;
|
||||
//m_Url = "wss://echo.websocket.events";
|
||||
m_bRun = true;
|
||||
m_WebSocket = new UnityWebSocket.WebSocket(m_Url);
|
||||
m_WebSocket.OnOpen += Socket_OnOpen;
|
||||
m_WebSocket.OnMessage += Socket_OnMessage;
|
||||
m_WebSocket.OnClose += Socket_OnClose;
|
||||
m_WebSocket.OnError += Socket_OnError;
|
||||
m_WebSocket.ConnectAsync();
|
||||
}
|
||||
|
||||
public void ConnectTcp(string host, int port, Action<XWebSocket, string> callback)
|
||||
{
|
||||
m_UseTcp = true;
|
||||
m_Url = $"{host}:{port}";
|
||||
m_Callback = callback;
|
||||
try
|
||||
{
|
||||
m_TcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
m_TcpSocket.Connect(host, port);
|
||||
m_bRun = true;
|
||||
m_TcpThread = new Thread(TcpReceiveLoop);
|
||||
m_TcpThread.IsBackground = true;
|
||||
m_TcpThread.Start();
|
||||
Debug.Log($"Connected tcp://{m_Url}");
|
||||
m_Callback(this, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_bRun = false;
|
||||
Debug.Log($"Tcp connect error: {e.Message}");
|
||||
m_Callback(null, e.Message);
|
||||
}
|
||||
}
|
||||
public void Socket_OnOpen(object sender, OpenEventArgs e)
|
||||
{
|
||||
if (e != null)
|
||||
Debug.Log($"Connected {m_Url} Result : {sender.ToString()}");
|
||||
else
|
||||
Debug.Log(string.Format("Connected: {0}", m_Url));
|
||||
m_Callback(this, null);
|
||||
}
|
||||
|
||||
public void Socket_OnMessage(object sender, UnityWebSocket.MessageEventArgs e)
|
||||
{
|
||||
//if (e.IsBinary)
|
||||
//{
|
||||
// Debug.Log(string.Format("C# Receive Bytes ({1}): {0}", e.Data, e.RawData.Length));
|
||||
//}
|
||||
//else if (e.IsText)
|
||||
//{
|
||||
// Debug.Log(string.Format("C# Receive: {0}", e.Data));
|
||||
//}
|
||||
//ArraySegment<byte> byteReal = new ArraySegment<byte>(m_byteTemp);
|
||||
//Debug.Log($"Buffer = {m_byteTemp.Length} ; Segment = {byteReal.Count}");
|
||||
//复制到m_byteBuffer
|
||||
AddBuffer(e.RawData);
|
||||
//receiveCount += 1;
|
||||
}
|
||||
|
||||
public void Socket_OnClose(object sender, CloseEventArgs e)
|
||||
{
|
||||
m_bRun = false;
|
||||
Debug.Log(string.Format("Closed: StatusCode: {0}, Reason: {1}", e.StatusCode, e.Reason));
|
||||
}
|
||||
|
||||
public void Socket_OnError(object sender, ErrorEventArgs e)
|
||||
{
|
||||
m_bRun = false;
|
||||
Debug.Log(string.Format("Error: {0}", e.Message));
|
||||
}
|
||||
//public async void Connect(string addr, int port, Action<XWebSocket, string> callback)
|
||||
//{
|
||||
// m_wSocket = new ClientWebSocket();
|
||||
// m_Token = new CancellationToken();
|
||||
// Uri url = new Uri("wss://echo.websocket.events");//"ws://121.40.165.18:8800");// $"ws://{addr}:{port}/xxx/xxx");
|
||||
// Debug.Log($"CS Connect {url.ToString()}");
|
||||
// m_bufSegment = new ArraySegment<byte>(m_byteBuffer);
|
||||
// await m_wSocket.ConnectAsync(url, m_Token);
|
||||
// if (m_wSocket.State == WebSocketState.Open)
|
||||
// {
|
||||
// Debug.Log($"--------连接成功 : {url.ToString()}");
|
||||
// m_bRun = true;
|
||||
// callback(this, null);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.Log($"--------连接失败 : {url.ToString()}");
|
||||
// callback(this, $"Connect Error : {m_wSocket.State}");
|
||||
// }
|
||||
// while (m_bRun)
|
||||
// {
|
||||
// //var result = new byte[1024];
|
||||
// ArraySegment<byte> byteReal = new ArraySegment<byte>(m_byteTemp);
|
||||
// WebSocketReceiveResult result = await m_wSocket.ReceiveAsync(byteReal, new CancellationToken());//接受数据
|
||||
// Debug.Log($"Buffer = {m_byteTemp.Length} ; Segment = {byteReal.Count}");
|
||||
// //复制到m_byteBuffer
|
||||
// AddBuffer(byteReal);
|
||||
// //var str = Encoding.UTF8.GetString(m_byteTemp, 0, m_byteTemp.Length);
|
||||
// //Debug.Log(str);
|
||||
// }
|
||||
//}
|
||||
void AddBuffer(byte[] buffer)
|
||||
{
|
||||
lock (m_BufferLock)
|
||||
{
|
||||
if (m_bufCurPos + buffer.Length > m_byteBuffer.Length)
|
||||
{
|
||||
m_bufCurPos = 0;
|
||||
}
|
||||
Array.ConstrainedCopy(buffer, 0, m_byteBuffer, m_bufCurPos, buffer.Length);
|
||||
m_bufCurPos = m_bufCurPos + buffer.Length;
|
||||
m_bufSegment = new ArraySegment<byte>(m_byteBuffer, 0, m_bufCurPos);
|
||||
}
|
||||
}
|
||||
public byte[] GetBuffer()
|
||||
{
|
||||
lock (m_BufferLock)
|
||||
{
|
||||
return m_bufSegment.ToArray();
|
||||
}
|
||||
}
|
||||
public byte[] recv(ref string errorMsg)
|
||||
{
|
||||
if (!m_bRun)
|
||||
{//已经断线了
|
||||
errorMsg = null;
|
||||
Debug.Log($"net disconnected !");
|
||||
return null;
|
||||
}
|
||||
if (m_bufCurPos == 0)
|
||||
{//不需要获取数据
|
||||
errorMsg = "";
|
||||
return null;
|
||||
}
|
||||
byte[] retBuf;
|
||||
lock (m_BufferLock)
|
||||
{
|
||||
retBuf = m_bufSegment.ToArray();
|
||||
m_bufCurPos = 0;
|
||||
m_bufSegment = new ArraySegment<byte>(m_byteBuffer, 0, 0);
|
||||
}
|
||||
//Debug.Log($"c# recv: {retBuf.Length}");
|
||||
return retBuf;
|
||||
}
|
||||
public byte[] Recv(ref string errorMsg)
|
||||
{
|
||||
return recv(ref errorMsg);
|
||||
}
|
||||
|
||||
//async void SendAsync(byte[] sendData, Action<int, string> callback)
|
||||
//{
|
||||
//await m_wSocket.SendAsync(new ArraySegment<byte>(sendData), WebSocketMessageType.Binary, false, m_Token);
|
||||
//if (m_wSocket.State != WebSocketState.Open)
|
||||
//{
|
||||
// callback(0, null);
|
||||
//}
|
||||
//else
|
||||
// callback(sendData.Length, null);
|
||||
//}
|
||||
public int send(byte[] sendData, Action<int, string> callback, ref string errorMsg )
|
||||
{
|
||||
//Debug.Log($"c# send {sendData.Length}");加入了consoleWindows后不能再这里打印
|
||||
if (m_UseTcp)
|
||||
{
|
||||
int sent = 0;
|
||||
while (sent < sendData.Length)
|
||||
{
|
||||
sent += m_TcpSocket.Send(sendData, sent, sendData.Length - sent, SocketFlags.None);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_WebSocket.SendAsync(sendData);
|
||||
}
|
||||
errorMsg = null;
|
||||
return sendData.Length;
|
||||
}
|
||||
public int Send(byte[] sendData, Action<int, string> callback, ref string errorMsg)
|
||||
{
|
||||
return send(sendData, callback, ref errorMsg);
|
||||
}
|
||||
public void close()
|
||||
{
|
||||
m_bRun = false;
|
||||
if (m_UseTcp)
|
||||
{
|
||||
m_TcpSocket?.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_WebSocket.CloseAsync();
|
||||
}
|
||||
}
|
||||
public bool status(ref string errorMsg)
|
||||
{
|
||||
return m_bRun;
|
||||
}
|
||||
|
||||
public void settimeout(int timeout)
|
||||
{
|
||||
}
|
||||
|
||||
private void TcpReceiveLoop()
|
||||
{
|
||||
byte[] buffer = new byte[4096];
|
||||
while (m_bRun)
|
||||
{
|
||||
try
|
||||
{
|
||||
int count = m_TcpSocket.Receive(buffer);
|
||||
if (count <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
byte[] data = new byte[count];
|
||||
Array.ConstrainedCopy(buffer, 0, data, 0, count);
|
||||
AddBuffer(data);
|
||||
Debug.Log($"Tcp received {count} bytes");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (m_bRun)
|
||||
{
|
||||
Debug.Log($"Tcp receive error: {e.Message}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_bRun = false;
|
||||
}
|
||||
|
||||
/*
|
||||
private void WebSocketReceive(object sender, MessageEventArgs e)
|
||||
{
|
||||
//优化逻辑
|
||||
//heartTime = 0;
|
||||
receiveMsgTime = Time.realtimeSinceStartup;
|
||||
|
||||
if (e.IsText)
|
||||
{
|
||||
string[] temp = e.Data.Split('.');
|
||||
//发送接口需要返回的消息
|
||||
SocketCode socketCode = (SocketCode)int.Parse(temp[0]);
|
||||
if (msgResponseDic.ContainsKey(socketCode))
|
||||
{
|
||||
List<Action<string>> actions = msgResponseDic[socketCode];
|
||||
for (int i = 0; i < actions.Count; i++)
|
||||
{
|
||||
actions[i](temp[1]);
|
||||
}
|
||||
msgResponseDic.Remove(socketCode);
|
||||
}
|
||||
|
||||
if (msgListenerDic.ContainsKey(socketCode))
|
||||
{
|
||||
List<Action<string>> actions = msgListenerDic[socketCode];
|
||||
for (int i = 0; i < actions.Count; i++)
|
||||
{
|
||||
actions[i](temp[1]);
|
||||
}
|
||||
}
|
||||
Debug.LogError(string.Format("接收到消息: {0}", e.Data));
|
||||
}
|
||||
else if (e.IsBinary)
|
||||
{
|
||||
Debug.LogError(string.Format("接受到消息 Bytes ({1}): {0}", e.Data, e.RawData.Length));
|
||||
}
|
||||
}
|
||||
|
||||
private void WebSocketError(object sender, ErrorEventArgs e)
|
||||
{
|
||||
connected = false;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void WebSocketOpen(object sender, OpenEventArgs e)
|
||||
{
|
||||
reconnectCount = 0;
|
||||
receiveMsgTime = Time.realtimeSinceStartup;
|
||||
connected = true;
|
||||
Debug.LogError(string.Format("连接成功,IP:{0}", ip));
|
||||
}
|
||||
|
||||
private void WebSocketClose(object sender, CloseEventArgs e)
|
||||
{
|
||||
connected = false;
|
||||
Debug.LogError(string.Format("连接关闭: StatusCode: {0}, Reason: {1}", e.StatusCode, e.Reason));
|
||||
}//*/
|
||||
}
|
||||
public class lsocket : MonoBehaviour
|
||||
{
|
||||
//private WebSocket m_wSocket = new WebSocket();
|
||||
public lsocket Instance;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
public static float gettime()
|
||||
{
|
||||
return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;
|
||||
}
|
||||
//外部接口
|
||||
public static void connect(string addr, int port, Action<XWebSocket, string> callback )
|
||||
{
|
||||
XWebSocket socket = new XWebSocket();
|
||||
|
||||
bool forceTcp = false;
|
||||
if (addr.StartsWith("http://"))
|
||||
addr = addr.Substring("http://".Length);
|
||||
else if (addr.StartsWith("https://"))
|
||||
addr = addr.Substring("https://".Length);
|
||||
else if (addr.StartsWith("tcp://"))
|
||||
{
|
||||
addr = addr.Substring("tcp://".Length);
|
||||
forceTcp = true;
|
||||
}
|
||||
|
||||
if (!addr.StartsWith("ws://") && !addr.StartsWith("wss://"))
|
||||
{
|
||||
int slash = addr.IndexOf("/");
|
||||
if (slash >= 0)
|
||||
addr = addr.Substring(0, slash);
|
||||
string host = addr;
|
||||
int tcpPort = port;
|
||||
int colon = addr.LastIndexOf(":");
|
||||
if (colon >= 0)
|
||||
{
|
||||
host = addr.Substring(0, colon);
|
||||
int.TryParse(addr.Substring(colon + 1), out tcpPort);
|
||||
}
|
||||
if (forceTcp || host == "localhost" || host == "127.0.0.1" || tcpPort == 7777 || tcpPort == 7788)
|
||||
{
|
||||
Debug.Log($"C# Connect tcp://{host}:{tcpPort}");
|
||||
socket.ConnectTcp(host, tcpPort, callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr.StartsWith("ws://") || addr.StartsWith("wss://"))
|
||||
{
|
||||
if (port != 0)
|
||||
addr = $"{addr}:{port}";
|
||||
Debug.Log($"C# Connect {addr}");
|
||||
socket.Connect(addr, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
//socket.Connect(addr, port, callback);
|
||||
//if (port != 0)
|
||||
int pos = addr.IndexOf(":");
|
||||
string str;
|
||||
if (pos == -1)
|
||||
str = addr;
|
||||
else
|
||||
str = addr.Substring(0, pos);
|
||||
string regexStrIPV4 = (@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
|
||||
if (Regex.IsMatch(str, regexStrIPV4) && addr != "0.0.0.0")
|
||||
{//ip用ws
|
||||
addr = $"ws://{addr}";
|
||||
}
|
||||
else
|
||||
{//域名的用wss
|
||||
addr = $"wss://{addr}";
|
||||
if (port != 0)
|
||||
port += 2000;//wss连接的端口规则
|
||||
}
|
||||
// if (!addr.StartsWith("wss://") && !addr.StartsWith("ws://"))
|
||||
// {
|
||||
|
||||
//#if UNITY_EDITOR
|
||||
// addr = $"ws://{addr}";
|
||||
//#else
|
||||
// if(!LoadDll.m_bInWX)
|
||||
// {
|
||||
// addr = $"wss://{addr}";
|
||||
// if(port != 0)
|
||||
// port += 2000;//wss连接的端口规则
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// addr = $"wss://{addr}";
|
||||
// if(port != 0)
|
||||
// port += 2000;//wss连接的端口规则
|
||||
// }
|
||||
//#endif
|
||||
// //addr = $"ws://{addr}";
|
||||
// }
|
||||
|
||||
if (port != 0)
|
||||
addr = $"{addr}:{port}";
|
||||
//addr = "wss://g7h5.guangyv.com:4201";
|
||||
Debug.Log($"C# Connect {addr}");
|
||||
socket.Connect(addr, callback);
|
||||
}
|
||||
|
||||
|
||||
//传入多个WebSocket引用,返回有数据处理的, dataSize为零就不需要处理
|
||||
public static XWebSocket[] select(XWebSocket[] readSockets, XWebSocket[] writeSockets, int Param, ref XWebSocket[] retWriteSockets, ref int dataSize)
|
||||
{
|
||||
List<XWebSocket> retReadSockets = new List<XWebSocket>();
|
||||
string error = null;
|
||||
bool bOK = true;
|
||||
dataSize = 0;
|
||||
for (int i = 0; i < readSockets.Length; ++i)
|
||||
{
|
||||
if (!readSockets[i].status(ref error))
|
||||
{
|
||||
bOK = false;
|
||||
break;
|
||||
}
|
||||
int recvSize = readSockets[i].GetRecvSize();
|
||||
if (recvSize > 0)
|
||||
{
|
||||
retReadSockets.Add(readSockets[i]);
|
||||
dataSize += recvSize;
|
||||
}
|
||||
}
|
||||
if (!bOK)
|
||||
return null;
|
||||
retWriteSockets = writeSockets;
|
||||
return retReadSockets.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
public class WebSocketLogic : MonoBehaviour
|
||||
{
|
||||
|
||||
public async void WebSocket()
|
||||
{
|
||||
try
|
||||
{
|
||||
ClientWebSocket ws = new ClientWebSocket();
|
||||
CancellationToken ct = new CancellationToken();
|
||||
//添加header
|
||||
//ws.Options.SetRequestHeader("X-Token", "eyJhbGciOiJIUzI1N");
|
||||
Uri url = new Uri("ws://121.40.165.18:8800/v1/test/test");
|
||||
await ws.ConnectAsync(url, ct);
|
||||
await ws.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes("hello")), WebSocketMessageType.Binary, true, ct); //发送数据
|
||||
while (true)
|
||||
{
|
||||
var result = new byte[1024];
|
||||
await ws.ReceiveAsync(new ArraySegment(result), new CancellationToken());//接受数据
|
||||
var str = Encoding.UTF8.GetString(result, 0, result.Length);
|
||||
Debug.Log(str);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private WebSocketLogic() { }
|
||||
private WebSocketLogic _instance;
|
||||
|
||||
|
||||
public WebSocketLogic Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new WebSocketLogic();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
private set { }
|
||||
}
|
||||
|
||||
WebSocket webSocket;
|
||||
string ip;
|
||||
|
||||
public void Init(string _ip)
|
||||
{
|
||||
inited = true;
|
||||
ip = _ip;
|
||||
}
|
||||
|
||||
public void Connect()
|
||||
{
|
||||
RemoveHandle();
|
||||
webSocket = new WebSocket(ip);
|
||||
webSocket.OnClose += WebSocketClose;
|
||||
webSocket.OnOpen += WebSocketOpen;
|
||||
webSocket.OnError += WebSocketError;
|
||||
webSocket.OnMessage += WebSocketReceive;
|
||||
webSocket.ConnectAsync();
|
||||
}
|
||||
|
||||
public void AddListener(SocketCode socketCode, Action<string> callback)
|
||||
{
|
||||
if (msgListenerDic.ContainsKey(socketCode))
|
||||
{
|
||||
List<Action<string>> actions = msgListenerDic[socketCode];
|
||||
for (int i = 0; i < actions.Count; i++)
|
||||
{
|
||||
if (actions[i] == callback)
|
||||
{
|
||||
Debug.LogError("重复注册监听,消息号:" + socketCode);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
msgListenerDic[socketCode].Add(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Action<string>> actions = new List<Action<string>>();
|
||||
actions.Add(callback);
|
||||
msgListenerDic.Add(socketCode, actions);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveListener(SocketCode socketCode, Action<string> callback)
|
||||
{
|
||||
if (msgListenerDic.ContainsKey(socketCode))
|
||||
{
|
||||
List<Action<string>> actions = msgListenerDic[socketCode];
|
||||
for (int i = 0; i < actions.Count; i++)
|
||||
{
|
||||
if (actions[i] == callback)
|
||||
{
|
||||
actions.RemoveAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Debug.LogError("移除监听出错,未包注册监听消息函数,消息号:" + socketCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("移除监听出错,未包注册监听,消息号:" + socketCode);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveHandle()
|
||||
{
|
||||
msgResponseDic.Clear();
|
||||
webSocket = null;
|
||||
webSocket.OnClose -= WebSocketClose;
|
||||
webSocket.OnOpen -= WebSocketOpen;
|
||||
webSocket.OnError -= WebSocketError;
|
||||
webSocket.OnMessage -= WebSocketReceive;
|
||||
}
|
||||
|
||||
|
||||
public void Send(SocketCode socketCode, string msg, Action<string> callback)
|
||||
{
|
||||
if (callback != null)
|
||||
{
|
||||
if (msgResponseDic.ContainsKey(socketCode))
|
||||
{
|
||||
msgResponseDic[socketCode].Add(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Action<string>> actions = new List<Action<string>>();
|
||||
actions.Add(callback);
|
||||
msgResponseDic.Add(socketCode, actions);
|
||||
}
|
||||
}
|
||||
webSocket.SendAsync(string.Format("{0}/{1}", socketCode, msg));
|
||||
}
|
||||
|
||||
|
||||
private void WebSocketReceive(object sender, MessageEventArgs e)
|
||||
{
|
||||
//优化逻辑
|
||||
//heartTime = 0;
|
||||
receiveMsgTime = Time.realtimeSinceStartup;
|
||||
|
||||
if (e.IsText)
|
||||
{
|
||||
string[] temp = e.Data.Split('.');
|
||||
//发送接口需要返回的消息
|
||||
SocketCode socketCode = (SocketCode)int.Parse(temp[0]);
|
||||
if (msgResponseDic.ContainsKey(socketCode))
|
||||
{
|
||||
List<Action<string>> actions = msgResponseDic[socketCode];
|
||||
for (int i = 0; i < actions.Count; i++)
|
||||
{
|
||||
actions[i](temp[1]);
|
||||
}
|
||||
msgResponseDic.Remove(socketCode);
|
||||
}
|
||||
|
||||
if (msgListenerDic.ContainsKey(socketCode))
|
||||
{
|
||||
List<Action<string>> actions = msgListenerDic[socketCode];
|
||||
for (int i = 0; i < actions.Count; i++)
|
||||
{
|
||||
actions[i](temp[1]);
|
||||
}
|
||||
}
|
||||
Debug.LogError(string.Format("接收到消息: {0}", e.Data));
|
||||
}
|
||||
else if (e.IsBinary)
|
||||
{
|
||||
Debug.LogError(string.Format("接受到消息 Bytes ({1}): {0}", e.Data, e.RawData.Length));
|
||||
}
|
||||
}
|
||||
|
||||
private void WebSocketError(object sender, ErrorEventArgs e)
|
||||
{
|
||||
connected = false;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void WebSocketOpen(object sender, OpenEventArgs e)
|
||||
{
|
||||
reconnectCount = 0;
|
||||
receiveMsgTime = Time.realtimeSinceStartup;
|
||||
connected = true;
|
||||
Debug.LogError(string.Format("连接成功,IP:{0}", ip));
|
||||
}
|
||||
|
||||
private void WebSocketClose(object sender, CloseEventArgs e)
|
||||
{
|
||||
connected = false;
|
||||
Debug.LogError(string.Format("连接关闭: StatusCode: {0}, Reason: {1}", e.StatusCode, e.Reason));
|
||||
}
|
||||
|
||||
|
||||
float heartTime = 0;
|
||||
float receiveMsgTime = 0;
|
||||
float reconnectCount = 0;
|
||||
private void Update()
|
||||
{
|
||||
if (!inited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
heartTime = heartTime + Time.deltaTime;
|
||||
if (heartTime >= 5.0f && connected == true)
|
||||
{
|
||||
heartTime = 0.0f;
|
||||
Send(SocketCode.Heart, "heartbeat", null);
|
||||
}
|
||||
if (receiveMsgTime != 0 && Time.realtimeSinceStartup - receiveMsgTime > 6.0f)
|
||||
{
|
||||
if (reconnectCount > 5)
|
||||
{
|
||||
Debug.LogError("重新连接失败!");
|
||||
return;
|
||||
}
|
||||
receiveMsgTime = Time.realtimeSinceStartup;
|
||||
connected = false;
|
||||
webSocket.CloseAsync();
|
||||
Connect();
|
||||
reconnectCount = reconnectCount + 1;
|
||||
Debug.LogError(string.Format("连接断开,尝试第{0}次重新连接!", reconnectCount));
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
connected = false;
|
||||
inited = false;
|
||||
msgResponseDic.Clear();
|
||||
msgListenerDic.Clear();
|
||||
}
|
||||
}//*/
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c5dd4f573cd35648b6e164cc3ec5b8d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user