调试过程中发现的客户端NetManager.cs 代码bug
在测试书籍附加的代码时,经过debug发现存在以下两个问题: 以下两个问题均在 客户端代码的NetManager中。
问题1: msgListeners字典管理不当,产生空指针
调试过程中,发现一局游戏结束后,再次从房间进入游戏,程序会直接报错跳出。
针对RemoveMsgListener函数:
//删除消息监听
public static void RemoveMsgListener(string msgName, MsgListener listener){
if (msgListeners.ContainsKey(msgName)){
msgListeners[msgName] -= listener;
}
}
在一局游戏结束后会执行RemoveMsgListener函数,把msgListeners字典的某个value删了,但key却没删。 当再次从同一个房间开启下次游戏的过程中,msgListeners 中 仍然有 msgName 作为key,但其对应的 value 却是 null。此时执行很多别的函数,if(msgListeners.ContainsKey(msgName))均为真,但此时其值为null,故报错跳出。如:
//分发消息
private static void FireMsg(string msgName, MsgBase msgBase){
// Debug.Log(msgName);
if(msgListeners.ContainsKey(msgName)){
msgListeners[msgName](msgBase);
}
}
故RemoveMsgListener 函数应改为:
//删除消息监听
public static void RemoveMsgListener(string msgName, MsgListener listener){
if (msgListeners.ContainsKey(msgName)){
msgListeners[msgName] -= listener;
if (msgListeners[msgName] == null)
{
msgListeners.Remove(msgName);
}
}
}
即删除完value后判断 key对应的value是否为空,若为空,则连着key一起删了。防止 key对应 null的情况出现。
RemoveEventListener 函数同理,不再赘述
问题2 运行正常,但debug单步调试卡在SendCallback函数运行不下去。
对于 SendCallback 函数,有这一串代码:
lock(writeQueue){
writeQueue.Dequeue();
ba = writeQueue.First();
}
}
虽然正常运行没有问题,但其中:ba = writeQueue.First(); 会卡住debug,无法单步调试,让debug过程非常恶心。
猜测原因是debug过程中 writeQueue 经常为空,故 writeQueue.First() 返回值异常导致卡死。
经过玄学调试,将其改为:
lock(writeQueue){
writeQueue.Dequeue();
if (writeQueue.Count > 0) {
ba = writeQueue.First();
} else {
ba = null;
}
}
之后,debug就可以正常进行了。
更改后的代码见附件 NetManager.txt
感谢作者大大的代码,整体框架非常牛逼,我就在这套代码的基础上开发的自己的项目。希望能帮助作者大大一起完善此书。