cfclient/Net/ClientNet.cs
2024-05-21 08:44:08 +08:00

194 lines
5.7 KiB
C#

using UnityEngine;
using LuaFramework;
using BestHTTP;
using BestHTTP.WebSocket;
using System;
using System.Collections.Generic;
using Google.Protobuf;
using pbr = global::Google.Protobuf.Reflection;
namespace Net
{
public delegate void OnNetOpen(ClientNet conn);
public delegate void OnNetError(ClientNet conn);
public delegate void OnNetClosed(ClientNet conn);
public class ClientNet : MonoBehaviour
{
enum EventType
{
Open,
Error,
Closed,
Read
}
private string uri;
private WebSocket ws;
private byte[] recvBuf = new byte[1024 * 64 * 3];
private int recvBufLen = 0;
public OnNetOpen OnOpen;
public OnNetError OnError;
public OnNetClosed OnClosed;
private readonly object lockObj = new object();
private Queue<KeyValuePair<EventType, object[]>> events = new Queue<KeyValuePair<EventType, object[]>>();
public void Init(string uri)
{
this.ws = new WebSocket(new Uri(uri));
this.ws.OnOpen += this.OnWsOpen;
this.ws.OnBinary += this.OnWsBinaryReceived;
this.ws.OnError += this.OnWsError;
this.ws.OnClosed += this.OnWsClosed;
}
public void Open()
{
this.ws.Open();
}
public int GetCMMsgId(string msgName)
{
return this.GetPbMsgId(typeof(battle.cs.CMMessageId_e), "_" + msgName);
}
public int GetSMMsgId(string msgName)
{
return this.GetPbMsgId(typeof(battle.cs.SMMessageId_e), "_" + msgName);
}
private int GetPbMsgId(Type enumType,string msgName)
{
foreach (var f in enumType.GetFields())
{
var tAttrs = f.GetCustomAttributes(typeof(pbr::OriginalNameAttribute), false);
if (tAttrs.Length > 0)
{
var tAttr = (pbr::OriginalNameAttribute)tAttrs[0];
if (tAttr.Name.Equals(msgName))
{
var val = Enum.Parse(enumType, f.Name);
return Convert.ToInt32(val);
}
}
}
return 0;
}
public void SendMsg<T>(T msg) where T : IMessage<T>
{
try
{
int msgId = this.GetCMMsgId(typeof(T).Name);
int packLen = msg.CalculateSize();
const int magicCode = 21323;
byte[] data = new byte[12 + packLen];
data[0] = (byte)(packLen & 0xFF);
data[1] = (byte)((packLen & 0xFFFF) >> 8);
data[2] = (byte)(msgId & 0xFF);
data[3] = (byte)((msgId & 0xFFFF) >> 8);
data[4] = 0;
data[5] = 0;
data[6] = 0;
data[7] = 0;
data[8] = (byte)(magicCode & 0xFF);
data[9] = (byte)((magicCode & 0xFFFF) >> 8);
data[10] = 0;
data[11] = 0;
msg.ToByteArray().CopyTo(data, 12);
this.ws.Send(data);
}catch(Exception e)
{
int i = 0;
}
}
private void OnWsOpen(WebSocket ws)
{
Debug.Log("ClientNet.OnOpen");
this.AddEvent(EventType.Open, null);
}
private void OnWsBinaryReceived(WebSocket ws, byte[] data)
{
Debug.Log("ClientNet.OnBinaryReceived");
this.AddEvent(EventType.Read, new object[]{data.Clone()});
}
private void OnWsError(WebSocket ws, string reason)
{
Debug.Log("ClientNet.OnError");
this.AddEvent(EventType.Error, null);
}
private void OnWsClosed(WebSocket ws, UInt16 code, string message)
{
Debug.Log("ClientNet.OnClosed");
this.AddEvent(EventType.Closed, null);
}
private void AddEvent(EventType type, object[] args)
{
lock (this.lockObj)
{
this.events.Enqueue(new KeyValuePair<EventType, object[]>(type, args));
}
}
void Update()
{
lock (this.lockObj)
{
while (this.events.Count > 0)
{
this.DispatchEvent(this.events.Dequeue());
}
}
}
private void DispatchEvent(KeyValuePair<EventType, object[]> e)
{
switch (e.Key)
{
case EventType.Open:
{
if (this.OnOpen != null)
{
this.OnOpen(this);
}
}
break;
case EventType.Error:
{
if (this.OnError != null)
{
this.OnError(this);
}
}
break;
case EventType.Closed:
{
if (this.OnClosed != null)
{
this.OnClosed(this);
}
}
break;
case EventType.Read:
{
}
break;
}
}
void Awake()
{
int i = 0;
}
}
}