unity_net_book icon indicating copy to clipboard operation
unity_net_book copied to clipboard

调试过程中发现的客户端NetManager.cs 代码bug

Open sytnocui opened this issue 2 years ago • 1 comments

在测试书籍附加的代码时,经过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

sytnocui avatar Mar 09 '24 16:03 sytnocui

感谢作者大大的代码,整体框架非常牛逼,我就在这套代码的基础上开发的自己的项目。希望能帮助作者大大一起完善此书。

sytnocui avatar Mar 09 '24 16:03 sytnocui