Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
sytnocui opened this issue Mar 9, 2024 · 1 comment
Open

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

sytnocui opened this issue Mar 9, 2024 · 1 comment

Comments

@sytnocui
Copy link

sytnocui commented Mar 9, 2024

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

sytnocui commented Mar 9, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant