socket编程遇到的bug记录

前言

  • 最近在按照siki的教程写socket编程,我快速看了一遍教程,然后按照他的思路开始自己编写
  • UI的各种方式,以及镜头刚开始的摆动这些我觉得很多余,花哨,没有添加
  • 知易行难,自己动手操作的时候遇到了很多bug,其实还好,大部分是由于自己考虑不周,或者细节性问题错误的
  • 本来想写完代码后再来写这篇博客,结果现在遇到一些bug,难以解决。

注册之后前面用户的账户无法登陆

  • 首先,我是无意中在注册了一个新用户之后发现这个问题的。
  • 然后为了确认这个问题是能还原的,我测试了很多遍,发现的确是有这么个问题。而不是一时的硬件或是其它所导致的
  • 解决过程
  • 首先我要确认是客户端的问题,还是服务器的问题,于是我把双方发送与接受的信息全部输出
  • 然后发现,发送的信息没有问题,但是接受的信息全部多了一些后缀。
  • 后来发现是信息解析代码的逻辑出现了问题,更正之后无误

密码完全相同,但是返回false

  • 我专门从数据库看的密码没有问题
  • 然后在数据库进行查询的时候,输出了一下查询到的密码和存储的密码,完全一致。但是返回false,导致登陆失败
  • 原因 因为我中间更改过一次密码字段的数据类型,所以原先注册的密码可能还是维持原来的样子。导致了这个问题

数据库问题

  • 数据库莫名其妙说是 host dont support ssl connection
  • 我试着设置sslmode=nono,但其后又出现1045拒绝访问的问题。
  • 我在网上查找了很多解决办法,最后都没有解决。只好重新安装数据库
  • 我觉得数据库问题最好的方式就是重新安装好了,把原有的数据库导出来,然后卸载,重新安装,再放置进去就是

无法获取房间列表

  • 当时报错为空引用
  • 后来发现,在方法里面的局部变量为data,然后脚本中的字段名也为data,两个重合了,所以一直报错为空引用

无法在None中找到对应的处理方法None

  • 这个问题是出现在用户登陆完之后,整个场景要转换到房间面板的时候,在房间面板有几个请求
  • 首先他要向服务器发送请求,获得用户自身的战绩信息,这个操作我放置在了房间面板的onResumeUI面板生命周期事件中。
  • 而每一个请求的Start方法中,我设置了每一个请求所对应的actioncode与requestcode,结果由于start调用顺序慢于onResume(),直接使用了基类baseRequest的code码none
  • 解决办法
  • 我把请求类的所有初始化放置在了awake方法中,然后解决了,后来进一步重构
  • 在awake方法中放入了init方法,子类只需要重写init方法即可

关于string为null的问题

  • string的默认值为null,在作为脚本的字段时
  • 我在写登录面板的校验逻辑时使用的是string.isNullorEmpty(content.trim());
  • 其实我本来想使用string.isNullorEmptyorWhite(),但是不知道为何无法使用,不知道是框架还是什么问题。
  • 这样会导致对null.trim()这样的错误。
  • 解决办法 将string赋初值为空字符串

用户重复登录的问题

  • 我注册了一个用户,45
  • 然后开了两个客户端,分别用该账户进行登录,发现可以运行
  • 解决方法
  • 我给每一个client绑定了一个userid,并且维护了一个client集合
  • 当一个用户登陆的时候,先从数据库中查询是否存在该用户,并且得到其id,然后查询已经登录的client集合中是否存在该id
  • 否则的话就返回false

关于请求解析脚本被禁用是否还会运行

  • 其实这不算一个bug,而是一个疑惑,问题来源于,我的服务器需要向客户端推送消息,让客户端更新房间列表界面,可是客户端此时可能正在游戏或者在等待开始状态
  • 这样的话,房间面板处于active(false)的状态,我就想,这种情况下发送请求,获得房间的脚本会运行吗,因为它是挂载在房间面板上面的
  • 解决办法
  • 我做了一个实验,即使物体被禁用了,但是这个脚本的实例还是处于内存当中,(当然前提是该物体在场景中active(true)过,这样内存中才会有其脚本的实例),可以被调用并且对该物体自身做一些改变

unity报错的问题

  • 这个问题描述起来很复杂,当只有一个客户端在线的时候,没有任何问题,但是两个客户端的时候,其中一个创建房间,其它客户端就没有办法再创建房间,但是这个时候依旧可以向服务器发送消息,服务器也发送了消息,而客户端没有接收消息,这就导致,无法知晓是否开房成功,没有办法进入另一个UI界面
  • 我debug这个错误花费了很长时间,因为他是各种错误混杂在了一起
  • 正常的解析思路
  • 两个客户端都登陆的情况下,其中一个可以创建房间,但是在其创建之后,另一个客户端就没有办法创建,只是发送消息,但是没办法接收
  • 而且服务器确实发送了消息。
  • 问题出在了客户端,客户端出现了某个异常,导致没办法正常运行。
  • 我发现在创建房间的时候,我让其广播了所有其他客户端,因为只有这条语句影响了其他客户端。所以我尝试着进行注释,发现问题就是这句代码
  • 然后我重新查看代码,发现我发送了两条消息,但是解析的时候试图获取第三条,出现了数组越界异常。但是Unity没有给我报错,程序却是不再正常运行了
  • 在实验之后,发现在子线程里面出现的错误,unity不会报错

掺杂的其他异常

  • 其一 空引用异常, 因为我粗心将字段名和方法参数名设置相同导致
  • 其二 服务器空引异常, 因为我粗心在遍历client集合时,应该是item.SendResponse(),写成了client.SendResponse()
  • 这些细微错误所导致的程序现象都十分奇怪。不过慢慢捋就好了。

实例化所导致的异常

  • 原因极其简单,通过GameObject实例化出来的物体,如果没有命名,都会加一个后缀clone
  • 我为了方便,在hierarchy面板留下了几个预制体方便修改,然后脚本获得物体的时候,获得的是我留下的这几个预制体。因为实例化的预制体名字多了一个clone,而留下的预制体是一直禁用状态,脚本没有初始化。导致我发送的一直是None

空指针异常

  • 这种异常往往是因为初始化顺序所导致的
  • 在这个实操过程中,空指针由这么几个引起
  • 1.我需要创建生成子物体,但是子物体的生成是在一个active为false的物体下,子物体的初始化脚本在awake方法里面,导致init时失败
  • 2.我在切换界面时,入场动画放置在了EnterAnim里面,放置在了设置数据后面。(当时是想,设置完数据再播放动画,界面会很好)。当第一次界面退出动画的时候,这些组件会setactivefalse,导致第二次进入时就会出现空引用。调整一下顺序即可。但是这个bug隐藏有点深,需要测试几次才能发现。

感想

  • 我很喜欢一口气把所有的功能全部写完,然后开始测试
  • 会这样是因为,我的电脑性能太差,每次vs打开或者测试都会很耗时间,所以我写客户端的时候,就尽量把客户端的代码全部写完,写服务器端的时候就把服务器端全部写完。这样其实很不好,应该写一个功能,测一下。避免太多bug混杂在一起。
  • 这些问题全部都是因为编程时的疏忽大意而引发的,也不是什么大问题。但是透过现象去找问题真的超级费时间,而那些疏忽大意又是无法避免的,因为无论检查多少遍,实际运行的时候,还是会出现问题。我在想

你可能感兴趣的:(Unity)