使用netty抓取斗鱼弹幕

有了上两篇的探索,然后又回顾了下netty,用netty写了一个版本。

https://github.com/finghine/douyuDanmu

程序流程

  • 程序入口 Main.java。参考netty的exmpale的factorial中客户端的写法
  • 编码与解码类
    • DyFrameDecoder 按斗鱼的协议把字节流分片组合为字符消息
    • FrameToMessageDecoder 把字符消息转化为key-value的消息
    • Encoder 把字符消息按斗鱼的协议编码为字节流
  • 处理器类 FrameHandler ,在这里相当于业务层的处理位置。只是简单按消息类型输出
  • 消息实体,参考https://github.com/yanglw/DouYuDanmaku ,增加消息类别,做了简化处理

实现细节

编码与解码

在写编码与解码类时花了点时间,把字节流长度算错了。
在decode中要markReaderIndex与resetReaderIndex的使用
当要探测当前流中,是不是把整个数据包与收到了,要先看看当前数据长度,就是读四个四节,但当读之前要mark一下index,如果读了四个字节后,发后readableBytes不够时,要resetReaderIndex,并返回,等下次数来了,再去读。
对netty分层处理更解很重要。

心跳包的处理

本来netty有IdleStateHandler和userEventTriggered来处理心跳包
在这里,没有使用这个方法。
直接回应服务器的qausrespond消息来实现

项目的层次

应该是把消息分为命令消息与界面消息的。
在这里只做了简化处理,用switch处理多类消息。
在这样的场景中可以用多态和责任链模式来处理多类消息。

抽象层次

最开始的时候,把四个字节的长度与服务器发向客户和客户端发向服务器的消息,抽象出来一个frame层。在frame层写编码与解码。后来发现有些多多余,1,size与type在上层中用不到,在该层用了之后,就丢弃。2,每次收发数据就要多一层包装。3,这层数据比较简单,相关数据的计算也是在decoder和encoder中计算的。所以去掉了,直接解成String。
在设计软件时抽象越高,越灵活,但同时增加系统层次。要权衡带来的收益与带来的代价。

后面要做的

[ ] 命令行发弹幕
[ ] 对弹幕的存储分析