182 lines
5.7 KiB
C#
182 lines
5.7 KiB
C#
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<KeyValuePair<EventType, object[]>> events = new Queue<KeyValuePair<EventType, object[]>>();
|
|
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>(T msg) where T : IMessage<T>
|
|
{
|
|
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<EventType, object[]>(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<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:
|
|
{
|
|
this.ParsePkt((byte[])e.Value[0]);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|