- LocalizationManager: 新增翻译表(SetFormatted/SetDuration/LocalizeOperateMsg) - LoginPanel: InputField placeholder本地化、字体颜色保持 - HistoryPanel: 用时数据本地化、placeholder本地化 - RecordDetailPanel: 操作详情消息本地化(LanguageChanged重建) - AppraiseWindowBase: 评价等级本地化、操作消息重建 - EditorAppraiser: 所有评估消息改用InjectOperateMsgLocalized - StudentOperateRecorder: 新增InjectOperateMsgLocalized方法 - LocalizationLanguageTestBar: 单例模式、ScreenSpaceOverlay筛选 - 字体切换时保留颜色和verticalOverflow
205 lines
5.8 KiB
C#
205 lines
5.8 KiB
C#
using UnityEngine;
|
|
using System.Net.Sockets;
|
|
using System;
|
|
using System.Linq;
|
|
using System.IO;
|
|
using XFramework.NetOuter;
|
|
using UnityEngine.Events;
|
|
using System.Collections.Generic;
|
|
|
|
public class TcpClient {
|
|
ProtocolBase protocol=new ProtocolByte();
|
|
string path="";
|
|
// public string serverMess="";
|
|
public Socket socket;
|
|
public const int bufferSize=16384;//最大可缓存16kb 的数据
|
|
int bufferCount = 0;
|
|
byte[] readBuffer = new byte[bufferSize];
|
|
byte[] lenbytes=new byte[sizeof(Int32)];
|
|
Int32 msgLength;
|
|
//string GetConnState;
|
|
private MsgDistribution msgDis = new MsgDistribution();
|
|
string address="";
|
|
int port=0;
|
|
float timer;
|
|
float heatBeatTime=5;
|
|
|
|
/// <summary>
|
|
/// 连接状态变化
|
|
/// </summary>
|
|
event UnityAction<bool> ConnectChanged;
|
|
|
|
Queue<bool> changedQueue = new Queue<bool>();//记录支线程 网络状态变化
|
|
public TcpClient(UnityAction<bool> ConnectChanged = null)
|
|
{
|
|
this.ConnectChanged += ConnectChanged;
|
|
ReadConfig();
|
|
AddListener();
|
|
ConnectServer();
|
|
}
|
|
|
|
// Mono类代为调用
|
|
public void ExtractingMsg()
|
|
{
|
|
msgDis.Distribution();
|
|
timer += Time.deltaTime;
|
|
if (timer > heatBeatTime)
|
|
{
|
|
HeatBeat();
|
|
timer = 0;
|
|
}
|
|
if (changedQueue.Count > 0)
|
|
{
|
|
ConnectChanged?.Invoke(changedQueue.Dequeue());
|
|
}
|
|
}
|
|
|
|
//连接到服务器
|
|
private void ConnectServer()
|
|
{
|
|
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
socket.BeginConnect(address, port, ReceiveConn, null);
|
|
//Debug.Log($"尝试建立连接{address}:{port}");
|
|
}
|
|
|
|
private void ReceiveConn(IAsyncResult ar)
|
|
{
|
|
if (socket.Connected)
|
|
{
|
|
socket.BeginReceive(readBuffer, 0, bufferSize, SocketFlags.None, ReceiveCb, null);
|
|
changedQueue.Enqueue(true);
|
|
}
|
|
}
|
|
|
|
//读取配置文件获取IP和端口
|
|
private void ReadConfig()
|
|
{
|
|
path = Application.streamingAssetsPath + "/TcpConfig/ServerAdress.txt";
|
|
if (File.Exists(path))
|
|
{
|
|
string[] config = File.ReadAllText(path, System.Text.Encoding.UTF8).Split(',');
|
|
if (config.Length >= 2)
|
|
{
|
|
address = config[0].Trim();
|
|
port = int.Parse(config[1].Trim());
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("config is error");
|
|
}
|
|
}
|
|
}
|
|
|
|
//添加监听消息事件
|
|
void AddListener()
|
|
{
|
|
msgDis.AddListener(NetMsgName.LoginResult.ToString(), new TCPLoginResultExcute());
|
|
msgDis.AddListener(NetMsgName.Subject.ToString(), new TCPSubExcute());
|
|
msgDis.AddListener(NetMsgName.AdjustingToStu.ToString(), new TCPAdjustingToStuExcute());
|
|
msgDis.AddListener(NetMsgName.AddOrRmoveTufa.ToString(), new TCPAddOrRmoveTufaExcute());
|
|
msgDis.AddListener(NetMsgName.AppraiseResult.ToString(), new TCPAppraiseResultExcute());
|
|
msgDis.AddListener(NetMsgName.GroupUserBreak.ToString(), new UserDiscExcute());//掉线处理逻辑
|
|
}
|
|
|
|
//接收信息的回调
|
|
private void ReceiveCb(IAsyncResult ar)
|
|
{
|
|
try
|
|
{
|
|
int count = socket.EndReceive(ar);
|
|
bufferCount += count;
|
|
ProcessData();
|
|
socket.BeginReceive(readBuffer, bufferCount, bufferSize- bufferCount, SocketFlags.None, ReceiveCb, null);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.Log(e.Message+"接收消息失败,断开连接");
|
|
changedQueue.Enqueue(false);
|
|
socket.Close();
|
|
}
|
|
}
|
|
|
|
//验证信息完整程度并删除处理完成的信息
|
|
private void ProcessData()
|
|
{
|
|
if (bufferCount < sizeof(Int32))
|
|
return;
|
|
Array.Copy(readBuffer,lenbytes,sizeof(Int32));
|
|
msgLength = BitConverter.ToInt32(lenbytes,0);
|
|
if (msgLength < 0)
|
|
{
|
|
Debug.Log("ReadBuffer解析数据长度解析有误");
|
|
return;
|
|
}
|
|
|
|
if (msgLength > bufferSize)
|
|
{
|
|
Debug.Log("ReadBuffer数据长度超出缓存空间");
|
|
return;
|
|
}
|
|
if (bufferCount < sizeof(Int32) + msgLength)
|
|
return;
|
|
ProtocolByte proto = (ProtocolByte)protocol.Decode(readBuffer, sizeof(Int32), msgLength);
|
|
//HandleMsg(proto);
|
|
ExcuteParam excute = new ExcuteParam(address,proto.GetProtocolName(), proto);
|
|
msgDis.Enqueue(excute);
|
|
int count = bufferCount - sizeof(Int32) - msgLength;
|
|
Array.Copy(readBuffer,sizeof(Int32)+msgLength,readBuffer,0,count);
|
|
bufferCount = count;
|
|
if (bufferCount > 0)
|
|
ProcessData();
|
|
}
|
|
//发送位置信息
|
|
|
|
|
|
//发送传输协议到服务器
|
|
public void Send(ProtocolBase proto)
|
|
{
|
|
byte[] bytes = proto.Encode();
|
|
byte[] length = BitConverter.GetBytes(bytes.Length);
|
|
byte[] sendBytes = length.Concat(bytes).ToArray();
|
|
try
|
|
{
|
|
socket.Send(sendBytes);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//Debug.Log("接收消息失败,断开连接");
|
|
socket.Close();
|
|
}
|
|
}
|
|
|
|
//心跳
|
|
void HeatBeat()
|
|
{
|
|
//Debug.Log(connIsRight);
|
|
if (socket.Connected)
|
|
{
|
|
ProtocolByte protoco = new ProtocolByte();
|
|
protoco.AddString("HeatBeat");
|
|
Send(protoco);
|
|
}
|
|
else
|
|
{
|
|
ConnectServer();
|
|
}
|
|
}
|
|
|
|
//关闭连接
|
|
public bool Close()
|
|
{
|
|
try
|
|
{
|
|
socket.Close();
|
|
ConnectChanged?.Invoke(false);
|
|
return true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.Log("关闭失败:"+e.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
}
|