797 lines
23 KiB
C#
797 lines
23 KiB
C#
using UnityEngine;
|
||
using System;
|
||
using System.IO;
|
||
using System.Net;
|
||
using System.Net.Sockets;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using GameLogic;
|
||
using System.Text;
|
||
using LuaInterface;
|
||
//using System.Runtime.InteropServices;
|
||
|
||
public enum NetworkStateType
|
||
{
|
||
Connected,
|
||
ConnectFail,
|
||
Reconnected,
|
||
ReconnectFail,
|
||
Exception,
|
||
Disconnect,
|
||
}
|
||
|
||
static class IPAddressExtensions
|
||
{
|
||
public static IPAddress MapToIPv6(this IPAddress addr)
|
||
{
|
||
if (addr.AddressFamily != AddressFamily.InterNetwork)
|
||
throw new ArgumentException("Must pass an IPv4 address to MapToIPv6");
|
||
|
||
string ipv4str = addr.ToString();
|
||
|
||
return IPAddress.Parse("::ffff:" + ipv4str);
|
||
}
|
||
|
||
public static bool IsIPv4MappedToIPv6(this IPAddress addr)
|
||
{
|
||
bool pass1 = addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6, pass2;
|
||
|
||
try
|
||
{
|
||
pass2 = (addr.ToString().StartsWith("0000:0000:0000:0000:0000:ffff:") ||
|
||
addr.ToString().StartsWith("0:0:0:0:0:ffff:") ||
|
||
addr.ToString().StartsWith("::ffff:")) &&
|
||
IPAddress.Parse(addr.ToString().Substring(addr.ToString().LastIndexOf(":") + 1)).AddressFamily == AddressFamily.InterNetwork;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return pass1 && pass2;
|
||
}
|
||
}
|
||
|
||
public class SocketClient
|
||
{
|
||
public NetworkManager netMgr;
|
||
private TcpClient client = null;
|
||
private NetworkStream outStream = null;
|
||
private MemoryStream _memStream;
|
||
public MemoryStream CurMemoryStream
|
||
{
|
||
get
|
||
{
|
||
if (_memStream == null)
|
||
_memStream = new MemoryStream();
|
||
|
||
return _memStream;
|
||
}
|
||
}
|
||
|
||
private BinaryReader _reader;
|
||
public BinaryReader CurReader
|
||
{
|
||
get
|
||
{
|
||
if (_reader == null)
|
||
_reader = new BinaryReader(_memStream);
|
||
|
||
return _reader;
|
||
}
|
||
}
|
||
|
||
static readonly int HeaderSize= sizeof(ushort)+sizeof(int);
|
||
private const int MAX_READ = 8192;
|
||
private byte[] byteBuffer = new byte[MAX_READ];
|
||
static TEA crypto = new TEA();
|
||
|
||
Queue<NetMsg> mEvents = new Queue<NetMsg>();
|
||
Stack<NetworkStateInfo> stateInfoStack = new Stack<NetworkStateInfo>();
|
||
Dictionary<int, IDispatcher> dispatchers = new Dictionary<int, IDispatcher>();
|
||
Dictionary<int, IDispatcher> callbacks = new Dictionary<int, IDispatcher>();
|
||
|
||
int m_serialId;
|
||
int m_indicationSid;
|
||
bool m_isConnected = false;
|
||
bool m_isConnecting = false;
|
||
|
||
private const int INDICATION_RESPONSE = 10046;
|
||
private const int INDICATION_ERROR_CODE = 10400;
|
||
|
||
public string IpAddress { get; private set; }
|
||
public int Port { get; private set; }
|
||
|
||
// Use this for initialization
|
||
public SocketClient(string ipAddress, int port)
|
||
{
|
||
IpAddress = ipAddress;
|
||
Port = port;
|
||
_memStream = new MemoryStream();
|
||
_reader = new BinaryReader(_memStream);
|
||
|
||
Debug.Log("SocketClient SocketClient ipAddress: " + ipAddress + " port: " + port);
|
||
}
|
||
|
||
public void SetIpAddress(string ipAddress, int port)
|
||
{
|
||
Debug.Log("SocketClient SetIpAddress ipAddress: " + ipAddress + " port: " + port);
|
||
if (!IsConnected())
|
||
{
|
||
IpAddress = ipAddress;
|
||
Port = port;
|
||
m_indicationSid = 0;
|
||
m_serialId = 1;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 连接服务器
|
||
/// </summary>
|
||
public void Connect()
|
||
{
|
||
Close();
|
||
Debug.Log("SocketClient Connect ipAddress: " + IpAddress);
|
||
try
|
||
{
|
||
var ipType = GetIPAddressType(IpAddress);
|
||
client = null;
|
||
client = new TcpClient(ipType);
|
||
client.SendTimeout = 1000;
|
||
client.ReceiveTimeout = 1000;
|
||
client.NoDelay = true;
|
||
client.BeginConnect(IpAddress, Port, new AsyncCallback(OnConnect), null);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
OnConnectFail();
|
||
Debug.LogError("SocketClient Connect catch: " + e.Message);
|
||
}
|
||
}
|
||
|
||
public void OnConnectFail()
|
||
{
|
||
AddStateInfo(NetworkStateType.ConnectFail, "OnConnectFail");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 连接上服务器
|
||
/// </summary>
|
||
void OnConnect(IAsyncResult asr)
|
||
{
|
||
Debug.LogError("SocketClient OnConnect");
|
||
outStream = client.GetStream();
|
||
client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
|
||
AddStateInfo(NetworkStateType.Connected, "OnConnect");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写数据
|
||
/// </summary>
|
||
void WriteMessage(byte[] message)
|
||
{
|
||
MemoryStream ms = null;
|
||
using (ms = new MemoryStream())
|
||
{
|
||
ms.Position = 0;
|
||
|
||
BinaryWriter writer = new BinaryWriter(ms);
|
||
short msglen = (short)message.Length;
|
||
|
||
msglen = IPAddress.HostToNetworkOrder(msglen);
|
||
|
||
byte[] tempBuffer = new byte[message.Length];
|
||
Buffer.BlockCopy(message, 0, tempBuffer, 0, message.Length);
|
||
|
||
if (crypto != null)
|
||
tempBuffer = crypto.Encode(tempBuffer);
|
||
|
||
writer.Write(tempBuffer);
|
||
writer.Flush();
|
||
if (client != null && client.Connected)
|
||
{
|
||
//NetworkStream stream = client.GetStream();
|
||
byte[] payload = ms.ToArray();
|
||
outStream.BeginWrite(payload, 0, payload.Length, new AsyncCallback(OnWrite), ms);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("SocketClient WriteMessage !connected");
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 读取消息
|
||
/// </summary>
|
||
void OnRead(IAsyncResult asr)
|
||
{
|
||
int bytesRead = 0;
|
||
//try
|
||
{
|
||
lock (client.GetStream())
|
||
{
|
||
//读取字节流到缓冲区
|
||
bytesRead = client.GetStream().EndRead(asr);
|
||
}
|
||
|
||
if (bytesRead < 1)
|
||
{
|
||
//包尺寸有问题,断线处理
|
||
AddStateInfo(NetworkStateType.Disconnect, "bytesRead < 1");
|
||
return;
|
||
}
|
||
OnReceive(byteBuffer, bytesRead); //分析数据包内容,抛给逻辑层
|
||
lock (client.GetStream())
|
||
{
|
||
//分析完,再次监听服务器发过来的新消息
|
||
Array.Clear(byteBuffer, 0, byteBuffer.Length); //清空数组
|
||
client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
|
||
}
|
||
}
|
||
//catch (Exception ex)
|
||
//{
|
||
// //PrintBytes();
|
||
// AddStateInfo(NetworkStateType.Exception, ex.Message);
|
||
//}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 丢失链接
|
||
/// </summary>
|
||
public void AddStateInfo(NetworkStateType dis, string msg)
|
||
{
|
||
NetworkStateInfo info = new NetworkStateInfo();
|
||
info.type = dis;
|
||
info.msg = msg;
|
||
stateInfoStack.Push(info);
|
||
Debug.Log("SocketClient AddStateInfo dis: " + dis + " msg: " + msg);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打印字节
|
||
/// </summary>
|
||
/// <param name="bytes"></param>
|
||
void PrintBytes()
|
||
{
|
||
string returnStr = string.Empty;
|
||
for (int i = 0; i < byteBuffer.Length; i++)
|
||
{
|
||
returnStr += byteBuffer[i].ToString("X2");
|
||
}
|
||
Debug.LogError("SocketClient PrintBytes Str: " + returnStr);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 向链接写入数据流
|
||
/// </summary>
|
||
void OnWrite(IAsyncResult r)
|
||
{
|
||
try
|
||
{
|
||
MemoryStream stream = (MemoryStream)r.AsyncState;
|
||
outStream.EndWrite(r);
|
||
if(stream!=null)
|
||
{
|
||
stream.Close();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.LogError("SocketClient OnWrite catch: " + ex.Message.ToString());
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 接收到消息
|
||
/// </summary>
|
||
void OnReceive(byte[] bytes, int length)
|
||
{
|
||
try
|
||
{
|
||
var stream = CurMemoryStream;
|
||
var reader = CurReader;
|
||
|
||
stream.Seek(0, SeekOrigin.End);
|
||
stream.Write(bytes, 0, length);
|
||
//Reset to beginning
|
||
stream.Seek(0, SeekOrigin.Begin);
|
||
|
||
while (RemainingBytes() > 4)
|
||
{
|
||
short messageLen = reader.ReadInt16();
|
||
messageLen = IPAddress.NetworkToHostOrder(messageLen);
|
||
//memStream.Seek(0, SeekOrigin.Begin);
|
||
//TEA解密需要补齐8位
|
||
int decodeMessageLen = (messageLen + 7) / 8 * 8;
|
||
if (RemainingBytes() >= decodeMessageLen) //粘包处理
|
||
{
|
||
var msgBytes = reader.ReadBytes(decodeMessageLen);
|
||
if (crypto != null)
|
||
msgBytes = crypto.Decode(msgBytes, messageLen);
|
||
OnReceivedMessage(new ByteBuffer(msgBytes));
|
||
}
|
||
else
|
||
{
|
||
//Back up the position two bytes
|
||
stream.Position = stream.Position - 2;
|
||
break;
|
||
}
|
||
}
|
||
//Create a new stream with any leftover bytes
|
||
byte[] leftover = reader.ReadBytes((int)RemainingBytes());
|
||
stream.SetLength(0); //Clear
|
||
stream.Write(leftover, 0, leftover.Length);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError("SocketClient OnReceive catch: " + e.ToString());
|
||
AddStateInfo(NetworkStateType.Disconnect, "Network Read Exception: " + e.ToString());
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 剩余的字节
|
||
/// </summary>
|
||
private long RemainingBytes()
|
||
{
|
||
return CurMemoryStream.Length - CurMemoryStream.Position;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 接收到消息
|
||
/// </summary>
|
||
/// <param name="ms"></param>
|
||
void OnReceivedMessage(ByteBuffer buffer)
|
||
{
|
||
//user id
|
||
buffer.ReadIntToByte();
|
||
//token
|
||
buffer.ReadIntToByte();
|
||
//协议号
|
||
int msgid = buffer.ReadIntToByte();
|
||
|
||
//收到心跳包
|
||
if (msgid == 1001)
|
||
{
|
||
lock (mEvents)
|
||
{
|
||
mEvents.Enqueue(new NetMsg(msgid, 0, 0, buffer));
|
||
}
|
||
return;
|
||
}
|
||
//消息index
|
||
int sId = buffer.ReadIntToByte();
|
||
//结果码
|
||
int result = buffer.ReadIntToByte();
|
||
lock (mEvents)
|
||
{
|
||
mEvents.Enqueue(new NetMsg(msgid, sId, result, buffer));
|
||
}
|
||
}
|
||
|
||
private void indicationErrorAction(ByteBuffer buffer)
|
||
{
|
||
Debug.Log("SocketClient indicationErrorAction");
|
||
Util.CallMethod("SocketManager", "ReceiveErrorInfo", this, buffer);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 关闭链接
|
||
/// </summary>
|
||
public void Close()
|
||
{
|
||
Debug.Log("SocketClient Close");
|
||
UnregistNetMessage(INDICATION_ERROR_CODE, indicationErrorAction);
|
||
m_isConnected = false;
|
||
m_isConnecting = false;
|
||
|
||
lock (mEvents)
|
||
{
|
||
mEvents.Clear();
|
||
}
|
||
dispatchers.Clear();
|
||
callbacks.Clear();
|
||
stateInfoStack.Clear();
|
||
|
||
if (client != null)
|
||
{
|
||
client.Close();
|
||
client = null;
|
||
}
|
||
else {
|
||
Debug.Log("SocketClient Close client==null");
|
||
}
|
||
|
||
if (_memStream != null)
|
||
{
|
||
_memStream.Dispose();
|
||
_memStream = null;
|
||
}
|
||
if (_reader != null)
|
||
{
|
||
_reader.Close();
|
||
_reader = null;
|
||
}
|
||
Array.Clear(byteBuffer, 0, byteBuffer.Length);
|
||
}
|
||
|
||
bool testConnect;
|
||
public void Update()
|
||
{
|
||
if (stateInfoStack.Count > 0)
|
||
{
|
||
var info = stateInfoStack.Pop();
|
||
|
||
if (info.type == NetworkStateType.Connected)
|
||
{
|
||
m_isConnected = true;
|
||
RegistNetMessage(INDICATION_ERROR_CODE, indicationErrorAction);
|
||
Util.CallMethod("SocketManager", "OnConnect", this);
|
||
}
|
||
else if (info.type == NetworkStateType.ConnectFail)
|
||
{
|
||
Util.CallMethod("SocketManager", "OnConnectFail", this);
|
||
}
|
||
else if (info.type == NetworkStateType.Reconnected)
|
||
{
|
||
m_isConnected = true;
|
||
RegistNetMessage(INDICATION_ERROR_CODE, indicationErrorAction);
|
||
Util.CallMethod("SocketManager", "OnReconnect", this);
|
||
}
|
||
else if (info.type == NetworkStateType.ReconnectFail)
|
||
{
|
||
Util.CallMethod("SocketManager", "OnReconnectFail", this);
|
||
}
|
||
else if (info.type == NetworkStateType.Disconnect)
|
||
{
|
||
Disconnect();
|
||
}
|
||
else if (info.type == NetworkStateType.Exception)
|
||
{
|
||
Disconnect();
|
||
}
|
||
return;
|
||
}
|
||
|
||
lock (mEvents)
|
||
{
|
||
while (mEvents.Count > 0)
|
||
{
|
||
DispatchMessage(mEvents.Dequeue());
|
||
}
|
||
}
|
||
|
||
testConnect = Input.GetKeyDown(KeyCode.F1);
|
||
|
||
if (testConnect)
|
||
{
|
||
Debug.Log("~~~~~~~~~~~~~测试掉线~~~~~~~~~~~~~~~");
|
||
}
|
||
|
||
if (m_isConnecting && !testConnect)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ((testConnect || !IsConnected()) && m_isConnected)
|
||
{
|
||
Disconnect();
|
||
}
|
||
}
|
||
|
||
void DispatchMessage(NetMsg _event)
|
||
{
|
||
int msgId = _event.msgId;
|
||
ByteBuffer msg = _event.msg;
|
||
|
||
//处理心跳包回调
|
||
if (msgId == 1001)
|
||
{
|
||
Util.CallMethod("SocketManager", "ReceiveClientHeartBeat", this, msg);
|
||
return;
|
||
}
|
||
//处理错误码
|
||
if (_event.result == 0)
|
||
{
|
||
Debug.Log("SocketClient DispatchMessage result == 0 msgID: " + msgId + " msg: " + msg);
|
||
m_serialId++;
|
||
Util.CallMethod("SocketManager", "ReceiveErrorInfo", this, msg);
|
||
if (callbacks.ContainsKey(msgId))
|
||
{
|
||
callbacks.Remove(msgId);
|
||
}
|
||
return;
|
||
}
|
||
//处理推送消息,当序列号比本地游标大1,处理推送信息,否则不处理
|
||
if (dispatchers.ContainsKey(msgId))
|
||
{
|
||
if (m_indicationSid == _event.sid - 1)
|
||
{
|
||
m_indicationSid++;
|
||
if (!dispatchers[msgId].Process(msg))
|
||
{
|
||
Debug.Log("SocketClient DispatchMessage Failed to process message. msgId : " + msgId);
|
||
}
|
||
}
|
||
if (_event.sid <= m_indicationSid)
|
||
{
|
||
m_SendMessage(INDICATION_RESPONSE, null, _event.sid);
|
||
}
|
||
}
|
||
//处理请求回应消息
|
||
if (callbacks.ContainsKey(msgId))
|
||
{
|
||
var call = callbacks[msgId];
|
||
callbacks.Remove(msgId);
|
||
m_serialId++;
|
||
if (!call.Process(msg))
|
||
{
|
||
Debug.Log("SocketClient DispatchMessage Failed to process message2. msgId : " + msgId);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void Disconnect()
|
||
{
|
||
Debug.Log("SocketClient Disconnect");
|
||
Close(); //关掉客户端链接
|
||
Util.CallMethod("SocketManager", "OnDisconnect", this);
|
||
}
|
||
|
||
private Coroutine checkConnect_co;
|
||
IEnumerator CheckConnect_Co()
|
||
{
|
||
yield return new WaitForEndOfFrame();
|
||
Debug.Log("SocketClient CheckConnect_Co IP: " + IpAddress + " Port: " + Port);
|
||
Connect();
|
||
m_isConnecting = true;
|
||
yield return new WaitForSeconds(AppConst.ConnectTimeout);
|
||
if (!IsConnected())
|
||
{
|
||
Debug.Log("SocketClient CheckConnect_Co connect Fail");
|
||
OnConnectFail();
|
||
}
|
||
|
||
m_isConnecting = false;
|
||
checkConnect_co = null;
|
||
}
|
||
/// <summary>
|
||
/// 发送连接请求
|
||
/// </summary>
|
||
public void TryConnect()
|
||
{
|
||
if (IsConnected())
|
||
{
|
||
Debug.Log("SocketClient TryConnect isConnected");
|
||
NetworkStateInfo info = new NetworkStateInfo();
|
||
info.type = NetworkStateType.Connected;
|
||
info.msg = null;
|
||
stateInfoStack.Push(info);
|
||
return;
|
||
}
|
||
if (m_isConnecting)
|
||
{
|
||
Debug.Log("SocketClient TryConnect m_isConnecting");
|
||
return;
|
||
}
|
||
|
||
if (checkConnect_co != null)
|
||
{
|
||
Debug.Log("SocketClient TryConnect checkConnect_co != nul");
|
||
netMgr.StopCoroutine(checkConnect_co);
|
||
}
|
||
checkConnect_co = netMgr.StartCoroutine(CheckConnect_Co());
|
||
}
|
||
|
||
private Coroutine reconnect_co;
|
||
IEnumerator CheckReconnect_Co()
|
||
{
|
||
Debug.Log("SocketClient TryConnect CheckReconnect_Co");
|
||
yield return new WaitForEndOfFrame();
|
||
Reconnect();
|
||
m_isConnecting = true;
|
||
yield return new WaitForSeconds(AppConst.ConnectTimeout);
|
||
if (!IsConnected())
|
||
{
|
||
Debug.Log("SocketClient CheckReconnect_Co connect Fail");
|
||
OnReconnectFail();
|
||
}
|
||
|
||
m_isConnecting = false;
|
||
reconnect_co = null;
|
||
}
|
||
|
||
public void TryReconnect()
|
||
{
|
||
if (IsConnected())
|
||
{
|
||
Debug.Log("SocketClient TryReconnect IsConnected");
|
||
NetworkStateInfo info = new NetworkStateInfo();
|
||
info.type = NetworkStateType.Reconnected;
|
||
info.msg = null;
|
||
stateInfoStack.Push(info);
|
||
return;
|
||
}
|
||
if (m_isConnecting)
|
||
{
|
||
Debug.Log("SocketClient TryReconnect m_isConnecting");
|
||
return;
|
||
}
|
||
|
||
|
||
if (reconnect_co != null)
|
||
{
|
||
Debug.Log("SocketClient TryReconnect reconnect_co != nul");
|
||
netMgr.StopCoroutine(reconnect_co);
|
||
}
|
||
reconnect_co = netMgr.StartCoroutine(CheckReconnect_Co());
|
||
}
|
||
|
||
public void Reconnect()
|
||
{
|
||
Close();
|
||
try
|
||
{
|
||
Debug.Log("SocketClient Reconnect");
|
||
var ipType = GetIPAddressType(IpAddress);
|
||
client = null;
|
||
client = new TcpClient(ipType);
|
||
//client.SendTimeout = 1000;
|
||
//client.ReceiveTimeout = 1000;
|
||
client.NoDelay = true;
|
||
client.BeginConnect(IpAddress, Port, new AsyncCallback(OnReconnect), null);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.Log("SocketClient Reconnect catch :" + e.Message);
|
||
OnReconnectFail();
|
||
}
|
||
}
|
||
|
||
public AddressFamily GetIPAddressType(string ip)
|
||
{
|
||
bool hasIpv4 = false;
|
||
bool hasIpv6 = false;
|
||
|
||
try
|
||
{
|
||
IPAddress[] address = Dns.GetHostAddresses(ip);
|
||
for (int i = 0; i < address.Length; i++)
|
||
{
|
||
//从IP地址列表中筛选出IPv4类型的IP地址
|
||
//AddressFamily.InterNetwork表示此IP为IPv4,
|
||
//AddressFamily.InterNetworkV6表示此地址为IPv6类型
|
||
if (address[i].AddressFamily == AddressFamily.InterNetwork)
|
||
{
|
||
hasIpv4 = true;
|
||
}
|
||
else if (address[i].AddressFamily == AddressFamily.InterNetworkV6)
|
||
{
|
||
hasIpv6 = true;
|
||
}
|
||
|
||
Util.Log("Network IPAddresssFamily: " + address[i].AddressFamily.ToString() + " IP: " + address[i].ToString());
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.Log("SocketClient GetIPAddressType catch :" + ex.Message);
|
||
return AddressFamily.InterNetwork;
|
||
}
|
||
|
||
if (hasIpv4)
|
||
return AddressFamily.InterNetwork;
|
||
|
||
if (hasIpv6)
|
||
return AddressFamily.InterNetworkV6;
|
||
|
||
return AddressFamily.InterNetwork;
|
||
}
|
||
|
||
public void OnReconnectFail()
|
||
{
|
||
AddStateInfo(NetworkStateType.ReconnectFail, "OnReconnectFail");
|
||
}
|
||
|
||
void OnReconnect(IAsyncResult result)
|
||
{
|
||
outStream = client.GetStream();
|
||
client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
|
||
AddStateInfo(NetworkStateType.Reconnected, "OnReconnect");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送消息
|
||
/// </summary>
|
||
public void SendMessage(int msgId, ByteBuffer msg)
|
||
{
|
||
Debug.Log("SocketClient SendMessage msgID: " + msgId);
|
||
m_serialId++;
|
||
m_SendMessage(msgId, msg, m_serialId);
|
||
}
|
||
|
||
void m_SendMessage(int msgId, ByteBuffer msg, int sn)
|
||
{
|
||
if (!IsConnected())
|
||
{
|
||
return;
|
||
}
|
||
ByteBuffer buffer = new ByteBuffer();
|
||
buffer.WriteIntToByte(AppConst.UserId);
|
||
buffer.WriteIntToByte(AppConst.Token);
|
||
buffer.WriteIntToByte(msgId);
|
||
buffer.WriteIntToByte(sn);
|
||
|
||
if (msg != null)
|
||
{
|
||
buffer.WriteBuffer(new LuaInterface.LuaByteBuffer(msg.ToBytes()));
|
||
msg.Close();
|
||
}
|
||
|
||
WriteMessage(buffer.ToBytes());
|
||
buffer.Close();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送心跳
|
||
/// </summary>
|
||
public void SendHeartBeat()
|
||
{
|
||
ByteBuffer buffer = new ByteBuffer();
|
||
buffer.WriteIntToByte(AppConst.UserId);
|
||
buffer.WriteIntToByte(AppConst.Token);
|
||
buffer.WriteIntToByte(1000);
|
||
WriteMessage(buffer.ToBytes());
|
||
buffer.Close();
|
||
}
|
||
|
||
|
||
public bool IsConnected()
|
||
{
|
||
return client != null && client.Connected;
|
||
}
|
||
|
||
public void RegistNetMessage(int msgId, Action<ByteBuffer> handle)
|
||
{
|
||
if (!dispatchers.ContainsKey(msgId))
|
||
dispatchers.Add(msgId, new SimpleDispatcher());
|
||
SimpleDispatcher find = (SimpleDispatcher)dispatchers[msgId];
|
||
find.processor += handle;
|
||
}
|
||
|
||
public void UnregistNetMessage(int msgId, Action<ByteBuffer> handle)
|
||
{
|
||
if (!dispatchers.ContainsKey(msgId))
|
||
return;
|
||
SimpleDispatcher find = (SimpleDispatcher)dispatchers[msgId];
|
||
find.processor -= handle;
|
||
}
|
||
|
||
|
||
public void SendMessageWithCallBack(int msgId, int receiveMsgId, ByteBuffer message, LuaFunction callback)
|
||
{
|
||
Debug.Log("SocketClient SendMessageWithCallBack msgID:" + msgId.ToString());
|
||
if (!IsConnected())
|
||
{
|
||
UnityEngine.Debug.LogErrorFormat("Try to send message with invalid connection.");
|
||
AddStateInfo(NetworkStateType.Disconnect, "bytesRead < 1");
|
||
}
|
||
else
|
||
{
|
||
SimpleDispatcher cb = new SimpleDispatcher();
|
||
cb.processor += b => callback.Call(b);
|
||
if (!callbacks.ContainsKey(receiveMsgId))
|
||
{
|
||
callbacks.Add(receiveMsgId, cb);
|
||
}
|
||
m_SendMessage(msgId, message, m_serialId);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|