为什么80%的码农都做不了架构师?>>>   

本文基于"斗鱼弹幕服务器第三方接入协议V1.6.2"编写

基础准备

接入方式:Socket

API服务地址:openbarrage.douyutv.com:8601

斗鱼私有协议说明

如上图所示,每次发送的消息或者接收到的消息都会由 消息长度 + 消息长度 + 消息类型 + 真实消息内容 + 结尾标识 组成

消息 = 消息长度(4) + 消息长度(4) + 消息类型(4) + 真实消息内容(?) + 结尾标识长度(1)

其中这里要特别说明三个点

一、消息长度的算法,消息长度 = 消息长度(4) + 消息类型(4) + 真实消息内容长度 + 结尾标识长度(1)

二、虽然消息里有 两个消息长度字段,但是如上面的算法所示,计算消息长度是 只需要加 一个 消息长度(4) 字段的长度即可。

三、斗鱼要求的消息长度都为 4 字节小端整数,java中都是大端整数,所以需要通过特别方法转换,我下面都给处理对应的工具代码

int contenLeng = 4 + 4 + content.length() + 1; //消息长度算法

下面开始实际进行接入,先上代码

示例代码

    public static void main(String[] args) throws IOException, InterruptedException {Socket socket = new Socket("openbarrage.douyutv.com", 8601);//发送登录请求(登入9999房间)String loginCMD = "type@=loginreq/roomid@=9999/";send(loginCMD, socket);//读取登录请求消息byte[] bytes = read(socket);String msg = new String(Arrays.copyOfRange(bytes, 0, bytes.length));System.out.println(msg);//加入弹幕分组开始接收弹幕String joinGroupCMD =  "type@=joingroup/rid@=9999/gid@=-9999/";send(joinGroupCMD, socket);//循环读取弹幕消息开始while (true){byte[] msgBytes = read(socket);String s = new String(Arrays.copyOfRange(msgBytes, 0, msgBytes.length));System.out.println(s);Thread.sleep(1);}//关闭链接//socket.close();}

如上面的代码所示,根据斗鱼的弹幕协议的要求,每次想接收弹幕必须

1、进行房间的登录

2、加入任意分组(全量弹幕分组:-9999)

然后即可可进行弹幕消息的接收。

其中 登录 的 API 为 type@=loginreq/roomid@=9999/

加入分组的 API 为 type@=joingroup/rid@=9999/gid@=-9999/

rid 表示房间ID,一般直接用房间号即可

当然根据要求 每隔 45秒 还得发送一次心跳消息进行心跳保持,我这并没有实现,请注意自己补充

全部示例代码

import com.yycdev.douyu.sdk.exceptions.DouYuSDKException;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;public class Test1 {public static void main(String[] args) throws IOException, InterruptedException {Socket socket = new Socket("openbarrage.douyutv.com", 8601);//发送登录请求(登入9999房间)String loginCMD = "type@=loginreq/roomid@=9999/";send(loginCMD, socket);//读取登录请求消息byte[] bytes = read(socket);String msg = new String(Arrays.copyOfRange(bytes, 0, bytes.length));System.out.println(msg);//加入弹幕分组开始接收弹幕String joinGroupCMD =  "type@=joingroup/rid@=9999/gid@=-9999/";send(joinGroupCMD, socket);//循环读取弹幕消息开始while (true){byte[] msgBytes = read(socket);String s = new String(Arrays.copyOfRange(msgBytes, 0, msgBytes.length));System.out.println(s);Thread.sleep(1);}//关闭链接//socket.close();}/*** 发送消息** @param content*/public static void send(String content, Socket socket) {try {//计算消息长度 = 消息长度(4) + 消息类型(4) + 真实消息内容长度 + 结尾标识长度(1)int contenLeng = 4 + 4 + content.length() + 1;//小端模式转换init (长度1)byte[] contenLeng1 = intToBytesLittle(contenLeng);//小端模式转换init (长度2)byte[] contenLeng2 = intToBytesLittle(contenLeng);//小端模式转换init (消息类型) (689:客户端发送给弹幕服务器的文本格式数据)byte[] msgType = intToBytesLittle(689);//标识数据结尾int end = 0;ByteArrayOutputStream byteArray = new ByteArrayOutputStream();//写入长度1byteArray.write(contenLeng1);//写入长度2(与长度1相同)byteArray.write(contenLeng2);//写入消息类型byteArray.write(msgType);//写入消息内容byteArray.write(content.getBytes("ISO-8859-1"));//写入数据结尾标识byteArray.write(end);//发送数据OutputStream out = socket.getOutputStream();out.write(byteArray.toByteArray());out.flush();} catch (IOException e) {throw new DouYuSDKException(e);}}/*** 读取消息** @return*/public static byte[] read(Socket socket) {try {InputStream inputStream = socket.getInputStream();//下条信息的长度int contentLen = 0;//读取前4个字节,得到数据长度byte[] bytes1 = readStream(inputStream,0,4);contentLen = bytesToIntLittle(bytes1, 0); //用小端模式转换byte数组为//System.out.println("数据长度1:" + contentLen);//继续读取4个字节,得到第二个 数据长度byte[] bytes2 = readStream(inputStream,0,4);int contentLen2 = bytesToIntLittle(bytes2, 0);//System.out.println("数据长度2:" + contentLen2);//再次读取4个字节,得到消息类型byte[] bytes3 = readStream(inputStream,0,4);//将小端整数转换为大端整数int msgType = bytesToIntLittle(bytes3, 0);//System.out.println("消息类型:" + msgType);//contentLen = contentLen - 8;//继续读取真正的消息内容int len = 0;        //本次读取数据长度int readLen = 0;    //已读数据长度byte[] bytes = new byte[contentLen];ByteArrayOutputStream byteArray = new ByteArrayOutputStream();while ((len = inputStream.read(bytes, 0, contentLen - readLen)) != -1) {byteArray.write(bytes, 0, len);readLen += len;if (readLen == contentLen) {break;}}return byteArray.toByteArray();} catch (IOException e) {throw new DouYuSDKException(e);}}/*** 计算消息体长度*/private static int calcMessageLength(String content) {return 4 + 4 + (content == null ? 0 : content.length()) + 1;}/*** 以小端模式将int转成byte[]** @param value* @return*/public static byte[] intToBytesLittle(int value) {byte[] src = new byte[4];src[3] = (byte) ((value >> 24) & 0xFF);src[2] = (byte) ((value >> 16) & 0xFF);src[1] = (byte) ((value >> 8) & 0xFF);src[0] = (byte) (value & 0xFF);return src;}/*** 以小端模式将byte[]转成int*/public static int bytesToIntLittle(byte[] src, int offset) {int value;value = (int) ((src[offset] & 0xFF)| ((src[offset + 1] & 0xFF) << 8)| ((src[offset + 2] & 0xFF) << 16)| ((src[offset + 3] & 0xFF) << 24));return value;}/*** 从流中读取数据* @param inputStream* @param off* @param len* @return* @throws IOException*/public static byte[] readStream(InputStream inputStream, int off, int len) throws IOException {byte[] bytes = new byte[len];inputStream.read(bytes, 0, 4);return bytes;}
}

对了顺便推广一下我已经封装好的斗鱼弹幕SDK,欢迎各位直接对接使用

gitee: https://gitee.com/yycdev/douyusdk

github: https://github.com/yyc-dev/douyu-sdk

转载于:https://my.oschina.net/fdblog/blog/1926640

详解-斗鱼弹幕API-接入(斗鱼弹幕服务器第三方接入协议)相关推荐

  1. IOS 多线程04-GCD详解 底层并发 API

    IOS 多线程04-GCD详解 底层并发 API 注:本人是翻译过来,并且加上本人的一点见解. 前言 想要揭示出表面之下深层次的一些可利用的方面.这些底层的 API 提供了大量的灵活性,随之而来的是大 ...

  2. libnuma详解-A NUMA API for LINUX

    参考资料 http://developer.amd.com/wordpress/media/2012/10/LibNUMA-WP-fv1.pdf numa(3) - Linux manual page ...

  3. Java API源码在哪里找_详解查看JAVA API及JAVA源码的方法

    在java的日常学习中,我们有时候会需要看java的api说明,或者是查看java的源码,使我们更好的了解java,接下来我就来说说如何查看java的api以及java源码 对于java的api,一般 ...

  4. 实验详解——DNS反向解析、DNS主服务器和从服务器的配置

    实验详解--DNS反向解析.DNS主服务器和从服务器的配置 实验一:DNS反向解析 1.安装bind 2.查找配置文件路径 3.配置/etc/named.conf主配置文件 4.修改/etc/name ...

  5. 用友系统客户端登录不上服务器,图文详解用友客户端连不上服务器解决方法.pdf...

    图文详解用友客户端连不上服务器解决方法,k3客户端连不上服务器,客户端连不上服务器,u8客户端连不上服务器,用友u8连不上服务器,用友连不上服务器,用友t3连不上服务器,用友u8客户端连不上,gta5 ...

  6. Telnet协议详解及使用C# 用Socket 编程来实现Telnet协议 - Atpking - 博客园

    Telnet协议详解及使用C# 用Socket 编程来实现Telnet协议 - Atpking - 博客园 Telnet协议详解及使用C# 用Socket 编程来实现Telnet协议 - Atpkin ...

  7. java nio详解,Java NIO API详解

    Java NIO API详解 在JDK 1.4以前,Java的IO操作集中在java.io这个包中,是基于流的阻塞(blocking)API.对于大多数应用来说,这样的API使用很方 便,然而,一些对 ...

  8. [Trident] Storm Trident 教程,state详解、trident api详解及实例

    英文原址:https://github.com/nathanmarz/storm/wiki/Trident-tutorial ---------------- Trident是在storm基础上,一个 ...

  9. 工业智能网关BL110详解之八十八: 实现西门子S7-1200 PLC接入华为云平台

    LAN 接口的配置 采集西门子S7-1200 PLC的配置 工业智能网关BL110一共有一 个LAN 接口,一个WAN接口,可以通过LAN 接口采集数据,通过WAN接口接入局域网,设置过程不一样,WA ...

最新文章

  1. 冒泡和快速排序的时间复杂度_排序算法整合(冒泡,快速,希尔,拓扑,归并)
  2. 大学python用什么教材-Python大学教程(普通高等教育十三五规划教材)
  3. php连接plc,PLC 几种常见的连接口和通讯协议
  4. FreeMarker语法指南
  5. python 教学_「Python基础」一次就装好Python手把手装到好
  6. 凸透镜成像动画可拖动_光学实验二:探究凸透镜成像规律
  7. SpringBoot: 注解@Autowired
  8. Setting the Background Image for a List Control
  9. 一起谈.NET技术,在.NET中嵌入IronPython 交互
  10. java手机号正则验证(电信、联通、移动、香港)
  11. 推荐几个e书下载地址
  12. android 屏幕共享 chrome,Chrome屏幕共享功能接入指南
  13. 010editor 过期处理
  14. coffeescript html5,CoffeeScript入门
  15. 信息搜集-读取微信聊天记录
  16. Visual Leak Detector VS2019
  17. 家里安装了两条宽带,有什么方法把两家运营商的宽带聚合起来用?
  18. VMware16安装苹果OS及如何unlock(亲测有效)
  19. IBM超级计算机揭秘最古老英语单词
  20. TCO-PNB ester,1438415-89-4, 反式环辛烯-对硝基苯

热门文章

  1. 停车自助缴费模拟系统c语言,停车场管理系统C语言实现,全动画模拟.doc
  2. UG NX 12 基准点
  3. pandorabox开启ssr_华硕及 PandoraBox 固件如何启用 SSH 和SFTP 连接
  4. ArcGis画简单的行政图的详细步骤
  5. PHP实现个人免签约微信支付接口原理+源码
  6. 牧牛区块链生态,区块链在五大领域的应用
  7. 服务器控制面板显示p1,纬地网络版服务器控制面板使用说明
  8. [开发日志]2d传统动画软件:Tracer
  9. 抖~~音 无水印video 下载
  10. 瑞芯微RK3399嵌入式开发板Wifi 驱动 build in 方式