实现网页的即时通讯,顺便还可以传输文件,对于聊天使用的TextWebSocketFrame,因为是字符串,也就是序列化反序列化的事,一般都没什么问题。
对于文件传输,首先就考虑到了二进制帧传输
第一个小坑
指定WebSocketServerProtocolHandler的大小太小了,我只给了1m,就导致了传输小文件可以正常传输,文件超过限制就会直接给客户端断掉连接,在调试的时候我一直觉得是前端的问题,也是困扰了好久,最后给每个channel都打上日志才发现文件传输一半给客户端断开连接了。
第二个小坑
这个才是让我最头疼的,,使用二进制帧传输文件必然要用到自定义二进制数据,我的想法也是先用一个int四个字节表示文件名的字节长度,,然后服务端先读取到文件名的长度,接着就能读取文件名了,最后才是文件的二进制数据。二进制数据格式还是很简单的,但是我一调试服务端读取到的int都是值特别大的,显然读取到的不正确,我在前端页面各种调,确定发送的int就是文件名的长度,服务端一直不能匹配,我在服务端也是确定除了使用readInt读取的数据不匹配,后面的二进制数据都是对的。最后查了很多资料才意识到,java默认按照大端字节序去读取存储整数,而JavaScript中,Int32Array是按照本地字节序(通常是小端字节序)来表示整数数组的。
这下问题就解决了,netty处理起来也很方便,使用readIntLE()就可以正常拿到文件名的长度了
最后再列一下大端字节序跟小端字节序的区别:
在小端字节序中,最低有效字节(即数值的最右边字节)被存储在最前面的地址中,而最高有效字节(即数值的最左边字节)被存储在最后面的地址中。例如,当一个 32 位整数 0x12345678 在小端字节序中被存储时,它的四个字节将分别按照 0x78, 0x56, 0x34, 0x12 的顺序存储。
在大端字节序中,最高有效字节被存储在最前面的地址中,而最低有效字节被存储在最后面的地址中。例如,当一个 32 位整数 0x12345678 在大端字节序中被存储时,它的四个字节将分别按照 0x12, 0x34, 0x56, 0x78 的顺序存储。
评论 (0)