Closed m2q1n9 closed 8 years ago
现在的那几个判断 构建unity ios版本时 如果开启il2cpp 会编译不过 这个比错误判断问题大多了
能否加个macro来判il2cpp是否开启?
可以判断下是否是ios版本 ios要支持64位一定要开il2cpp的 另外 pack时有时会走到这 偶现 原因未知 https://github.com/lvzixun/sproto-Csharp/blob/master/src/SprotoPack.cs#L130
那个异常是说, 对pack的buffer而言, 最坏情况下每2K字节会多浪费2个字节, 这里的maxsz
是pack后的最大值。如果pack之后发现大小超过了maxsz
将会认为是错误的。
能否提供下对应pack的二进制数据?
周一过去加点log 出现的概率还挺高 游戏挂在那就会出 有的时候能pack出错误数据 然后发到服务端unpack时会挂 我暂时只是过滤了下~
有日志显示SprotoTypeSize.error ("packing error, return size="+this.buffer.Position);
这段代码中的return size
是多少吗?
好像是169
我看了下pack的代码,看上去并不会出现这样的问题。 你那边方便把出现异常的buffer给dump出来吗?有必现的测试数据的话,会好查一些。
https://github.com/lvzixun/sproto-Csharp/blob/master/src/SprotoRpc.cs#L55 从这调过去的 我加些代码把pack前的数据dump下好了 周一上班再搞了 复现还是要看点运气的
pack
本身应该跟sprotoStream
没关系的。你对sprotoStream
的修改我之前也看过,看样子跟pack
没关系的。我觉得,先把pack
出现异常的buffer dump出来看看再说吧。
那个错误数据dump出来了 RPC encode后 01 00 ee 4e 01 00 00 00 58 00 00 00 06 00 00 00 00 00 03 00 00 00 03 00 04 00 0a 00 00 00 31 34 35 30 36 37 38 32 36 35 2a 00 00 00 02 00 00 00 00 00 18 00 00 00 03 00 00 00 40 06 00 00 04 00 00 00 c6 73 02 00 04 00 00 00 a8 7e 02 00 04 00 00 00 1d fd 06 00 0a 00 00 00 04 00 d2 07 01 00 fe 17 02 00
pack后 1d 01 ee 4e 01 11 58 06 44 03 03 c5 04 0a 31 34 ff 00 35 30 36 37 38 32 36 35 11 2a 02 44 18 03 4c 40 06 04 5c c6 73 02 04 5c a8 7e 02 04 5c 1d fd 06 0a 74 04 d2 07 01 07 fe 17 02
Dispatch时就会出异常了
我在云风的lua版本sproto和sproto-csharp中都测试了下上面你提供的数据, 进行pack后跟你提供的数据是一致的。而且都能正常的unpack.
------ raw ------
01 00 EE 4E 01 00 00 00 - 58 00 00 00 06 00 00 00
00 00 03 00 00 00 03 00 - 04 00 0A 00 00 00 31 34
35 30 36 37 38 32 36 35 - 2A 00 00 00 02 00 00 00
00 00 18 00 00 00 03 00 - 00 00 40 06 00 00 04 00
00 00 C6 73 02 00 04 00 - 00 00 A8 7E 02 00 04 00
00 00 1D FD 06 00 0A 00 - 00 00 04 00 D2 07 01 00
FE 17 02 00
---- pack -----
1D 01 EE 4E 01 11 58 06 - 44 03 03 C5 04 0A 31 34
FF 00 35 30 36 37 38 32 - 36 35 11 2A 02 44 18 03
4C 40 06 04 5C C6 73 02 - 04 5C A8 7E 02 04 5C 1D
FD 06 0A 74 04 D2 07 01 - 07 FE 17 02
---- unpack -----
01 00 EE 4E 01 00 00 00 - 58 00 00 00 06 00 00 00
00 00 03 00 00 00 03 00 - 04 00 0A 00 00 00 31 34
35 30 36 37 38 32 36 35 - 2A 00 00 00 02 00 00 00
00 00 18 00 00 00 03 00 - 00 00 40 06 00 00 04 00
00 00 C6 73 02 00 04 00 - 00 00 A8 7E 02 00 04 00
00 00 1D FD 06 00 0A 00 - 00 00 04 00 D2 07 01 00
FE 17 02 00 00 00 00 00 -
你说的跑出异常是说在客户端pack
之后,在服务器那边unpack
dispatch 出现了异常?还是说,客户端这边收到服务器返回的这个pack后的数据, 在客户端unpack后dispatch出现了异常?
byte[] pack_buffer = rpc.spack.pack(rpc.stream.Buffer, len);
try
{
rpc.Dispatch(pack_buffer);
} catch (Exception e)
{
dump_bytes(rpc.stream.Buffer, len);
dump_bytes(pack_buffer, pack_buffer.Length);
}
return pack_buffer;
改了rpc Invoke return前Dispatch了下
可以unpack 可能数据不对
你不应当在invoke
中调用rpc.Dispatch(pack_buffer);
, 对于客户端来说invoke
的含义是client发送给server数据包, dispatch
的含义是分发client接受到server发来的数据包。如果server和client用的协议是两份的话,客户端dispatch
到一个客户端不知道的协议(但是服务器是知道的)确实会出现异常。
我觉得添加异常捕获的地方需要修改下:
客户端:你应该是在网络层接收到服务器发来的数据包,进行client.dispatch
那里try catch
。
服务器:应当在server.dispatch
那里进行try catch
捕获出现无法解析的数据包。
就用一份协议 invoke后的数据 不管发给客户端还是服务端应该都能dispatch解析把? 这个是玩家的状态同步包 服务端验证后会原样同步给场景中的其他客户端
这个dispatch失败出现的概率不是很高
如果是一份的话,确实不论是client还是server都能够正确的dispatch
出来。只要你创建client rpc对象的时候有传入protocol:SprotoRpc client = new SprotoRpc (Protocol.Instance);
。
如果pack,unpack都没问题的话,那有可能是进行decode的时候出现了问题。你那边方便提供下具体协议的定义吗?
byte[] pack_buffer = rpc.spack.pack(rpc.stream.Buffer, len);
try
{
rpc.Dispatch(pack_buffer);
} catch (Exception e)
{
dump_bytes(rpc.stream.Buffer, len);
dump_bytes(pack_buffer, pack_buffer.Length);
}
return pack_buffer;
异常的具体信息能够查看到吗?能否知道是在哪一行出现了问题?
我把那个数据直接Dispatch下 发现是能解出来的。。
目前看应该是Dispatch重入了~
我觉得你可以尝试把try catch
的位置给改下,放到client.dispatch(resp)
那里。
服务器那边最好也加个try catch
,检查下是否从客户端收到错误的包。
之前因为一个bug导致两条socket recv线程在跑 recv会调用Dispatch 导致Dispatch可能重入 出现这个问题 改好后send的时候Invoke里加了try Dispatch catch这个反而掉坑了 因为send和recv也是两条线程。。 目前还没完全确认这个问题 暂时把 try Dispatch catch 删了 确保只有1个地方会Dispatch 看还有没问题 :)
我先把你的提交merge
到master
上面来吧。
il2cpp bug 比较运算符两边都是动态类型时 会导致il2cpp编译器无法静态做类型推导 SprotoStream相关bug 具体看diff