using UnityEngine; using LuaFramework; using BestHTTP; using BestHTTP.WebSocket; using System; using System.Collections.Generic; using Google.Protobuf; 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> events = new Queue>(); public F6.MsgHandler msgHandler = new F6.MsgHandler(typeof(battle.cs.CMMessageId_e), typeof(battle.cs.SMMessageId_e)); 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 void SendMsg(T msg) where T : IMessage { try { int msgId = this.msgHandler.GetCMMsgId(typeof(T)); 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) { 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(type, args)); } } void Update() { lock (this.lockObj) { while (this.events.Count > 0) { this.DispatchEvent(this.events.Dequeue()); } } } private void ParsePkt(byte[] data) { data.CopyTo(this.recvBuf, this.recvBufLen); this.recvBufLen += data.Length; while (this.recvBufLen >= 12) { ushort packLen = C6.Utils.ReadU16Le(this.recvBuf, 0); ushort msgId = C6.Utils.ReadU16Le(this.recvBuf, 2); uint seqId = C6.Utils.ReadU32Le(this.recvBuf, 4); ushort magicCode = C6.Utils.ReadU16Le(this.recvBuf, 8); ushort extLen = C6.Utils.ReadU16Le(this.recvBuf, 10); if (packLen + 12 > this.recvBufLen) { break; } this.msgHandler.DispatchMsg(msgId, this.recvBuf, 12, packLen); for (int i = packLen + 12; i < this.recvBufLen; ++i) { this.recvBuf[i - (packLen + 12)] = this.recvBuf[i]; } this.recvBufLen -= 12 + packLen; } } private void DispatchEvent(KeyValuePair 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: { this.ParsePkt((byte[])e.Value[0]); } break; } } } }