【优化】网络层优化-峰哥

dev_chengFeng
gaoxin 2020-12-29 20:27:35 +08:00 committed by JieLing
parent 9f691e4e05
commit 816351d73e
4 changed files with 214 additions and 96 deletions

View File

@ -1,4 +1,4 @@
using UnityEngine;
using UnityEngine;
using System;
using System.IO;
using System.Net;
@ -20,6 +20,7 @@ public enum NetworkStateType
Disconnect,
}
static class IPAddressExtensions
{
public static IPAddress MapToIPv6(this IPAddress addr)
@ -81,7 +82,7 @@ public class SocketClient
}
}
static readonly int HeaderSize= sizeof(ushort)+sizeof(int);
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();
@ -105,24 +106,23 @@ public class SocketClient
// Use this for initialization
public SocketClient(string ipAddress, int port)
{
//Debug.Log("****Socket*********************创建一个Socket ---" + ipAddress);
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>
@ -130,8 +130,8 @@ public class SocketClient
/// </summary>
public void Connect()
{
//Debug.Log("****Socket*********************Connect ---" + IpAddress);
Close();
Debug.Log("SocketClient Connect ipAddress: " + IpAddress);
try
{
var ipType = GetIPAddressType(IpAddress);
@ -145,13 +145,14 @@ public class SocketClient
catch (Exception e)
{
OnConnectFail();
Debug.LogError("SocketClient Connect catch: " + e.Message);
Debug.LogWarning(e.Message);
}
}
public void OnConnectFail()
{
AddStateInfo(NetworkStateType.ConnectFail, "OnConnectFail");
//Debug.Log("****Socket*********************OnConnectFail ---" + IpAddress);
AddStateInfo(NetworkStateType.ConnectFail, null);
}
/// <summary>
@ -159,10 +160,35 @@ public class SocketClient
/// </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");
//Debug.Log("****Socket*********************OnConnect ---" + IpAddress);
//outStream = client.GetStream();
//client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
//AddStateInfo(NetworkStateType.Connected, null);
m_isConnecting = false;
//检测是否成功的建立了链接。..
if (client == null || !client.Connected)
{
Debug.Log("****Socket*********************OnConnect FAILED ---" + IpAddress);
return;
}
try
{
//完成本次链接
client.EndConnect(asr);
// 记录链接的成功事件。
outStream = client.GetStream();
client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
AddStateInfo(NetworkStateType.Connected, null);
Debug.Log("****Socket*********************OnConnect SUCCESS ---" + IpAddress);
}
catch (Exception e)
{
Debug.Log("****Socket*********************OnConnect FAILED ---" + e.Message);
}
}
/// <summary>
@ -174,7 +200,7 @@ public class SocketClient
using (ms = new MemoryStream())
{
ms.Position = 0;
BinaryWriter writer = new BinaryWriter(ms);
short msglen = (short)message.Length;
@ -196,7 +222,7 @@ public class SocketClient
}
else
{
Debug.LogError("SocketClient WriteMessage !connected");
Debug.Log("client.connected----->>false");
}
}
}
@ -208,7 +234,7 @@ public class SocketClient
void OnRead(IAsyncResult asr)
{
int bytesRead = 0;
//try
try
{
lock (client.GetStream())
{
@ -229,12 +255,15 @@ public class SocketClient
Array.Clear(byteBuffer, 0, byteBuffer.Length); //清空数组
client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
}
Debug.Log("SocketClient.OnRead " + byteBuffer.ToString());
}
catch (Exception ex)
{
Debug.LogError("SocketClient.OnRead " + ex.ToString());
//Lnhbuc_PrintBytes();
AddStateInfo(NetworkStateType.Exception, ex.Message);
}
//catch (Exception ex)
//{
// //PrintBytes();
// AddStateInfo(NetworkStateType.Exception, ex.Message);
//}
}
/// <summary>
@ -246,21 +275,20 @@ public class SocketClient
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()
void Lnhbuc_PrintBytes()
{
string returnStr = string.Empty;
for (int i = 0; i < byteBuffer.Length; i++)
{
returnStr += byteBuffer[i].ToString("X2");
}
Debug.LogError("SocketClient PrintBytes Str: " + returnStr);
Debug.LogError(returnStr);
}
/// <summary>
@ -272,14 +300,14 @@ public class SocketClient
{
MemoryStream stream = (MemoryStream)r.AsyncState;
outStream.EndWrite(r);
if(stream!=null)
if (stream != null)
{
stream.Close();
}
}
catch (Exception ex)
{
Debug.LogError("SocketClient OnWrite catch: " + ex.Message.ToString());
Debug.LogError("OnWrite--->>>" + ex.Message);
}
}
@ -288,6 +316,8 @@ public class SocketClient
/// </summary>
void OnReceive(byte[] bytes, int length)
{
//Debug.Log("****Socket*********************OnReceive ---" + IpAddress);
try
{
var stream = CurMemoryStream;
@ -298,14 +328,14 @@ public class SocketClient
//Reset to beginning
stream.Seek(0, SeekOrigin.Begin);
while (RemainingBytes() > 4)
while (Bkupkw_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) //粘包处理
if (Bkupkw_RemainingBytes() >= decodeMessageLen) //粘包处理
{
var msgBytes = reader.ReadBytes(decodeMessageLen);
if (crypto != null)
@ -320,13 +350,13 @@ public class SocketClient
}
}
//Create a new stream with any leftover bytes
byte[] leftover = reader.ReadBytes((int)RemainingBytes());
byte[] leftover = reader.ReadBytes((int)Bkupkw_RemainingBytes());
stream.SetLength(0); //Clear
stream.Write(leftover, 0, leftover.Length);
}
catch (Exception e)
{
Debug.LogError("SocketClient OnReceive catch: " + e.ToString());
Debug.LogError("Network Read Exception: " + e.ToString());
AddStateInfo(NetworkStateType.Disconnect, "Network Read Exception: " + e.ToString());
}
}
@ -334,7 +364,7 @@ public class SocketClient
/// <summary>
/// 剩余的字节
/// </summary>
private long RemainingBytes()
private long Bkupkw_RemainingBytes()
{
return CurMemoryStream.Length - CurMemoryStream.Position;
}
@ -348,7 +378,7 @@ public class SocketClient
//user id
buffer.ReadIntToByte();
//token
buffer.ReadIntToByte();
buffer.ReadIntToByte();
//协议号
int msgid = buffer.ReadIntToByte();
@ -368,12 +398,13 @@ public class SocketClient
lock (mEvents)
{
mEvents.Enqueue(new NetMsg(msgid, sId, result, buffer));
}
}
}
private void indicationErrorAction(ByteBuffer buffer)
private void Ygqmgx_indicationErrorAction(ByteBuffer buffer)
{
Debug.Log("SocketClient indicationErrorAction");
//Debug.Log("****Socket*********************indicationErrorAction ---" + IpAddress);
Util.CallMethod("SocketManager", "ReceiveErrorInfo", this, buffer);
}
@ -383,8 +414,8 @@ public class SocketClient
/// </summary>
public void Close()
{
Debug.Log("SocketClient Close");
UnregistNetMessage(INDICATION_ERROR_CODE, indicationErrorAction);
Debug.Log("****Socket*********************Close ---" + IpAddress);
UnregistNetMessage(INDICATION_ERROR_CODE, Ygqmgx_indicationErrorAction);
m_isConnected = false;
m_isConnecting = false;
@ -401,9 +432,6 @@ public class SocketClient
client.Close();
client = null;
}
else {
Debug.Log("SocketClient Close client==null");
}
if (_memStream != null)
{
@ -421,6 +449,13 @@ public class SocketClient
bool testConnect;
public void Update()
{
// FHF DEBUG
//TimeSpan ts1 = Process.GetCurrentProcess().TotalProcessorTime;
//System.Diagnostics.Stopwatch stw = new System.Diagnostics.Stopwatch();
//stw.Start();
if (stateInfoStack.Count > 0)
{
var info = stateInfoStack.Pop();
@ -428,7 +463,7 @@ public class SocketClient
if (info.type == NetworkStateType.Connected)
{
m_isConnected = true;
RegistNetMessage(INDICATION_ERROR_CODE, indicationErrorAction);
RegistNetMessage(INDICATION_ERROR_CODE, Ygqmgx_indicationErrorAction);
Util.CallMethod("SocketManager", "OnConnect", this);
}
else if (info.type == NetworkStateType.ConnectFail)
@ -438,7 +473,7 @@ public class SocketClient
else if (info.type == NetworkStateType.Reconnected)
{
m_isConnected = true;
RegistNetMessage(INDICATION_ERROR_CODE, indicationErrorAction);
RegistNetMessage(INDICATION_ERROR_CODE, Ygqmgx_indicationErrorAction);
Util.CallMethod("SocketManager", "OnReconnect", this);
}
else if (info.type == NetworkStateType.ReconnectFail)
@ -447,20 +482,21 @@ public class SocketClient
}
else if (info.type == NetworkStateType.Disconnect)
{
Disconnect();
Disconnect(" NetworkStateType.Disconnect");
}
else if (info.type == NetworkStateType.Exception)
{
Disconnect();
}
Disconnect("NetworkStateType.Exception");
}
return;
}
// int _CCC = 0;
lock (mEvents)
{
while (mEvents.Count > 0)
{
DispatchMessage(mEvents.Dequeue());
// _CCC++;
}
}
@ -468,7 +504,7 @@ public class SocketClient
if (testConnect)
{
Debug.Log("~~~~~~~~~~~~~测试掉线~~~~~~~~~~~~~~~");
UnityEngine.Debug.Log("~~~~~~~~~~~~~测试掉线~~~~~~~~~~~~~~~");
}
if (m_isConnecting && !testConnect)
@ -478,8 +514,14 @@ public class SocketClient
if ((testConnect || !IsConnected()) && m_isConnected)
{
Disconnect();
Disconnect("TEST");
}
//FHF Debug time preform
// stw.Stop();
// if(_CCC>0)
// UnityEngine.Debug.Log("NET EVENT HANDLE: " + _CCC.ToString()+"@"+(stw.ElapsedTicks).ToString());
}
void DispatchMessage(NetMsg _event)
@ -487,16 +529,20 @@ public class SocketClient
int msgId = _event.msgId;
ByteBuffer msg = _event.msg;
//Debug.LogError("msgId:" + msgId);
//Debug.LogError("m_indicationSid:" + m_indicationSid);
//Debug.LogError("sid:" + _event.sid);
//处理心跳包回调
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))
@ -513,11 +559,12 @@ public class SocketClient
m_indicationSid++;
if (!dispatchers[msgId].Process(msg))
{
Debug.Log("SocketClient DispatchMessage Failed to process message. msgId : " + msgId);
UnityEngine.Debug.LogErrorFormat("Failed to process message. msgId : {0}", msgId);
}
}
if (_event.sid <= m_indicationSid)
{
//Debug.LogError("INDICATION_RESPONSE" + msgId);
m_SendMessage(INDICATION_RESPONSE, null, _event.sid);
}
}
@ -529,29 +576,29 @@ public class SocketClient
m_serialId++;
if (!call.Process(msg))
{
Debug.Log("SocketClient DispatchMessage Failed to process message2. msgId : " + msgId);
UnityEngine.Debug.LogErrorFormat("Failed to process message. msgId : {0}", msgId);
}
}
}
public void Disconnect()
public string Error;
public void Disconnect(string _err)
{
Debug.Log("SocketClient Disconnect");
Close(); //关掉客户端链接
Util.CallMethod("SocketManager", "OnDisconnect", this);
Error = _err;
Debug.Log("****Socket*********************Disconnect [" + Error + "] ---" + IpAddress);
Close();
Util.CallMethod("SocketManager", "OnDisconnect", this, _err);
}
private Coroutine checkConnect_co;
IEnumerator CheckConnect_Co()
{
yield return new WaitForEndOfFrame();
Debug.Log("SocketClient CheckConnect_Co IP: " + IpAddress + " Port: " + Port);
Debug.LogWarning("Start Connecting IP: " + IpAddress + " Port: " + Port);
Connect();
m_isConnecting = true;
yield return new WaitForSeconds(AppConst.ConnectTimeout);
if (!IsConnected())
{
Debug.Log("SocketClient CheckConnect_Co connect Fail");
OnConnectFail();
}
@ -563,9 +610,9 @@ public class SocketClient
/// </summary>
public void TryConnect()
{
//Debug.Log("****Socket*********************TryConnect ---" + IpAddress);
if (IsConnected())
{
Debug.Log("SocketClient TryConnect isConnected");
NetworkStateInfo info = new NetworkStateInfo();
info.type = NetworkStateType.Connected;
info.msg = null;
@ -573,58 +620,53 @@ public class SocketClient
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 WaitForEndOfFrame();
Reconnect();
yield return new WaitForSeconds(AppConst.ConnectTimeout);
if (!IsConnected())
{
Debug.Log("SocketClient CheckReconnect_Co connect Fail");
OnReconnectFail();
}
m_isConnecting = false;
reconnect_co = null;
}
float _LastReconectime = 0;
public void TryReconnect()
{
if (Time.time - _LastReconectime < AppConst.ConnectTimeout + 1)
return;
_LastReconectime = Time.time;
Debug.Log("****Socket*********************TryReconnect ---" + IpAddress);
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());
@ -632,10 +674,10 @@ public class SocketClient
public void Reconnect()
{
Debug.Log("****Socket*********************Reconnect ---" + IpAddress);
Close();
try
{
Debug.Log("SocketClient Reconnect");
var ipType = GetIPAddressType(IpAddress);
client = null;
client = new TcpClient(ipType);
@ -646,7 +688,7 @@ public class SocketClient
}
catch (Exception e)
{
Debug.Log("SocketClient Reconnect catch " + e.Message);
Debug.LogError(e.Message);
OnReconnectFail();
}
}
@ -678,7 +720,7 @@ public class SocketClient
}
catch (Exception ex)
{
Debug.Log("SocketClient GetIPAddressType catch " + ex.Message);
Debug.LogWarning("Network GetIPAddressType Exception: " + ex);
return AddressFamily.InterNetwork;
}
@ -693,26 +735,48 @@ public class SocketClient
public void OnReconnectFail()
{
AddStateInfo(NetworkStateType.ReconnectFail, "OnReconnectFail");
//Debug.Log("****Socket*********************OnReconnectFail ---" + IpAddress);
AddStateInfo(NetworkStateType.ReconnectFail, null);
}
void OnReconnect(IAsyncResult result)
{
outStream = client.GetStream();
client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
AddStateInfo(NetworkStateType.Reconnected, "OnReconnect");
m_isConnecting = false;
//检测是否成功的建立了链接。..
if (client == null || !client.Connected)
{
Debug.Log("****Socket*********************OnReconnect FAILED ---" + IpAddress);
return;
}
try
{
//完成本次链接
client.EndConnect(result);
// 记录链接的成功事件。
outStream = client.GetStream();
client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null);
AddStateInfo(NetworkStateType.Reconnected, null);
Debug.Log("****Socket*********************OnReconnect SUCCESS ---" + IpAddress);
}
catch (Exception e)
{
Debug.Log("****Socket*********************OnReconnect FAILED ---" + e.Message);
}
}
/// <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())
@ -733,6 +797,9 @@ public class SocketClient
WriteMessage(buffer.ToBytes());
buffer.Close();
//UnityEngine.Debug.Log("SocketClient.m_SendMessage..."+ msgId);
}
/// <summary>
@ -758,6 +825,7 @@ public class SocketClient
{
if (!dispatchers.ContainsKey(msgId))
dispatchers.Add(msgId, new SimpleDispatcher());
//XDebug.Log.l("++++++++++++++++RegistNetMessage================================", msgId, IpAddress, Port);
SimpleDispatcher find = (SimpleDispatcher)dispatchers[msgId];
find.processor += handle;
}
@ -766,6 +834,7 @@ public class SocketClient
{
if (!dispatchers.ContainsKey(msgId))
return;
XDebug.Log.l("-------------------UnregistNetMessage================================", msgId, IpAddress, Port);
SimpleDispatcher find = (SimpleDispatcher)dispatchers[msgId];
find.processor -= handle;
}
@ -773,7 +842,6 @@ public class SocketClient
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.");
@ -781,6 +849,7 @@ public class SocketClient
}
else
{
SimpleDispatcher cb = new SimpleDispatcher();
cb.processor += b => callback.Call(b);
if (!callbacks.ContainsKey(receiveMsgId))
@ -791,6 +860,4 @@ public class SocketClient
}
}
}

View File

@ -1,4 +1,4 @@
require "Message/CommonProto_pb"
require "Message/CommonProto_pb"
require "Message/MessageTypeProto_pb"
require "Base/Queue"
Network = {}
@ -57,14 +57,14 @@ function Network:OnException()
end
--连接中断,或者被踢掉--
function Network:OnDisconnect()
function Network:OnDisconnect(err)
self.reconnectFlag = true
self.isConnected = false
self.bIsStartListenHeartBeat = false
Game.GlobalEvent:DispatchEvent(Protocal.Disconnect, self)
RequestPanel.Show("您已掉线,正在请求重连")
RequestPanel.Show("您已掉线,正在请求重连")--..err)
self.socket:TryReconnect()
end
@ -85,6 +85,8 @@ function Network:OnReconnect()
RequestPanel.Show("重连成功!等待服务器响应")
self.re_resendTimes = 0
self.reconnectFlag = false
self.socket:SendMessageWithCallBack(MessageTypeProto_pb.RECONNECT_REQUEST, MessageTypeProto_pb.RECONNECT_RESPONSE, nil, function(b)
Log("已经重连!!")
RequestPanel.Hide()
@ -92,6 +94,15 @@ function Network:OnReconnect()
self.bIsStartListenHeartBeat = true
Game.GlobalEvent:DispatchEvent(Protocal.Connect, self)
end)
coroutine.start(function()
coroutine.wait(2)
if not self.isConnected then
Log("没有收到 重连信息,重新设置链接!!")
self.socket:Disconnect()
end
end)
end
function Network:Reset()

View File

@ -99,9 +99,9 @@ function SocketManager.OnException(socket)
end
--连接中断,或者被踢掉--
function SocketManager.OnDisconnect(socket)
function SocketManager.OnDisconnect(socket, _err)
if SocketManager.SocketDic[socket] then
SocketManager.SocketDic[socket]:OnDisconnect()
SocketManager.SocketDic[socket]:OnDisconnect(_err)
end
end

View File

@ -28,6 +28,7 @@ public class SocketClientWrap
L.RegFunction("New", _CreateSocketClient);
L.RegFunction("__tostring", ToLua.op_ToString);
L.RegVar("netMgr", get_netMgr, set_netMgr);
L.RegVar("Error", get_Error, set_Error);
L.RegVar("CurMemoryStream", get_CurMemoryStream, null);
L.RegVar("CurReader", get_CurReader, null);
L.RegVar("IpAddress", get_IpAddress, null);
@ -166,9 +167,10 @@ public class SocketClientWrap
{
try
{
ToLua.CheckArgsCount(L, 1);
ToLua.CheckArgsCount(L, 2);
SocketClient obj = (SocketClient)ToLua.CheckObject<SocketClient>(L, 1);
obj.Disconnect();
string arg0 = ToLua.CheckString(L, 2);
obj.Disconnect(arg0);
return 0;
}
catch (Exception e)
@ -385,6 +387,25 @@ public class SocketClientWrap
}
}
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int get_Error(IntPtr L)
{
object o = null;
try
{
o = ToLua.ToObject(L, 1);
SocketClient obj = (SocketClient)o;
string ret = obj.Error;
LuaDLL.lua_pushstring(L, ret);
return 1;
}
catch(Exception e)
{
return LuaDLL.toluaL_exception(L, e, o, "attempt to index Error on a nil value");
}
}
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int get_CurMemoryStream(IntPtr L)
{
@ -479,5 +500,24 @@ public class SocketClientWrap
return LuaDLL.toluaL_exception(L, e, o, "attempt to index netMgr on a nil value");
}
}
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int set_Error(IntPtr L)
{
object o = null;
try
{
o = ToLua.ToObject(L, 1);
SocketClient obj = (SocketClient)o;
string arg0 = ToLua.CheckString(L, 2);
obj.Error = arg0;
return 0;
}
catch(Exception e)
{
return LuaDLL.toluaL_exception(L, e, o, "attempt to index Error on a nil value");
}
}
}