内置GateHandler Bind函数逻辑修改建议
youngpto opened this issue · comments
issue:执行156行会产生nil pointer panic
branch:master
runtime: go1.12+
复现流程:内置的ClientAgent实现确保了session不为空且无置nil操作所以不会触发,通过SetCreateAgent函数自定义ClientAgent并在调用Bind函数前对session置空则稳定复现
修改建议:此处设计上是对新连接的session同步持久化数据,不应该有空session的存在,抛出异常会更恰当
mqant/gate/base/gate_handler.go
Lines 140 to 173 in d5761a1
还有文档好像很久没有更新了,Gate模块对StorageHandler的介绍几乎没有,需要自行研究代码,比如此处153行的使用到的data是由使用者自定义的StorageHandler返回的,此处文档没有说明StorageHandler返回[]byte该遵守什么约定或者需要额外做什么处理,看了默认的NewSession实现才能发现需要把data解码为proto.SessionImp类型。
您说的那个nil pointer panic我没太看明白,那个地方有做nil判断呀?
第二个问题StorageHandler序列化方式完全由开发者选择,所以[]byte不用遵循什么规范,按开发者自己的规范序列化和反序列化就行
第一个问题我觉得通过155行也可以看出此处判断的是为空的时候还调用了这个空指针,只是正常情况下不会触发这个case,所以这个判空其实是没有意义的,并且可以看到整个方法体内是默认GetSession不为空的比如说一开始就调用了SetUserID这个方法。
第二个问题可能是我描述的有些问题,StorageHandler内部如何存储数据确实是开发者自己定义结构就可以的,但是Query这个方法在上面代码块的150行也被调用,而后这个data被传入NewSession方法。
确实默认的Agent实现方法NewMqttAgent,确保了客户端连接后就初始化了session,所以不会出现nil,如果是自己实现的Agent也得遵循这个逻辑
第一个问题我觉得通过155行也可以看出此处判断的是为空的时候还调用了这个空指针,只是正常情况下不会触发这个case,所以这个判空其实是没有意义的,并且可以看到整个方法体内是默认GetSession不为空的比如说一开始就调用了SetUserID这个方法。 第二个问题可能是我描述的有些问题,StorageHandler内部如何存储数据确实是开发者自己定义结构就可以的,但是Query这个方法在上面代码块的150行也被调用,而后这个data被传入NewSession方法。
确实会有这个问题,session必须有序列化规范,不过可以用session.Serializable() ([]byte, error) 来解决session序列化问题,别自己去序列化
确实会有这个问题,session必须有序列化规范,不过可以用session.Serializable() ([]byte, error) 来解决session序列化问题,别自己去序列化
是的,这是一种比较好的方案,两个问题其实都可以总结为文档没有明确指出一些约定俗成的规范,框架功能多是一件好事配套的文档如果更完善一些就更好了,感谢作者持续跟进。