Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
live-crawler
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhiwei
live-crawler
Commits
325fad04
Commit
325fad04
authored
Jan 29, 2019
by
zhiwei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改B站、斗鱼、熊猫TV弹幕数据返回形式,及修复获取弹幕时不发心跳的问题
parent
01161ad1
Show whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
406 additions
and
2753 deletions
+406
-2753
src/main/java/com/zhiwei/live/danmu/bilibili/BilibiliClient.java
+1
-21
src/main/java/com/zhiwei/live/danmu/bilibili/BilibiliMessageHandler.java
+6
-3
src/main/java/com/zhiwei/live/danmu/bilibili/BilibiliMessageListener.java
+0
-13
src/main/java/com/zhiwei/live/danmu/douyu/DouYuApi.java
+0
-18
src/main/java/com/zhiwei/live/danmu/douyu/DouYuClient.java
+0
-252
src/main/java/com/zhiwei/live/danmu/douyu/DouYuMessage.java
+101
-0
src/main/java/com/zhiwei/live/danmu/douyu/DouyuClient.java
+45
-0
src/main/java/com/zhiwei/live/danmu/douyu/DouyuMessageHandler.java
+118
-0
src/main/java/com/zhiwei/live/danmu/douyu/Main.java
+0
-52
src/main/java/com/zhiwei/live/danmu/douyu/Message.java
+0
-85
src/main/java/com/zhiwei/live/danmu/douyu/MessageHandler.java
+0
-92
src/main/java/com/zhiwei/live/danmu/douyu/MessageListener.java
+0
-29
src/main/java/com/zhiwei/live/danmu/douyu/constants/DouYuConstants.java
+0
-17
src/main/java/com/zhiwei/live/danmu/douyu/constants/MsgType.java
+0
-51
src/main/java/com/zhiwei/live/danmu/douyu/entity/BaseMsg.java
+0
-59
src/main/java/com/zhiwei/live/danmu/douyu/entity/ChatMsg.java
+0
-403
src/main/java/com/zhiwei/live/danmu/douyu/entity/DgbMsg.java
+0
-242
src/main/java/com/zhiwei/live/danmu/douyu/entity/ErrorMsg.java
+0
-85
src/main/java/com/zhiwei/live/danmu/douyu/entity/GgbbMsg.java
+0
-159
src/main/java/com/zhiwei/live/danmu/douyu/entity/MsgEntity.java
+0
-20
src/main/java/com/zhiwei/live/danmu/douyu/entity/SpbcMsg.java
+0
-214
src/main/java/com/zhiwei/live/danmu/douyu/entity/SsdMsg.java
+0
-116
src/main/java/com/zhiwei/live/danmu/douyu/entity/UenterMsg.java
+0
-184
src/main/java/com/zhiwei/live/danmu/douyu/enums/NobleLevel.java
+0
-26
src/main/java/com/zhiwei/live/danmu/douyu/exceptions/DouYuSDKException.java
+0
-19
src/main/java/com/zhiwei/live/danmu/douyu/exceptions/UtilException.java
+0
-43
src/main/java/com/zhiwei/live/danmu/douyu/listener/DefaultBaseMsgListener.java
+0
-24
src/main/java/com/zhiwei/live/danmu/douyu/listener/DefaultChatMsgListener.java
+0
-23
src/main/java/com/zhiwei/live/danmu/douyu/util/ArrayUtil.java
+0
-116
src/main/java/com/zhiwei/live/danmu/douyu/util/DataUtil.java
+0
-48
src/main/java/com/zhiwei/live/danmu/douyu/util/ReflectUtil.java
+0
-161
src/main/java/com/zhiwei/live/danmu/douyu/util/SimpleCache.java
+0
-87
src/main/java/com/zhiwei/live/danmu/douyu/util/UUIDUtil.java
+0
-31
src/main/java/com/zhiwei/live/danmu/pandam/PandamClient.java
+12
-5
src/main/java/com/zhiwei/live/danmu/pandam/PandamMessage.java
+1
-1
src/main/java/com/zhiwei/live/danmu/pandam/PandamMessageHandler.java
+9
-4
src/main/java/com/zhiwei/live/danmu/pandamtv/PandamMessageListener.java
+0
-12
src/main/java/com/zhiwei/live/danmu/util/DataCallBack.java
+9
-2
src/main/java/com/zhiwei/live/danmu/util/DouYuUtil.java
+2
-36
src/main/java/com/zhiwei/live/roominfo/DouYuRoomInfoCrawler.java
+23
-0
src/test/java/com/zhiwei/live/test/danmu/BilibiliDanMuTest.java
+26
-0
src/test/java/com/zhiwei/live/test/danmu/DouYuDanMuTest.java
+26
-0
src/test/java/com/zhiwei/live/test/danmu/PanDamDanMuTest.java
+27
-0
No files found.
src/main/java/com/zhiwei/live/danmu/bilibili/BilibiliClient.java
View file @
325fad04
...
...
@@ -12,6 +12,7 @@ import com.zhiwei.crawler.core.HttpBoot;
import
com.zhiwei.crawler.core.RequestUtils
;
import
com.zhiwei.live.bean.RoomInfo
;
import
com.zhiwei.live.danmu.util.Connector
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
import
com.zhiwei.live.roominfo.BilibiliRoomInfoCrawler
;
import
io.netty.channel.nio.NioEventLoopGroup
;
...
...
@@ -25,27 +26,6 @@ public class BilibiliClient {
private
static
Logger
logger
=
LogManager
.
getLogger
(
BilibiliClient
.
class
);
private
static
final
int
PORT
=
2243
;
public
static
void
main
(
String
[]
args
)
throws
InterruptedException
{
String
roomUrl
=
"https://live.bilibili.com/139"
;
String
roomId
=
roomUrl
.
replaceAll
(
"https://live.bilibili.com/"
,
""
);
try
{
getDanmu
(
new
DataCallBack
()
{
@Override
public
void
onData
(
BilibiliMessage
data
)
{
System
.
out
.
println
(
"-------------"
+
data
.
toString
());
}
},
roomId
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
/**
* 根据房间号获取弹幕信息
* @param roomId
...
...
src/main/java/com/zhiwei/live/danmu/bilibili/BilibiliMessageHandler.java
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
bilibili
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
org.apache.commons.lang3.StringUtils
;
import
com.alibaba.fastjson.JSONObject
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.buffer.ByteBufUtil
;
...
...
@@ -22,7 +25,7 @@ public class BilibiliMessageHandler extends ChannelInboundHandlerAdapter{
private
static
final
byte
[]
BILI_IN
=
new
byte
[]
{
0x00
,
0x10
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x07
,
0x00
,
0x00
,
0x00
,
0x01
};
private
static
final
byte
[]
PING
=
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x1F
,
0x00
,
0x10
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x02
,
0x00
,
0x00
,
0x00
,
0x01
,
0x5B
,
0x6F
,
0x62
,
0x6A
,
0x65
,
0x63
,
0x74
,
0x20
,
0x4F
,
0x62
,
0x6A
,
0x65
,
0x63
,
0x74
,
0x5D
};
private
static
Pattern
pattern
=
Pattern
.
compile
(
"\\{\"cmd\":\"DANMU_MSG.+?\\]\\}"
);
private
String
room
i
d
;
private
String
room
I
d
;
private
DataCallBack
dataCallBack
;
/**
...
...
@@ -33,7 +36,7 @@ public class BilibiliMessageHandler extends ChannelInboundHandlerAdapter{
*/
public
BilibiliMessageHandler
(
DataCallBack
dataCallBack
,
String
roomid
)
{
this
.
dataCallBack
=
dataCallBack
;
this
.
room
id
=
roomid
;
this
.
room
Id
=
requireNonNull
(
roomid
,
"roomId is null"
)
;
}
/*
...
...
@@ -45,7 +48,7 @@ public class BilibiliMessageHandler extends ChannelInboundHandlerAdapter{
public
void
channelActive
(
ChannelHandlerContext
ctx
)
throws
Exception
{
System
.
out
.
println
(
"TCP 连接建立成功: "
+
ctx
.
channel
());
byte
[]
body
=
StringUtils
.
join
(
"{\"uid\":0,\"roomid\":"
,
room
i
d
,
",\"protover\":1,\"platform\":\"web\",\"clientver\":\"1.5.15\"}"
)
.
join
(
"{\"uid\":0,\"roomid\":"
,
room
I
d
,
",\"protover\":1,\"platform\":\"web\",\"clientver\":\"1.5.15\"}"
)
.
getBytes
();
ByteBuf
loginMsg
=
Unpooled
.
wrappedBuffer
(
Unpooled
.
wrappedBuffer
(
FIRST_REQ
)
,
Unpooled
.
buffer
(
1
).
writeByte
(
body
.
length
+
16
),
Unpooled
.
wrappedBuffer
(
BILI_IN
),
Unpooled
.
wrappedBuffer
(
body
));
...
...
src/main/java/com/zhiwei/live/danmu/bilibili/BilibiliMessageListener.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
bilibili
;
import
java.util.List
;
import
java.util.Vector
;
public
class
BilibiliMessageListener
{
public
static
List
<
BilibiliMessage
>
messages
=
new
Vector
<>();
public
static
void
addMessages
(
BilibiliMessage
bilibiliMessage
)
{
messages
.
add
(
bilibiliMessage
);
}
}
src/main/java/com/zhiwei/live/danmu/douyu/DouYuApi.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
/**
*
* 功能描述:斗鱼弹幕服务API
* 基于(斗鱼弹幕服务器第三方接入协议v1.6.2)开发
*
* @auther: coffee
* @date: 2018-07-04 15:45:56
* 修改日志:
*
*/
public
class
DouYuApi
{
public
static
String
LOGIN_REQ
=
"type@=loginreq/roomid@=%s/"
;
public
static
String
JOIN_GROUP
=
"type@=joingroup/rid@=%s/gid@=%s/"
;
public
static
String
KEEP_LIVE
=
"type@=mrkl/"
;
public
static
String
LOGOUT
=
"type@=logout/"
;
}
src/main/java/com/zhiwei/live/danmu/douyu/DouYuClient.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
import
java.io.IOException
;
import
java.net.InetSocketAddress
;
import
java.net.Socket
;
import
java.net.SocketAddress
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.zhiwei.crawler.proxy.ProxyHolder
;
import
com.zhiwei.live.danmu.douyu.constants.DouYuConstants
;
import
com.zhiwei.live.danmu.douyu.constants.MsgType
;
import
com.zhiwei.live.danmu.douyu.entity.BaseMsg
;
import
com.zhiwei.live.danmu.douyu.entity.ChatMsg
;
import
com.zhiwei.live.danmu.douyu.entity.DgbMsg
;
import
com.zhiwei.live.danmu.douyu.entity.ErrorMsg
;
import
com.zhiwei.live.danmu.douyu.entity.GgbbMsg
;
import
com.zhiwei.live.danmu.douyu.entity.MsgEntity
;
import
com.zhiwei.live.danmu.douyu.entity.SpbcMsg
;
import
com.zhiwei.live.danmu.douyu.entity.SsdMsg
;
import
com.zhiwei.live.danmu.douyu.entity.UenterMsg
;
import
com.zhiwei.live.danmu.douyu.exceptions.DouYuSDKException
;
import
com.zhiwei.live.danmu.douyu.util.DataUtil
;
import
com.zhiwei.live.danmu.douyu.util.STTUtil
;
import
com.zhiwei.live.danmu.douyu.util.UUIDUtil
;
/**
* 功能描述:斗鱼SDK
*
* @auther: coffee
* @date: 2018-07-04 15:19:51
* 修改日志:
*/
public
class
DouYuClient
{
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
DouYuClient
.
class
);
private
String
host
;
//API Host
private
int
port
;
//API 端口
private
String
roomId
;
//房间ID(房间号)
private
String
groupId
=
DouYuConstants
.
MASSIVE_GID
;
//分组ID
private
Socket
socket
;
//通讯socket对象
private
Thread
dataSyncThread
;
//异步读取消息线程
private
Boolean
isExitMark
=
false
;
//退出标记
private
MessageHandler
messageHandler
;
private
List
<
MessageListener
>
messageListenerList
=
new
ArrayList
<>();
public
DouYuClient
(
String
host
,
int
port
,
String
roomId
)
{
this
.
host
=
host
;
this
.
port
=
port
;
this
.
roomId
=
roomId
;
//初始化
this
.
init
();
}
public
DouYuClient
(
String
roomId
)
{
this
.
host
=
"openbarrage.douyutv.com"
;
this
.
port
=
8601
;
this
.
roomId
=
roomId
;
//初始化
this
.
init
();
}
/**
* 初始化Client
*/
private
void
init
()
{
logger
.
info
(
"初始化斗鱼SDK_Client..."
);
this
.
connect
();
}
/**
* 打开socket连接
*/
private
void
connect
()
{
try
{
logger
.
info
(
"从服务器({}:{})获取弹幕服务器数据"
,
host
,
port
);
socket
=
new
Socket
(
ProxyHolder
.
NAT_PROXY
.
getProxy
());
socket
.
connect
(
new
InetSocketAddress
(
host
,
port
));
messageHandler
=
new
MessageHandler
(
socket
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
/**
* 登入斗鱼弹幕服务器
*/
public
DouYuClient
login
()
{
logger
.
info
(
"登录房间 {}"
,
roomId
);
String
content
=
String
.
format
(
DouYuApi
.
LOGIN_REQ
,
roomId
);
messageHandler
.
send
(
content
);
return
this
;
}
/**
* 加入房间分组并接收房间消息
*
* @return
*/
private
DouYuClient
joinGroup
(
String
groupId
)
{
if
(
DouYuConstants
.
MASSIVE_GID
.
equals
(
groupId
))
{
logger
.
info
(
"开启海量弹幕接收模式"
);
}
else
{
logger
.
info
(
"关闭海量弹幕接收模式"
);
}
logger
.
info
(
"加入分组({})并开始接收消息"
,
groupId
);
String
content
=
String
.
format
(
DouYuApi
.
JOIN_GROUP
,
roomId
,
groupId
);
messageHandler
.
send
(
content
);
return
this
;
}
/**
* 注册消息监听器
*
* @param messageListener
* @return
*/
public
DouYuClient
registerMessageListener
(
MessageListener
messageListener
)
{
logger
.
info
(
"注册消息监听器:{}"
,
messageListener
.
getClass
());
this
.
messageListenerList
.
add
(
messageListener
);
return
this
;
}
/**
* 开始同步并接收房间消息
*/
public
DouYuClient
sync
()
{
//加入海量弹幕分组,接收所有消息
this
.
joinGroup
(
groupId
);
//开启异步线程接收房间消息
dataSyncThread
=
new
Thread
(
new
Runnable
()
{
@Override
public
void
run
()
{
long
start
=
System
.
currentTimeMillis
();
while
(
true
)
{
//判断是否退出线程
if
(
isExitMark
==
true
)
{
break
;
}
//读取弹幕消息
byte
[]
bytes
=
messageHandler
.
read
();
String
msg
=
new
String
(
Arrays
.
copyOfRange
(
bytes
,
8
,
bytes
.
length
));
//获取消息类型
String
msgType
=
DataUtil
.
getMsgType
(
msg
);
if
(
msgType
==
null
)
{
logger
.
error
(
"获取消息类型失败,消息:{}"
,
msg
);
continue
;
}
//封装基础消息对象
BaseMsg
msgBase
=
new
BaseMsg
();
msgBase
.
setUuid
(
UUIDUtil
.
simpleUUID
());
msgBase
.
setType
(
msgType
);
msgBase
.
setMessage
(
msg
);
//根据不同的消息类型 序列化不同的 实体对象
MsgEntity
entity
=
null
;
if
(
MsgType
.
CHAT_MSG
.
equals
(
msgType
))
{
entity
=
STTUtil
.
toBean
(
msg
,
ChatMsg
.
class
);
}
else
if
(
MsgType
.
DGB
.
equals
(
msgType
))
{
entity
=
STTUtil
.
toBean
(
msg
,
DgbMsg
.
class
);
}
else
if
(
MsgType
.
GGBB
.
equals
(
msgType
))
{
entity
=
STTUtil
.
toBean
(
msg
,
GgbbMsg
.
class
);
}
else
if
(
MsgType
.
SPBC
.
equals
(
msgType
))
{
entity
=
STTUtil
.
toBean
(
msg
,
SpbcMsg
.
class
);
}
else
if
(
MsgType
.
SSD
.
equals
(
msgType
))
{
entity
=
STTUtil
.
toBean
(
msg
,
SsdMsg
.
class
);
}
else
if
(
MsgType
.
UENTER
.
equals
(
msgType
))
{
entity
=
STTUtil
.
toBean
(
msg
,
UenterMsg
.
class
);
}
else
if
(
MsgType
.
ERROR
.
equals
(
msgType
))
{
entity
=
STTUtil
.
toBean
(
msg
,
ErrorMsg
.
class
);
}
if
(
entity
!=
null
)
{
entity
.
setMessage
(
msg
);
entity
.
setUuid
(
msgBase
.
getUuid
());
}
//消息监听器处理
for
(
MessageListener
messageListener
:
messageListenerList
)
{
try
{
//基础消息监听器处理
if
(
messageListener
.
getMsgClazz
()
==
BaseMsg
.
class
)
{
messageListener
.
read
(
msgBase
);
}
//指定类型消息监听器处理
else
if
(
entity
!=
null
&&
messageListener
.
getMsgClazz
()
==
entity
.
getClass
())
{
messageListener
.
read
(
entity
);
}
//String消息监听器处理
else
if
(
messageListener
.
getMsgClazz
()
==
String
.
class
)
{
messageListener
.
read
(
msg
);
}
}
catch
(
Exception
e
)
{
logger
.
error
(
"消息处理出现异常:"
,
e
);
}
}
//发送心跳消息保持通道
long
end
=
System
.
currentTimeMillis
();
if
(
end
-
start
>
30000
)
{
doKeepLive
();
start
=
System
.
currentTimeMillis
();
}
//休眠1毫秒
try
{
Thread
.
sleep
(
1
);
}
catch
(
InterruptedException
e
)
{
throw
new
DouYuSDKException
(
e
);
}
}
//客户端关闭,断开socket通道
messageHandler
.
close
();
logger
.
info
(
"斗鱼弹幕SDK客户端已成功退出"
);
}
});
dataSyncThread
.
start
();
return
this
;
}
/**
* 发送心跳消息,保持通道
*/
public
void
doKeepLive
()
{
String
content
=
String
.
format
(
DouYuApi
.
KEEP_LIVE
);
logger
.
info
(
"发送心跳信息,保持通道中..."
);
messageHandler
.
send
(
content
);
}
/**
* 发送登出消息,用于退出
*/
public
void
logout
(){
String
content
=
String
.
format
(
DouYuApi
.
LOGOUT
);
logger
.
info
(
"发送登出消息中..."
);
messageHandler
.
send
(
content
);
}
public
void
exit
()
{
logout
();
isExitMark
=
true
;
logger
.
info
(
"斗鱼弹幕SDK客户端正在退出中..."
);
}
}
src/main/java/com/zhiwei/live/danmu/douyu/DouYuMessage.java
0 → 100644
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
import
java.util.Date
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
public
class
DouYuMessage
{
String
messageType
;
//弹幕消息类型
String
user_id
;
//发布者uid
String
nickName
;
//发布者昵称
Date
time
;
//弹幕时间
String
content
;
//弹幕内容
String
room_id
;
//房间id
public
DouYuMessage
(
JSONObject
json
)
throws
Exception
{
constructJson
(
json
);
}
public
DouYuMessage
(){
}
private
void
constructJson
(
JSONObject
json
)
throws
Exception
{
try
{
user_id
=
json
.
getString
(
"uid"
);
time
=
new
Date
();
nickName
=
json
.
getString
(
"nn"
);
content
=
json
.
getString
(
"txt"
);
room_id
=
json
.
getString
(
"rid"
);
}
catch
(
Exception
e
)
{
throw
new
Exception
();
}
}
@Override
public
String
toString
()
{
return
"new BilibiliMessage["
+
"user_id = "
+
user_id
+
", nickName = "
+
nickName
+
", time = "
+
time
+
", content = "
+
content
+
", room_id = "
+
room_id
+
"]"
;
}
public
Date
getTime
()
{
return
time
;
}
public
void
setTime
(
Date
time
)
{
this
.
time
=
time
;
}
public
String
getMessageType
()
{
return
messageType
;
}
public
String
getUser_id
()
{
return
user_id
;
}
public
String
getNickName
()
{
return
nickName
;
}
public
String
getContent
()
{
return
content
;
}
public
void
setMessageType
(
String
messageType
)
{
this
.
messageType
=
messageType
;
}
public
void
setUser_id
(
String
user_id
)
{
this
.
user_id
=
user_id
;
}
public
void
setNickName
(
String
nickName
)
{
this
.
nickName
=
nickName
;
}
public
void
setContent
(
String
content
)
{
this
.
content
=
content
;
}
public
String
getRoom_id
()
{
return
room_id
;
}
public
void
setRoom_id
(
String
room_id
)
{
this
.
room_id
=
room_id
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/DouyuClient.java
0 → 100644
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
import
java.util.Objects
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
com.zhiwei.live.bean.RoomInfo
;
import
com.zhiwei.live.danmu.util.Connector
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
import
com.zhiwei.live.roominfo.DouYuRoomInfoCrawler
;
import
io.netty.channel.nio.NioEventLoopGroup
;
import
io.netty.handler.timeout.IdleStateHandler
;
/**
* @ClassName: DouyuClient
* @Description: TODO
* @author 0xff
* @date Jan 25, 2019 10:57:49 AM
*/
public
class
DouyuClient
{
private
static
Logger
logger
=
LogManager
.
getLogger
(
DouyuClient
.
class
);
private
static
final
int
PORT
=
8601
;
private
static
final
String
HOST
=
"openbarrage.douyutv.com"
;
/**
* 根据房间号获取弹幕信息
*
* @param roomId
* @throws Exception
*/
public
static
void
getDanmu
(
DataCallBack
dataCallBack
,
String
roomId
)
throws
Exception
{
// 根据房间号获取真实房间号
RoomInfo
roomInfo
=
DouYuRoomInfoCrawler
.
getRoomInfoByRoomId
(
roomId
);
if
(
Objects
.
nonNull
(
roomInfo
))
{
// 建立弹幕连接
Connector
.
asynchronizedTcpConnect
(
new
NioEventLoopGroup
(),
HOST
,
PORT
,
new
IdleStateHandler
(
0
,
30
,
45
),
new
DouyuMessageHandler
(
dataCallBack
,
roomInfo
.
getRoomId
())).
sync
();
}
else
{
logger
.
info
(
"获取真实房间号出现问题,请及时检查程序"
);
}
}
}
src/main/java/com/zhiwei/live/danmu/douyu/DouyuMessageHandler.java
0 → 100644
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
java.util.Map
;
import
org.apache.commons.lang3.StringUtils
;
import
com.alibaba.fastjson.JSONObject
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
import
com.zhiwei.live.danmu.util.DouYuUtil
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.buffer.ByteBufUtil
;
import
io.netty.buffer.Unpooled
;
import
io.netty.channel.Channel
;
import
io.netty.channel.ChannelFutureListener
;
import
io.netty.channel.ChannelHandlerContext
;
import
io.netty.channel.ChannelInboundHandlerAdapter
;
import
io.netty.handler.timeout.IdleState
;
import
io.netty.handler.timeout.IdleStateEvent
;
import
io.netty.util.CharsetUtil
;
import
io.netty.util.ReferenceCountUtil
;
/**
* @ClassName: WebSocketMessageHandler
* @Description: TODO
* @author 0xff
* @date Jan 25, 2019 11:03:20 AM
*/
public
class
DouyuMessageHandler
extends
ChannelInboundHandlerAdapter
{
private
String
roomId
;
private
boolean
finish
;
private
DataCallBack
dataCallBack
;
/**
* Constructor
*
* @param roomId
* 房间号
*/
public
DouyuMessageHandler
(
DataCallBack
dataCallBack
,
String
roomid
)
{
this
.
dataCallBack
=
dataCallBack
;
this
.
roomId
=
requireNonNull
(
roomId
,
"roomId is null"
);
}
/*
* @see
* io.netty.channel.ChannelInboundHandlerAdapter#channelActive(io.netty.channel.
* ChannelHandlerContext)
*/
@Override
public
void
channelActive
(
ChannelHandlerContext
ctx
)
throws
Exception
{
System
.
out
.
println
(
"TCP 连接建立成功: "
+
ctx
.
channel
());
Channel
channel
=
ctx
.
channel
();
ByteBuf
loginMsg
=
buildMsg
(
StringUtils
.
join
(
"type@=loginreq/roomid@="
,
roomId
,
"/"
));
System
.
out
.
println
(
"发送登录消息: \n"
+
ByteBufUtil
.
prettyHexDump
(
loginMsg
));
channel
.
writeAndFlush
(
loginMsg
).
addListener
((
ChannelFutureListener
)
future
->
{
if
(!
future
.
isSuccess
())
{
System
.
out
.
println
(
"发送登录消息失败"
);
}
});
}
/*
* @see io.netty.channel.ChannelInboundHandlerAdapter#channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object)
*/
@Override
public
void
channelRead
(
ChannelHandlerContext
ctx
,
Object
msg
)
throws
Exception
{
if
(
msg
instanceof
ByteBuf
)
{
ByteBuf
buf
=
(
ByteBuf
)
msg
;
String
source
=
buf
.
toString
(
CharsetUtil
.
UTF_8
);
// System.out.println("source========="+source);
if
(
source
.
contains
(
"chatmsg"
))
{
Map
<
String
,
Object
>
messageMap
=
DouYuUtil
.
toMap
(
source
);
String
data
=
JSONObject
.
toJSONString
(
messageMap
);
JSONObject
messagesJson
=
JSONObject
.
parseObject
(
data
);
DouYuMessage
douYuMessage
=
new
DouYuMessage
(
messagesJson
);
System
.
out
.
println
(
douYuMessage
.
getContent
());
}
}
ReferenceCountUtil
.
release
(
msg
);
if
(!
finish
)
{
ByteBuf
groupMsg
=
buildMsg
(
StringUtils
.
join
(
"type@=joingroup/rid@="
,
roomId
,
"/gid@=-9999/"
));
System
.
out
.
println
(
"发送入组消息: \n"
+
ByteBufUtil
.
prettyHexDump
(
groupMsg
));
ctx
.
writeAndFlush
(
groupMsg
);
finish
=
true
;
}
ctx
.
fireChannelRead
(
msg
);
}
/*
* @see io.netty.channel.ChannelInboundHandlerAdapter#userEventTriggered(io.netty.channel.ChannelHandlerContext, java.lang.Object)
*/
@Override
public
void
userEventTriggered
(
ChannelHandlerContext
ctx
,
Object
evt
)
throws
Exception
{
if
(
evt
instanceof
IdleStateEvent
)
{
IdleStateEvent
event
=
(
IdleStateEvent
)
evt
;
if
(
event
.
state
()
==
IdleState
.
WRITER_IDLE
)
{
ByteBuf
pingMsg
=
buildMsg
(
StringUtils
.
join
(
"type@=keeplive/tick@="
,
System
.
currentTimeMillis
()
/
1000
,
"/"
));
System
.
out
.
println
(
"发送心跳消息: \n"
+
ByteBufUtil
.
prettyHexDump
(
pingMsg
));
ctx
.
writeAndFlush
(
pingMsg
);
}
else
{
ctx
.
fireUserEventTriggered
(
evt
);
}
}
else
{
ctx
.
fireUserEventTriggered
(
evt
);
}
}
private
ByteBuf
buildMsg
(
String
content
)
{
int
fixedLen
=
4
+
4
+
1
;
byte
[]
body
=
content
.
getBytes
(
CharsetUtil
.
UTF_8
);
int
length
=
fixedLen
+
body
.
length
;
return
Unpooled
.
buffer
(
length
).
writeIntLE
(
length
).
writeIntLE
(
length
).
writeShortLE
(
689
)
.
writeShortLE
(
0
).
writeBytes
(
body
).
writeByte
(
'\0'
);
}
}
src/main/java/com/zhiwei/live/danmu/douyu/Main.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.zhiwei.common.config.GroupType
;
import
com.zhiwei.crawler.proxy.ProxyFactory
;
import
com.zhiwei.live.danmu.douyu.entity.ChatMsg
;
/**
* 功能描述:
*
* @auther: coffee
* @date: 2018-07-04 19:37:41
* 修改日志:
*/
public
class
Main
{
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
Main
.
class
);
private
static
final
String
registry
=
"zookeeper://192.168.0.36:2181"
;
private
static
final
String
group
=
"local"
;
static
{
ProxyFactory
.
init
(
registry
,
group
,
GroupType
.
PROVIDER
);
}
public
static
void
main
(
String
[]
args
)
throws
InterruptedException
{
DouYuClient
client
=
new
DouYuClient
(
"3084150"
);
client
.
registerMessageListener
(
new
MessageListener
<
ChatMsg
>()
{
@Override
public
void
read
(
ChatMsg
message
)
{
//logger.info(message.toChatStr());
// System.out.println(message.toChatStr());
}
});
client
.
registerMessageListener
(
new
MessageListener
<
String
>()
{
@Override
public
void
read
(
String
message
)
{
System
.
out
.
println
(
message
);
// logger.info(message);
}
});
client
.
login
();
client
.
sync
();
Thread
.
sleep
(
30000
);
client
.
exit
();
}
}
src/main/java/com/zhiwei/live/danmu/douyu/Message.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.util.Arrays
;
/**
*
* 功能描述:斗鱼消息实体
*
* @auther: coffee
* @date: 2018-07-04 15:06:45
* 修改日志:
*
*/
public
class
Message
{
/**
* 请求消息体包含五部分:
* 1.计算后四部分的字节长度,占4个字节
* 2.内容同上
* 3.请求代码,固定,发到斗鱼是0xb1,0x02,0x00,0x00,接收是0xb2,0x02,0x00,0x00,4个字节
* 4.消息正文
* 5.尾部1个空字节
*/
private
int
[]
length1
;
private
int
[]
length2
;
private
int
[]
magic
;
private
String
content
;
private
int
[]
end
;
public
Message
(
String
content
)
{
length1
=
new
int
[]{
calcMessageLength
(
content
),
0x00
,
0x00
,
0x00
};
length2
=
new
int
[]{
calcMessageLength
(
content
),
0x00
,
0x00
,
0x00
};
magic
=
new
int
[]{
0xb1
,
0x02
,
0x00
,
0x00
};
this
.
content
=
content
;
end
=
new
int
[]{
0x00
};
}
/**
* 计算消息体长度
*/
private
int
calcMessageLength
(
String
content
)
{
return
4
+
4
+
(
content
==
null
?
0
:
content
.
length
())
+
1
;
}
@Override
public
String
toString
()
{
return
"Message{"
+
"length1="
+
Arrays
.
toString
(
length1
)
+
", length2="
+
Arrays
.
toString
(
length2
)
+
", magic="
+
Arrays
.
toString
(
magic
)
+
", content='"
+
content
+
'\''
+
", end="
+
Arrays
.
toString
(
end
)
+
'}'
;
}
/**
* 将Message对象转化为字节数组
*/
public
byte
[]
getBytes
()
throws
IOException
{
ByteArrayOutputStream
byteArray
=
new
ByteArrayOutputStream
();
//写入长度1
for
(
int
b
:
length1
){
byteArray
.
write
(
b
);
}
//写入长度2
for
(
int
b
:
length2
){
byteArray
.
write
(
b
);
}
//写入消息类型
for
(
int
b
:
magic
){
byteArray
.
write
(
b
);
}
//写入消息内容
if
(
content
!=
null
){
byteArray
.
write
(
content
.
getBytes
(
"ISO-8859-1"
));
}
//写入尾部结束符
for
(
int
b
:
end
){
byteArray
.
write
(
b
);
}
return
byteArray
.
toByteArray
();
}
}
src/main/java/com/zhiwei/live/danmu/douyu/MessageHandler.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.net.Socket
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.zhiwei.live.danmu.douyu.exceptions.DouYuSDKException
;
/**
* 功能描述:消息处理助手
*
* @auther: coffee
* @date: 2018-07-04 15:11:13
* 修改日志:
*/
public
class
MessageHandler
{
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
MessageHandler
.
class
);
private
Socket
socket
;
public
MessageHandler
(
Socket
socket
)
{
this
.
socket
=
socket
;
}
/**
* 发送消息
*
* @param content
*/
public
void
send
(
String
content
)
{
try
{
Message
message
=
new
Message
(
content
);
OutputStream
out
=
socket
.
getOutputStream
();
out
.
write
(
message
.
getBytes
());
out
.
flush
();
}
catch
(
IOException
e
)
{
throw
new
DouYuSDKException
(
e
);
}
}
/**
* 读取消息
*
* @return
*/
public
byte
[]
read
(){
try
{
InputStream
inputStream
=
socket
.
getInputStream
();
//下条信息的长度
int
contentLen
=
0
;
//读取前4个字节,得到数据长度
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
int
tmp
=
inputStream
.
read
();
contentLen
+=
tmp
*
Math
.
pow
(
16
,
2
*
i
);
}
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
);
}
}
/**
* 关闭socket通道
*
* @throws IOException
*/
public
void
close
(){
try
{
socket
.
close
();
}
catch
(
IOException
e
)
{
logger
.
warn
(
"socket通道关闭异常"
,
e
);
}
}
}
src/main/java/com/zhiwei/live/danmu/douyu/MessageListener.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
;
import
java.lang.reflect.ParameterizedType
;
/**
* 功能描述:消息监听器
*
* @auther: coffee
* @date: 2018-07-04 16:22:22
* 修改日志:
*/
public
abstract
class
MessageListener
<
T
>
{
private
Class
<
T
>
msgClazz
;
public
MessageListener
()
{
ParameterizedType
type
=
(
ParameterizedType
)
this
.
getClass
().
getGenericSuperclass
();
this
.
msgClazz
=
(
Class
<
T
>)
type
.
getActualTypeArguments
()[
0
];
}
/**
* 消息读取
*/
public
abstract
void
read
(
T
message
);
public
Class
<
T
>
getMsgClazz
()
{
return
msgClazz
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/constants/DouYuConstants.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
constants
;
/**
*
* 功能描述:斗鱼常量
*
* @auther: coffee
* @date: 2018-07-06 11:27:32
* 修改日志:
*
*/
public
class
DouYuConstants
{
//海量弹幕分组
public
final
static
String
MASSIVE_GID
=
"-9999"
;
}
src/main/java/com/zhiwei/live/danmu/douyu/constants/MsgType.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
constants
;
/**
*
* 功能描述:消息类型
*
* @auther: coffee
* @date: 2018-07-07 16:22:36
* 修改日志:
*
*/
public
class
MsgType
{
//登录响应
public
static
final
String
LOGIN_RES
=
"loginres"
;
//服务心跳响应
public
static
final
String
KEEP_LIVE
=
"loginres"
;
//弹幕消息
public
static
final
String
CHAT_MSG
=
"chatmsg"
;
//领取鱼丸暴击
public
static
final
String
ONLINE_GIFT
=
"onlinegift"
;
//赠送礼物消息
public
static
final
String
DGB
=
"dgb"
;
//用户进入房间
public
static
final
String
UENTER
=
"uenter"
;
//房间开播关播
public
static
final
String
RSS
=
"rss"
;
//房间贡献排行榜更新广播
public
static
final
String
RANK_LIST
=
"ranklist"
;
//超级弹幕
public
static
final
String
SSD
=
"ssd"
;
//房间内礼物广播
public
static
final
String
SPBC
=
"spbc"
;
//房间用户抢红包
public
static
final
String
GGBB
=
"ggbb"
;
//房间分区排名变化消息
public
static
final
String
RANK_UP
=
"rankup"
;
//错误信息
public
static
final
String
ERROR
=
"error"
;
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/BaseMsg.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
* 功能描述:通用消息实体
*
* @auther: coffee
* @date: 2018-07-07 17:16:27
* 修改日志:
*/
public
class
BaseMsg
implements
MsgEntity
{
private
String
uuid
;
private
String
type
;
private
String
message
;
public
String
getUuid
()
{
return
uuid
;
}
public
void
setUuid
(
String
uuid
)
{
this
.
uuid
=
uuid
;
}
public
String
getType
()
{
return
type
;
}
public
void
setType
(
String
type
)
{
this
.
type
=
type
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
public
BaseMsg
()
{
}
public
BaseMsg
(
String
uuid
,
String
type
,
String
message
)
{
this
.
uuid
=
uuid
;
this
.
type
=
type
;
this
.
message
=
message
;
}
@Override
public
String
toString
()
{
return
"BaseMsg{"
+
"uuid='"
+
uuid
+
'\''
+
", type='"
+
type
+
'\''
+
", message='"
+
message
+
'\''
+
'}'
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/ChatMsg.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
* 功能描述:弹幕消息
*
* @auther: coffee
* @date: 2018-07-04 19:44:16
* 修改日志:
*/
public
class
ChatMsg
implements
MsgEntity
{
/**
* 原消息
*/
private
String
message
;
/**
* 原消息ID
*/
private
String
uuid
;
/**
* 弹幕唯一ID
*/
private
String
cid
;
/**
* 弹幕组ID
*/
private
String
gid
;
/**
* 房间ID
*/
private
String
rid
;
/**
* 发送者 uid
*/
private
String
uid
;
/**
* 用户昵称
*/
private
String
nn
;
/**
* 消息内容
*/
private
String
txt
;
/**
* 用户等级
*/
private
String
level
;
/**
* 礼物头衔:默认值 0(表示没有头衔)
*/
private
String
gt
;
/**
* 消息颜色:默认值 0(表示默认颜色弹幕)
*/
private
String
col
;
/**
* 客户端类型:默认值 0
*/
private
String
ct
;
/**
* 房间权限组:默认值 1(表示普通权限用户)
*/
private
String
rg
;
/**
* 平台权限组:默认值 1(表示普通权限用户)
*/
private
String
pg
;
/**
* 弹幕具体类型: 默认值 0(普通弹幕)
*/
private
String
cmt
;
/**
* 用户头像
*/
private
String
ic
;
/**
* 贵族等级
*/
private
String
nl
;
/**
* 贵族弹幕标识,0-非贵族弹幕,1-贵族弹幕,默认值 0
*/
private
String
nc
;
/**
* 粉丝牌名称
*/
private
String
bnn
;
/**
* 粉丝牌等级
*/
private
String
bl
;
/**
* 粉丝牌关联房间号
*/
private
String
brid
;
/**
* 徽章信息校验码
*/
private
String
hc
;
/**
* 主播等级
*/
private
String
ol
;
/**
* 是否反向弹幕标记: 0-普通弹幕,1-反向弹幕, 默认值 0
*/
private
String
rev
;
/**
* 是否高亮弹幕标记: 0-普通,1-高亮, 默认值 0
*/
private
String
hl
;
/**
* 是否粉丝弹幕标记: 0-非粉丝弹幕,1-粉丝弹幕, 默认值 0
*/
private
String
ifs
;
/**
* 弹幕发送时间
*/
private
String
cst
;
public
String
getCid
()
{
return
cid
;
}
public
void
setCid
(
String
cid
)
{
this
.
cid
=
cid
;
}
public
String
getGid
()
{
return
gid
;
}
public
void
setGid
(
String
gid
)
{
this
.
gid
=
gid
;
}
public
String
getRid
()
{
return
rid
;
}
public
void
setRid
(
String
rid
)
{
this
.
rid
=
rid
;
}
public
String
getUid
()
{
return
uid
;
}
public
void
setUid
(
String
uid
)
{
this
.
uid
=
uid
;
}
public
String
getNn
()
{
return
nn
;
}
public
void
setNn
(
String
nn
)
{
this
.
nn
=
nn
;
}
public
String
getTxt
()
{
return
txt
;
}
public
void
setTxt
(
String
txt
)
{
this
.
txt
=
txt
;
}
public
String
getLevel
()
{
return
level
;
}
public
void
setLevel
(
String
level
)
{
this
.
level
=
level
;
}
public
String
getGt
()
{
return
gt
;
}
public
void
setGt
(
String
gt
)
{
this
.
gt
=
gt
;
}
public
String
getCol
()
{
return
col
;
}
public
void
setCol
(
String
col
)
{
this
.
col
=
col
;
}
public
String
getCt
()
{
return
ct
;
}
public
void
setCt
(
String
ct
)
{
this
.
ct
=
ct
;
}
public
String
getRg
()
{
return
rg
;
}
public
void
setRg
(
String
rg
)
{
this
.
rg
=
rg
;
}
public
String
getPg
()
{
return
pg
;
}
public
void
setPg
(
String
pg
)
{
this
.
pg
=
pg
;
}
public
String
getCmt
()
{
return
cmt
;
}
public
void
setCmt
(
String
cmt
)
{
this
.
cmt
=
cmt
;
}
public
String
getIc
()
{
return
ic
;
}
public
void
setIc
(
String
ic
)
{
this
.
ic
=
ic
;
}
public
String
getNl
()
{
return
nl
;
}
public
void
setNl
(
String
nl
)
{
this
.
nl
=
nl
;
}
public
String
getNc
()
{
return
nc
;
}
public
void
setNc
(
String
nc
)
{
this
.
nc
=
nc
;
}
public
String
getBnn
()
{
return
bnn
;
}
public
void
setBnn
(
String
bnn
)
{
this
.
bnn
=
bnn
;
}
public
String
getBl
()
{
return
bl
;
}
public
void
setBl
(
String
bl
)
{
this
.
bl
=
bl
;
}
public
String
getBrid
()
{
return
brid
;
}
public
void
setBrid
(
String
brid
)
{
this
.
brid
=
brid
;
}
public
String
getHc
()
{
return
hc
;
}
public
void
setHc
(
String
hc
)
{
this
.
hc
=
hc
;
}
public
String
getOl
()
{
return
ol
;
}
public
void
setOl
(
String
ol
)
{
this
.
ol
=
ol
;
}
public
String
getRev
()
{
return
rev
;
}
public
void
setRev
(
String
rev
)
{
this
.
rev
=
rev
;
}
public
String
getHl
()
{
return
hl
;
}
public
void
setHl
(
String
hl
)
{
this
.
hl
=
hl
;
}
public
String
getIfs
()
{
return
ifs
;
}
public
void
setIfs
(
String
ifs
)
{
this
.
ifs
=
ifs
;
}
public
String
getCst
()
{
return
cst
;
}
public
void
setCst
(
String
cst
)
{
this
.
cst
=
cst
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
@Override
public
String
getUuid
()
{
return
uuid
;
}
@Override
public
void
setUuid
(
String
uuid
)
{
this
.
uuid
=
uuid
;
}
@Override
public
String
toString
()
{
return
"ChatMsg{"
+
"cid='"
+
cid
+
'\''
+
", gid='"
+
gid
+
'\''
+
", rid='"
+
rid
+
'\''
+
", uid='"
+
uid
+
'\''
+
", nn='"
+
nn
+
'\''
+
", txt='"
+
txt
+
'\''
+
", level='"
+
level
+
'\''
+
", gt='"
+
gt
+
'\''
+
", col='"
+
col
+
'\''
+
", ct='"
+
ct
+
'\''
+
", rg='"
+
rg
+
'\''
+
", pg='"
+
pg
+
'\''
+
", cmt='"
+
cmt
+
'\''
+
", ic='"
+
ic
+
'\''
+
", nl='"
+
nl
+
'\''
+
", nc='"
+
nc
+
'\''
+
", bnn='"
+
bnn
+
'\''
+
", bl='"
+
bl
+
'\''
+
", brid='"
+
brid
+
'\''
+
", hc='"
+
hc
+
'\''
+
", ol='"
+
ol
+
'\''
+
", rev='"
+
rev
+
'\''
+
", hl='"
+
hl
+
'\''
+
", ifs='"
+
ifs
+
'\''
+
", cst='"
+
cst
+
'\''
+
'}'
;
}
/**
* 转换为弹幕消息展示 (name: txt)
*
* @return
*/
public
String
toChatStr
()
{
return
String
.
format
(
"%s: %s"
,
nn
,
txt
);
}
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/DgbMsg.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
*
* 功能描述:赠送礼物
*
* @auther: coffee
* @date: 2018-07-08 23:59:55
* 修改日志:
*
*/
public
class
DgbMsg
implements
MsgEntity
{
/**
* 原消息
*/
private
String
message
;
/**
* 原消息ID
*/
private
String
uuid
;
/**
* 房间ID
*/
private
String
rid
;
/**
* 弹幕组ID
*/
private
String
gid
;
/**
* 礼物ID
*/
private
String
gfid
;
/**
* 礼物显示样式
*/
private
String
gs
;
/**
* 用户ID
*/
private
String
uid
;
/**
* 用户昵称
*/
private
String
nn
;
/**
* 大礼物标识:默认值为 0(表示是小礼物)
*/
private
String
bg
;
/**
* 礼物个数:默认值 1(表示 1 个礼物)
*/
private
String
gfcnt
;
/**
* 礼物连击次数:默认值 1(表示 1 连击)
*/
private
String
hits
;
/**
* 贵族等级
*/
private
String
nl
;
/**
* 粉丝牌名称
*/
private
String
bnn
;
/**
* 粉丝牌等级
*/
private
String
bl
;
/**
* 粉丝牌关联房间号
*/
private
String
brid
;
/**
* 徽章信息校验码
*/
private
String
hc
;
public
String
getRid
()
{
return
rid
;
}
public
void
setRid
(
String
rid
)
{
this
.
rid
=
rid
;
}
public
String
getGid
()
{
return
gid
;
}
public
void
setGid
(
String
gid
)
{
this
.
gid
=
gid
;
}
public
String
getGfid
()
{
return
gfid
;
}
public
void
setGfid
(
String
gfid
)
{
this
.
gfid
=
gfid
;
}
public
String
getGs
()
{
return
gs
;
}
public
void
setGs
(
String
gs
)
{
this
.
gs
=
gs
;
}
public
String
getUid
()
{
return
uid
;
}
public
void
setUid
(
String
uid
)
{
this
.
uid
=
uid
;
}
public
String
getNn
()
{
return
nn
;
}
public
void
setNn
(
String
nn
)
{
this
.
nn
=
nn
;
}
public
String
getBg
()
{
return
bg
;
}
public
void
setBg
(
String
bg
)
{
this
.
bg
=
bg
;
}
public
String
getGfcnt
()
{
return
gfcnt
;
}
public
void
setGfcnt
(
String
gfcnt
)
{
this
.
gfcnt
=
gfcnt
;
}
public
String
getHits
()
{
return
hits
;
}
public
void
setHits
(
String
hits
)
{
this
.
hits
=
hits
;
}
public
String
getNl
()
{
return
nl
;
}
public
void
setNl
(
String
nl
)
{
this
.
nl
=
nl
;
}
public
String
getBnn
()
{
return
bnn
;
}
public
void
setBnn
(
String
bnn
)
{
this
.
bnn
=
bnn
;
}
public
String
getBl
()
{
return
bl
;
}
public
void
setBl
(
String
bl
)
{
this
.
bl
=
bl
;
}
public
String
getBrid
()
{
return
brid
;
}
public
void
setBrid
(
String
brid
)
{
this
.
brid
=
brid
;
}
public
String
getHc
()
{
return
hc
;
}
public
void
setHc
(
String
hc
)
{
this
.
hc
=
hc
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
@Override
public
String
getUuid
()
{
return
uuid
;
}
@Override
public
void
setUuid
(
String
uuid
)
{
this
.
uuid
=
uuid
;
}
@Override
public
String
toString
()
{
return
"DgbMsg{"
+
"rid='"
+
rid
+
'\''
+
", gid='"
+
gid
+
'\''
+
", gfid='"
+
gfid
+
'\''
+
", gs='"
+
gs
+
'\''
+
", uid='"
+
uid
+
'\''
+
", nn='"
+
nn
+
'\''
+
", bg='"
+
bg
+
'\''
+
", gfcnt='"
+
gfcnt
+
'\''
+
", hits='"
+
hits
+
'\''
+
", nl='"
+
nl
+
'\''
+
", bnn='"
+
bnn
+
'\''
+
", bl='"
+
bl
+
'\''
+
", brid='"
+
brid
+
'\''
+
", hc='"
+
hc
+
'\''
+
'}'
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/ErrorMsg.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
* 功能描述:错误消息
* <p>
* 0 操作成功
* 51 数据传输出错
* 52 服务器关闭
* 204 房间id错误
*
* @auther: coffee
* @date: 2018-07-16 16:09:02
* 修改日志:
*/
public
class
ErrorMsg
implements
MsgEntity
{
/**
* 原消息
*/
private
String
message
;
/**
* 原消息ID
*/
private
String
uuid
;
/**
* 错误代码
*/
private
String
code
;
/**
* 错误描述
*/
private
String
desc
;
public
String
getCode
()
{
return
code
;
}
public
void
setCode
(
String
code
)
{
this
.
code
=
code
;
}
public
String
getDesc
()
{
if
(
desc
==
null
&&
code
!=
null
)
{
switch
(
code
)
{
case
"0"
:
desc
=
"斗鱼弹幕客户端-操作成功"
;
break
;
case
"51"
:
desc
=
"斗鱼弹幕客户端-数据传输出错"
;
break
;
case
"52"
:
desc
=
"斗鱼弹幕客户端-服务已登出 或 服务器关闭"
;
break
;
case
"204"
:
desc
=
"斗鱼弹幕客户端-房间ID错误"
;
break
;
}
}
return
desc
;
}
public
void
setDesc
(
String
desc
)
{
this
.
desc
=
desc
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
@Override
public
String
getUuid
()
{
return
uuid
;
}
@Override
public
void
setUuid
(
String
uuid
)
{
this
.
uuid
=
uuid
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/GgbbMsg.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
* 功能描述:房间内用户抢红包消息
*
* @auther: coffee
* @date: 2018-07-09 11:36:12
* 修改日志:
*
*/
public
class
GgbbMsg
implements
MsgEntity
{
/**
* 原消息
*/
private
String
message
;
/**
* 原消息ID
*/
private
String
uuid
;
/**
* 房间ID
*/
private
String
rid
;
/**
* 弹幕组ID
*/
private
String
gid
;
/**
* 抢到的鱼丸数量
*/
private
String
sl
;
/**
* 礼包产生者 id
*/
private
String
sid
;
/**
* 抢礼包者 id
*/
private
String
did
;
/**
* 礼包产生者昵称
*/
private
String
snk
;
/**
* 抢礼包者昵称
*/
private
String
dnk
;
/**
* 礼包类型
*/
private
String
rpt
;
public
String
getRid
()
{
return
rid
;
}
public
void
setRid
(
String
rid
)
{
this
.
rid
=
rid
;
}
public
String
getGid
()
{
return
gid
;
}
public
void
setGid
(
String
gid
)
{
this
.
gid
=
gid
;
}
public
String
getSl
()
{
return
sl
;
}
public
void
setSl
(
String
sl
)
{
this
.
sl
=
sl
;
}
public
String
getSid
()
{
return
sid
;
}
public
void
setSid
(
String
sid
)
{
this
.
sid
=
sid
;
}
public
String
getDid
()
{
return
did
;
}
public
void
setDid
(
String
did
)
{
this
.
did
=
did
;
}
public
String
getSnk
()
{
return
snk
;
}
public
void
setSnk
(
String
snk
)
{
this
.
snk
=
snk
;
}
public
String
getDnk
()
{
return
dnk
;
}
public
void
setDnk
(
String
dnk
)
{
this
.
dnk
=
dnk
;
}
public
String
getRpt
()
{
return
rpt
;
}
public
void
setRpt
(
String
rpt
)
{
this
.
rpt
=
rpt
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
@Override
public
String
getUuid
()
{
return
uuid
;
}
@Override
public
void
setUuid
(
String
uuid
)
{
this
.
uuid
=
uuid
;
}
@Override
public
String
toString
()
{
return
"GgbbMsg{"
+
"rid='"
+
rid
+
'\''
+
", gid='"
+
gid
+
'\''
+
", sl='"
+
sl
+
'\''
+
", sid='"
+
sid
+
'\''
+
", did='"
+
did
+
'\''
+
", snk='"
+
snk
+
'\''
+
", dnk='"
+
dnk
+
'\''
+
", rpt='"
+
rpt
+
'\''
+
'}'
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/MsgEntity.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
*
* 功能描述:
*
* @auther: coffee
* @date: 2018-07-07 17:27:36
* 修改日志:
*
*/
public
interface
MsgEntity
{
String
getMessage
();
void
setMessage
(
String
message
);
String
getUuid
();
void
setUuid
(
String
uuid
);
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/SpbcMsg.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
*
* 功能描述:礼物广播消息
*
* @auther: coffee
* @date: 2018-07-09 10:28:48
* 修改日志:
*
*/
public
class
SpbcMsg
implements
MsgEntity
{
/**
* 原消息
*/
private
String
message
;
/**
* 原消息ID
*/
private
String
uuid
;
/**
* 房间ID
*/
private
String
rid
;
/**
* 弹幕组ID
*/
private
String
gid
;
/**
* 赠送者昵称
*/
private
String
sn
;
/**
* 受赠者昵称
*/
private
String
dn
;
/**
* 礼物名称
*/
private
String
gn
;
/**
* 礼物数量
*/
private
String
gc
;
/**
* 赠送房间
*/
private
String
drid
;
/**
* 广播样式
*/
private
String
gs
;
/**
* 是否有礼包(0-无礼包,1-有礼包)
*/
private
String
gb
;
/**
* 广播展现样式(1-火箭,2-飞机)
*/
private
String
es
;
/**
* 礼物 id
*/
private
String
gfid
;
/**
* 特效 id
*/
private
String
eid
;
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
@Override
public
String
getUuid
()
{
return
uuid
;
}
@Override
public
void
setUuid
(
String
uuid
)
{
this
.
uuid
=
uuid
;
}
public
String
getRid
()
{
return
rid
;
}
public
void
setRid
(
String
rid
)
{
this
.
rid
=
rid
;
}
public
String
getGid
()
{
return
gid
;
}
public
void
setGid
(
String
gid
)
{
this
.
gid
=
gid
;
}
public
String
getSn
()
{
return
sn
;
}
public
void
setSn
(
String
sn
)
{
this
.
sn
=
sn
;
}
public
String
getDn
()
{
return
dn
;
}
public
void
setDn
(
String
dn
)
{
this
.
dn
=
dn
;
}
public
String
getGn
()
{
return
gn
;
}
public
void
setGn
(
String
gn
)
{
this
.
gn
=
gn
;
}
public
String
getGc
()
{
return
gc
;
}
public
void
setGc
(
String
gc
)
{
this
.
gc
=
gc
;
}
public
String
getDrid
()
{
return
drid
;
}
public
void
setDrid
(
String
drid
)
{
this
.
drid
=
drid
;
}
public
String
getGs
()
{
return
gs
;
}
public
void
setGs
(
String
gs
)
{
this
.
gs
=
gs
;
}
public
String
getGb
()
{
return
gb
;
}
public
void
setGb
(
String
gb
)
{
this
.
gb
=
gb
;
}
public
String
getEs
()
{
return
es
;
}
public
void
setEs
(
String
es
)
{
this
.
es
=
es
;
}
public
String
getGfid
()
{
return
gfid
;
}
public
void
setGfid
(
String
gfid
)
{
this
.
gfid
=
gfid
;
}
public
String
getEid
()
{
return
eid
;
}
public
void
setEid
(
String
eid
)
{
this
.
eid
=
eid
;
}
@Override
public
String
toString
()
{
return
"SpbcMsg{"
+
"rid='"
+
rid
+
'\''
+
", gid='"
+
gid
+
'\''
+
", sn='"
+
sn
+
'\''
+
", dn='"
+
dn
+
'\''
+
", gn='"
+
gn
+
'\''
+
", gc='"
+
gc
+
'\''
+
", drid='"
+
drid
+
'\''
+
", gs='"
+
gs
+
'\''
+
", gb='"
+
gb
+
'\''
+
", es='"
+
es
+
'\''
+
", gfid='"
+
gfid
+
'\''
+
", eid='"
+
eid
+
'\''
+
'}'
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/SsdMsg.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
*
* 功能描述:超级弹幕消息
*
* @auther: coffee
* @date: 2018-07-09 10:24:53
* 修改日志:
*
*/
public
class
SsdMsg
implements
MsgEntity
{
/**
* 原消息
*/
private
String
message
;
/**
* 原消息ID
*/
private
String
uuid
;
/**
* 超级弹幕ID
*/
private
String
sdid
;
/**
* 房间ID
*/
private
String
rid
;
/**
* 弹幕组ID
*/
private
String
gid
;
/**
* 跳转房间ID
*/
private
String
trid
;
/**
* 超级弹幕内容
*/
private
String
content
;
public
String
getSdid
()
{
return
sdid
;
}
public
void
setSdid
(
String
sdid
)
{
this
.
sdid
=
sdid
;
}
public
String
getRid
()
{
return
rid
;
}
public
void
setRid
(
String
rid
)
{
this
.
rid
=
rid
;
}
public
String
getGid
()
{
return
gid
;
}
public
void
setGid
(
String
gid
)
{
this
.
gid
=
gid
;
}
public
String
getTrid
()
{
return
trid
;
}
public
void
setTrid
(
String
trid
)
{
this
.
trid
=
trid
;
}
public
String
getContent
()
{
return
content
;
}
public
void
setContent
(
String
content
)
{
this
.
content
=
content
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
@Override
public
String
getUuid
()
{
return
uuid
;
}
@Override
public
void
setUuid
(
String
uuid
)
{
this
.
uuid
=
uuid
;
}
@Override
public
String
toString
()
{
return
"SsdMsg{"
+
"sdid='"
+
sdid
+
'\''
+
", rid='"
+
rid
+
'\''
+
", gid='"
+
gid
+
'\''
+
", trid='"
+
trid
+
'\''
+
", content='"
+
content
+
'\''
+
'}'
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/entity/UenterMsg.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
entity
;
/**
*
* 功能描述:用户进房通知消息
*
* @auther: coffee
* @date: 2018-07-09 00:28:36
* 修改日志:
*
*/
public
class
UenterMsg
implements
MsgEntity
{
/**
* 原消息
*/
private
String
message
;
/**
* 原消息ID
*/
private
String
uuid
;
/**
* 房间ID
*/
private
String
rid
;
/**
* 弹幕组ID
*/
private
String
gid
;
/**
* 用户ID
*/
private
String
uid
;
/**
* 用户昵称
*/
private
String
nn
;
/**
* 用户等级
*/
private
String
level
;
/**
* 礼物头衔:默认值 0(表示没有头衔)
*/
private
String
gt
;
/**
* 房间权限组:默认值 1(表示普通权限用户)
*/
private
String
rg
;
/**
* 平台权限组:默认值 1(表示普通权限用户)
*/
private
String
pg
;
/**
* 用户头像
*/
private
String
ic
;
/**
* 贵族等级
*/
private
String
nl
;
public
String
getRid
()
{
return
rid
;
}
public
void
setRid
(
String
rid
)
{
this
.
rid
=
rid
;
}
public
String
getGid
()
{
return
gid
;
}
public
void
setGid
(
String
gid
)
{
this
.
gid
=
gid
;
}
public
String
getUid
()
{
return
uid
;
}
public
void
setUid
(
String
uid
)
{
this
.
uid
=
uid
;
}
public
String
getNn
()
{
return
nn
;
}
public
void
setNn
(
String
nn
)
{
this
.
nn
=
nn
;
}
public
String
getLevel
()
{
return
level
;
}
public
void
setLevel
(
String
level
)
{
this
.
level
=
level
;
}
public
String
getGt
()
{
return
gt
;
}
public
void
setGt
(
String
gt
)
{
this
.
gt
=
gt
;
}
public
String
getRg
()
{
return
rg
;
}
public
void
setRg
(
String
rg
)
{
this
.
rg
=
rg
;
}
public
String
getPg
()
{
return
pg
;
}
public
void
setPg
(
String
pg
)
{
this
.
pg
=
pg
;
}
public
String
getIc
()
{
return
ic
;
}
public
void
setIc
(
String
ic
)
{
this
.
ic
=
ic
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
public
String
getUuid
()
{
return
uuid
;
}
public
void
setUuid
(
String
uuid
)
{
this
.
uuid
=
uuid
;
}
public
String
getNl
()
{
return
nl
;
}
public
void
setNl
(
String
nl
)
{
this
.
nl
=
nl
;
}
@Override
public
String
toString
()
{
return
"UenterMsg{"
+
"rid='"
+
rid
+
'\''
+
", gid='"
+
gid
+
'\''
+
", uid='"
+
uid
+
'\''
+
", nn='"
+
nn
+
'\''
+
", level='"
+
level
+
'\''
+
", gt='"
+
gt
+
'\''
+
", rg='"
+
rg
+
'\''
+
", pg='"
+
pg
+
'\''
+
", ic='"
+
ic
+
'\''
+
", nl='"
+
nl
+
'\''
+
'}'
;
}
}
src/main/java/com/zhiwei/live/danmu/douyu/enums/NobleLevel.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
enums
;
/**
* 功能描述:贵族等级
*
* @auther: coffee
* @date: 2018-07-08 23:38:22
* 修改日志:
*/
public
enum
NobleLevel
{
LEVEL_0
(
"0"
,
"游侠"
),
LEVEL_1
(
"1"
,
"骑士"
),
LEVEL_2
(
"2"
,
"子爵"
),
LEVEL_3
(
"3"
,
"伯爵"
),
LEVEL_4
(
"4"
,
"公爵"
),
LEVEL_5
(
"5"
,
"国外"
),
LEVEL_6
(
"6"
,
"皇帝"
),;
NobleLevel
(
String
code
,
String
description
)
{
this
.
code
=
code
;
this
.
description
=
description
;
}
private
String
code
;
private
String
description
;
}
src/main/java/com/zhiwei/live/danmu/douyu/exceptions/DouYuSDKException.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
exceptions
;
/**
*
* 功能描述:
*
* @auther: coffee
* @date: 2018-07-04 15:50:12
* 修改日志:
*
*/
public
class
DouYuSDKException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
-
2974352294232725589L
;
public
DouYuSDKException
(
Exception
e
)
{
super
(
e
);
}
}
src/main/java/com/zhiwei/live/danmu/douyu/exceptions/UtilException.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
exceptions
;
/**
* 工具类异常
*
* @author coffee
*/
public
class
UtilException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
8247610319171014183L
;
public
UtilException
(
Throwable
e
)
{
super
(
UtilException
.
getMessage
(
e
),
e
);
}
public
UtilException
(
String
message
)
{
super
(
message
);
}
public
UtilException
(
String
messageTemplate
,
Object
...
params
)
{
super
(
String
.
format
(
messageTemplate
,
params
));
}
public
UtilException
(
String
message
,
Throwable
throwable
)
{
super
(
message
,
throwable
);
}
public
UtilException
(
Throwable
throwable
,
String
messageTemplate
,
Object
...
params
)
{
super
(
String
.
format
(
messageTemplate
,
params
),
throwable
);
}
/**
* 获得完整消息,包括异常名
*
* @param e 异常
* @return 完整消息
*/
public
static
String
getMessage
(
Throwable
e
)
{
if
(
null
==
e
)
{
return
"null"
;
}
return
String
.
format
(
"{}: {}"
,
e
.
getClass
().
getSimpleName
(),
e
.
getMessage
());
}
}
src/main/java/com/zhiwei/live/danmu/douyu/listener/DefaultBaseMsgListener.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
listener
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.zhiwei.live.danmu.douyu.MessageListener
;
import
com.zhiwei.live.danmu.douyu.entity.BaseMsg
;
/**
*
* 功能描述:默认的BaseMsg消息监听器
*
* @auther: coffee
* @date: 2018-07-07 18:48:48
* 修改日志:
*
*/
public
class
DefaultBaseMsgListener
extends
MessageListener
<
BaseMsg
>
{
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
DefaultBaseMsgListener
.
class
);
@Override
public
void
read
(
BaseMsg
message
)
{
logger
.
info
(
message
.
toString
());
}
}
src/main/java/com/zhiwei/live/danmu/douyu/listener/DefaultChatMsgListener.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
listener
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.zhiwei.live.danmu.douyu.MessageListener
;
import
com.zhiwei.live.danmu.douyu.entity.ChatMsg
;
/**
* 功能描述:默认ChatMsg消息监听处理器
*
* @auther: coffee
* @date: 2018-07-08 21:23:08
* 修改日志:
*/
public
class
DefaultChatMsgListener
extends
MessageListener
<
ChatMsg
>
{
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
DefaultBaseMsgListener
.
class
);
@Override
public
void
read
(
ChatMsg
message
)
{
logger
.
info
(
message
.
toChatStr
());
}
}
src/main/java/com/zhiwei/live/danmu/douyu/util/ArrayUtil.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
util
;
import
java.lang.reflect.Array
;
/**
* 数组工具类
*
* @author Looly
*
*/
public
class
ArrayUtil
{
/**
* 将新元素添加到已有数组中<br>
* 添加新元素会生成一个新的数组,不影响原数组
*
* @param <T> 数组元素类型
* @param buffer 已有数组
* @param newElements 新元素
* @return 新数组
*/
@SafeVarargs
public
static
<
T
>
T
[]
append
(
T
[]
buffer
,
T
...
newElements
)
{
if
(
isEmpty
(
buffer
))
{
return
newElements
;
}
return
insert
(
buffer
,
buffer
.
length
,
newElements
);
}
/**
* 将新元素插入到到已有数组中的某个位置<br>
* 添加新元素会生成一个新的数组,不影响原数组<br>
* 如果插入位置为为负数,从原数组从后向前计数,若大于原数组长度,则空白处用null填充
*
* @param <T> 数组元素类型
* @param buffer 已有数组
* @param index 插入位置,此位置为对应此位置元素之前的空档
* @param newElements 新元素
* @return 新数组
* @since 4.0.8
*/
@SafeVarargs
public
static
<
T
>
T
[]
insert
(
T
[]
buffer
,
int
index
,
T
...
newElements
)
{
if
(
isEmpty
(
newElements
))
{
return
buffer
;
}
if
(
isEmpty
(
buffer
))
{
return
newElements
;
}
if
(
index
<
0
)
{
index
=
(
index
%
buffer
.
length
)
+
buffer
.
length
;
}
final
T
[]
result
=
newArray
(
buffer
.
getClass
().
getComponentType
(),
Math
.
max
(
buffer
.
length
,
index
)
+
newElements
.
length
);
System
.
arraycopy
(
buffer
,
0
,
result
,
0
,
Math
.
min
(
buffer
.
length
,
index
));
System
.
arraycopy
(
newElements
,
0
,
result
,
index
,
newElements
.
length
);
if
(
index
<
buffer
.
length
)
{
System
.
arraycopy
(
buffer
,
index
,
result
,
index
+
newElements
.
length
,
buffer
.
length
-
index
);
}
return
result
;
}
// ---------------------------------------------------------------------- isEmpty
/**
* 数组是否为空
*
* @param <T> 数组元素类型
* @param array 数组
* @return 是否为空
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
boolean
isEmpty
(
final
T
...
array
)
{
return
array
==
null
||
array
.
length
==
0
;
}
// ---------------------------------------------------------------------- isNotEmpty
/**
* 数组是否为非空
*
* @param <T> 数组元素类型
* @param array 数组
* @return 是否为非空
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
boolean
isNotEmpty
(
final
T
...
array
)
{
return
(
array
!=
null
&&
array
.
length
!=
0
);
}
/**
* 新建一个空数组
*
* @param <T> 数组元素类型
* @param componentType 元素类型
* @param newSize 大小
* @return 空数组
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
T
[]
newArray
(
Class
<?>
componentType
,
int
newSize
)
{
return
(
T
[])
Array
.
newInstance
(
componentType
,
newSize
);
}
/**
* 新建一个空数组
*
* @param <T> 数组元素类型
* @param newSize 大小
* @return 空数组
* @since 3.3.0
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
T
[]
newArray
(
int
newSize
)
{
return
(
T
[])
new
Object
[
newSize
];
}
}
src/main/java/com/zhiwei/live/danmu/douyu/util/DataUtil.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
util
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* 功能描述:数据处理工具类
*
* @auther: coffee
* @date: 2018-07-07 16:23:11
* 修改日志:
*/
public
class
DataUtil
{
static
Pattern
nickNamePattern
=
Pattern
.
compile
(
"/nn@=(.*?)/"
);
static
Pattern
msgTextPattern
=
Pattern
.
compile
(
"/txt@=(.*?)/"
);
static
Pattern
typePattern
=
Pattern
.
compile
(
"type@=(.*?)/"
);
private
static
String
match
(
String
source
,
Pattern
pattern
,
int
groupId
)
{
Matcher
matcher
=
pattern
.
matcher
(
source
);
if
(
matcher
.
find
())
{
return
matcher
.
group
(
groupId
);
}
else
{
return
""
;
}
}
public
static
String
getNickName
(
String
source
)
{
return
match
(
source
,
nickNamePattern
,
1
);
}
public
static
String
getMsg
(
String
source
)
{
return
match
(
source
,
msgTextPattern
,
1
);
}
/**
* 从消息中获取消息类型
* @param source
* @return
*/
public
static
String
getMsgType
(
String
source
)
{
return
match
(
source
,
typePattern
,
1
);
}
}
src/main/java/com/zhiwei/live/danmu/douyu/util/ReflectUtil.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
util
;
import
java.lang.reflect.Field
;
import
com.zhiwei.live.danmu.douyu.exceptions.UtilException
;
/**
* 反射工具类
*
* @author coffee
*/
public
class
ReflectUtil
{
/**
* 字段缓存
*/
private
static
final
SimpleCache
<
Class
<?>,
Field
[]>
FIELDS_CACHE
=
new
SimpleCache
<>();
/**
* 获得一个类中所有字段列表,包括其父类中的字段
*
* @param beanClass 类
* @return 字段列表
* @throws SecurityException 安全检查异常
*/
public
static
Field
[]
getFields
(
Class
<?>
beanClass
)
throws
SecurityException
{
Field
[]
allFields
=
FIELDS_CACHE
.
get
(
beanClass
);
if
(
null
!=
allFields
)
{
return
allFields
;
}
allFields
=
getFieldsDirectly
(
beanClass
,
true
);
return
FIELDS_CACHE
.
put
(
beanClass
,
allFields
);
}
/**
* 获得一个类中所有字段列表,直接反射获取,无缓存
*
* @param beanClass 类
* @param withSuperClassFieds 是否包括父类的字段列表
* @return 字段列表
* @throws SecurityException 安全检查异常
*/
public
static
Field
[]
getFieldsDirectly
(
Class
<?>
beanClass
,
boolean
withSuperClassFieds
)
throws
SecurityException
{
if
(
beanClass
==
null
)
{
throw
new
UtilException
(
"反射获取字段出现异常,参数 beanClass 为空"
);
}
Field
[]
allFields
=
null
;
Class
<?>
searchType
=
beanClass
;
Field
[]
declaredFields
;
while
(
searchType
!=
null
)
{
declaredFields
=
searchType
.
getDeclaredFields
();
if
(
null
==
allFields
)
{
allFields
=
declaredFields
;
}
else
{
allFields
=
ArrayUtil
.
append
(
allFields
,
declaredFields
);
}
searchType
=
withSuperClassFieds
?
searchType
.
getSuperclass
()
:
null
;
}
return
allFields
;
}
/**
* 查找指定类中的所有字段(包括非public字段),也包括父类和Object类的字段, 字段不存在则返回<code>null</code>
*
* @param beanClass 被查找字段的类,不能为null
* @param name 字段名
* @return 字段
* @throws SecurityException 安全异常
*/
public
static
Field
getField
(
Class
<?>
beanClass
,
String
name
)
throws
SecurityException
{
final
Field
[]
fields
=
getFields
(
beanClass
);
if
(
ArrayUtil
.
isNotEmpty
(
fields
))
{
for
(
Field
field
:
fields
)
{
if
((
name
.
equals
(
field
.
getName
())))
{
return
field
;
}
}
}
return
null
;
}
/**
* 设置字段值
*
* @param obj 对象
* @param fieldName 字段名
* @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型
* @throws UtilException 包装IllegalAccessException异常
*/
public
static
void
setFieldValue
(
Object
obj
,
String
fieldName
,
Object
value
)
throws
UtilException
{
if
(
obj
==
null
)
{
throw
new
UtilException
(
"[Assertion failed] - this argument is required; it must not be null"
);
}
if
(
fieldName
==
null
||
""
.
equals
(
fieldName
))
{
throw
new
UtilException
(
"[Assertion failed] - this String argument must have text; it must not be null, empty, or blank"
);
}
setFieldValue
(
obj
,
getField
(
obj
.
getClass
(),
fieldName
),
value
);
}
/**
* 设置字段值
*
* @param obj 对象
* @param field 字段
* @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型
* @throws UtilException UtilException 包装IllegalAccessException异常
*/
public
static
void
setFieldValue
(
Object
obj
,
Field
field
,
Object
value
)
throws
UtilException
{
if
(
obj
==
null
)
{
throw
new
UtilException
(
"[Assertion failed] - this argument is required; it must not be null"
);
}
if
(
field
==
null
)
{
throw
new
UtilException
(
"[Assertion failed] - this argument is required; it must not be null"
);
}
field
.
setAccessible
(
true
);
try
{
field
.
set
(
obj
,
value
);
}
catch
(
IllegalAccessException
e
)
{
throw
new
UtilException
(
e
,
"IllegalAccess for {}.{}"
,
obj
.
getClass
(),
field
.
getName
());
}
}
/**
* 实例化对象
*
* @param <T> 对象类型
* @param clazz 类名
* @return 对象
* @throws UtilException 包装各类异常
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
T
newInstance
(
String
clazz
)
throws
UtilException
{
try
{
return
(
T
)
Class
.
forName
(
clazz
).
newInstance
();
}
catch
(
Exception
e
)
{
throw
new
UtilException
(
e
,
"Instance class [{}] error!"
,
clazz
);
}
}
/**
* 实例化对象
*
* @param clazz 对象类型
* @param <T> 类名
* @return 对象
* @throws UtilException 包装各类异常
*/
public
static
<
T
>
T
newInstance
(
Class
<
T
>
clazz
)
throws
UtilException
{
try
{
return
(
T
)
clazz
.
newInstance
();
}
catch
(
Exception
e
)
{
throw
new
UtilException
(
e
,
"Instance class [{}] error!"
,
clazz
);
}
}
}
src/main/java/com/zhiwei/live/danmu/douyu/util/SimpleCache.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
util
;
import
java.util.Map
;
import
java.util.WeakHashMap
;
import
java.util.concurrent.locks.ReentrantReadWriteLock
;
import
java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock
;
import
java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock
;
/**
* 简单缓存,无超时实现,使用{@link WeakHashMap}实现缓存自动清理
*
* @param <K> 键类型
* @param <V> 值类型
* @author Looly
*/
public
class
SimpleCache
<
K
,
V
>
{
/**
* 池
*/
private
final
Map
<
K
,
V
>
cache
=
new
WeakHashMap
<>();
private
final
ReentrantReadWriteLock
cacheLock
=
new
ReentrantReadWriteLock
();
private
final
ReadLock
readLock
=
cacheLock
.
readLock
();
private
final
WriteLock
writeLock
=
cacheLock
.
writeLock
();
/**
* 从缓存池中查找值
*
* @param key 键
* @return 值
*/
public
V
get
(
K
key
)
{
// 尝试读取缓存
readLock
.
lock
();
V
value
;
try
{
value
=
cache
.
get
(
key
);
}
finally
{
readLock
.
unlock
();
}
return
value
;
}
/**
* 放入缓存
*
* @param key 键
* @param value 值
* @return 值
*/
public
V
put
(
K
key
,
V
value
)
{
writeLock
.
lock
();
try
{
cache
.
put
(
key
,
value
);
}
finally
{
writeLock
.
unlock
();
}
return
value
;
}
/**
* 移除缓存
*
* @param key 键
* @return 移除的值
*/
public
V
remove
(
K
key
)
{
writeLock
.
lock
();
try
{
return
cache
.
remove
(
key
);
}
finally
{
writeLock
.
unlock
();
}
}
/**
* 清空缓存池
*/
public
void
clear
()
{
writeLock
.
lock
();
try
{
this
.
cache
.
clear
();
}
finally
{
writeLock
.
unlock
();
}
}
}
src/main/java/com/zhiwei/live/danmu/douyu/util/UUIDUtil.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
util
;
import
java.util.UUID
;
/**
*
* 功能描述:UUID工具类
*
* @auther: coffee
* @date: 2018-07-07 18:26:09
* 修改日志:
*
*/
public
class
UUIDUtil
{
/**
* @return 随机UUID
*/
public
static
String
randomUUID
()
{
return
UUID
.
randomUUID
().
toString
();
}
/**
* 简化的UUID,去掉了横线
*
* @return 简化的UUID,去掉了横线
* @since 3.2.2
*/
public
static
String
simpleUUID
()
{
return
randomUUID
().
replace
(
"-"
,
""
);
}
}
src/main/java/com/zhiwei/live/danmu/pandam
tv/Panda
Client.java
→
src/main/java/com/zhiwei/live/danmu/pandam
/Pandam
Client.java
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
pandam
tv
;
package
com
.
zhiwei
.
live
.
danmu
.
pandam
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.zhiwei.crawler.core.HttpBoot
;
import
com.zhiwei.crawler.core.RequestUtils
;
import
com.zhiwei.live.danmu.util.Connector
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
import
io.netty.channel.nio.NioEventLoopGroup
;
import
io.netty.handler.timeout.IdleStateHandler
;
...
...
@@ -17,11 +18,17 @@ import okhttp3.Response;
* @author 0xff
* @date Jan 25, 2019 3:24:33 PM
*/
public
class
Panda
Client
{
public
class
Panda
mClient
{
private
static
HttpBoot
httpBoot
=
new
HttpBoot
();
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
roomId
=
"337852"
;
/**
* 根据房间号获取弹幕信息
* @param roomId
* @throws Exception
*/
public
static
void
getDanmu
(
DataCallBack
dataCallBack
,
String
roomId
)
throws
Exception
{
//根据房间号获取弹幕服务器地址
Request
request
=
RequestUtils
.
wrapGet
(
"http://riven.panda.tv/chatroom/getinfo?roomid="
+
roomId
);
String
host
=
null
;
int
port
=
-
1
;
...
...
@@ -45,7 +52,7 @@ public class PandaClient {
String
authType
=
json
.
getString
(
"authType"
);
String
ts
=
json
.
getString
(
"ts"
);
Connector
.
asynchronizedTcpConnect
(
new
NioEventLoopGroup
(),
host
,
port
,
new
IdleStateHandler
(
0
,
0
,
45
),
new
PandaMessageHandler
(
appid
,
rid
,
ts
,
sign
,
authType
)).
sync
();
new
IdleStateHandler
(
0
,
30
,
45
),
new
PandamMessageHandler
(
dataCallBack
,
appid
,
rid
,
ts
,
sign
,
authType
)).
sync
();
}
}
src/main/java/com/zhiwei/live/danmu/pandam
tv
/PandamMessage.java
→
src/main/java/com/zhiwei/live/danmu/pandam/PandamMessage.java
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
pandam
tv
;
package
com
.
zhiwei
.
live
.
danmu
.
pandam
;
import
com.alibaba.fastjson.JSONObject
;
...
...
src/main/java/com/zhiwei/live/danmu/pandam
tv/Panda
MessageHandler.java
→
src/main/java/com/zhiwei/live/danmu/pandam
/Pandam
MessageHandler.java
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
pandam
tv
;
package
com
.
zhiwei
.
live
.
danmu
.
pandam
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
...
...
@@ -6,6 +6,7 @@ import java.util.regex.Pattern;
import
org.apache.commons.lang3.StringUtils
;
import
com.alibaba.fastjson.JSONObject
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.buffer.ByteBufUtil
;
...
...
@@ -23,7 +24,7 @@ import io.netty.util.ReferenceCountUtil;
* @author 0xff
* @date Jan 25, 2019 11:03:20 AM
*/
public
class
Panda
MessageHandler
extends
ChannelInboundHandlerAdapter
{
public
class
Panda
mMessageHandler
extends
ChannelInboundHandlerAdapter
{
private
static
final
byte
[]
FIRST_REQ
=
new
byte
[]
{
0x00
,
0x06
,
0x00
,
0x02
,
0x00
};
private
static
final
byte
[]
FIRST_RES
=
new
byte
[]
{
0x00
,
0x06
,
0x00
,
0x06
};
private
static
final
byte
[]
PING
=
new
byte
[]
{
0x00
,
0x06
,
0x00
,
0x00
};
...
...
@@ -34,6 +35,8 @@ public class PandaMessageHandler extends ChannelInboundHandlerAdapter {
private
String
ts
;
private
String
sign
;
private
String
authType
;
private
DataCallBack
dataCallBack
;
/**
* Constructor
...
...
@@ -41,12 +44,14 @@ public class PandaMessageHandler extends ChannelInboundHandlerAdapter {
* @param roomId
* 房间号
*/
public
PandaMessageHandler
(
String
appid
,
String
rid
,
String
ts
,
String
sign
,
String
authType
)
{
public
PandamMessageHandler
(
DataCallBack
dataCallBack
,
String
appid
,
String
rid
,
String
ts
,
String
sign
,
String
authType
)
{
this
.
dataCallBack
=
dataCallBack
;
this
.
appid
=
appid
;
this
.
rid
=
rid
;
this
.
sign
=
sign
;
this
.
authType
=
authType
;
this
.
ts
=
ts
;
}
/*
...
...
@@ -96,7 +101,7 @@ public class PandaMessageHandler extends ChannelInboundHandlerAdapter {
public
void
userEventTriggered
(
ChannelHandlerContext
ctx
,
Object
evt
)
throws
Exception
{
if
(
evt
instanceof
IdleStateEvent
)
{
IdleStateEvent
event
=
(
IdleStateEvent
)
evt
;
if
(
event
.
state
()
==
IdleState
.
ALL_IDLE
)
{
if
(
event
.
state
()
==
IdleState
.
WRITER_IDLE
)
{
ByteBuf
pingMsg
=
Unpooled
.
wrappedBuffer
(
PING
);
System
.
out
.
println
(
"发送心跳消息: \n"
+
ByteBufUtil
.
prettyHexDump
(
pingMsg
));
ctx
.
writeAndFlush
(
pingMsg
);
...
...
src/main/java/com/zhiwei/live/danmu/pandamtv/PandamMessageListener.java
deleted
100644 → 0
View file @
01161ad1
package
com
.
zhiwei
.
live
.
danmu
.
pandamtv
;
import
java.util.List
;
import
java.util.Vector
;
public
class
PandamMessageListener
extends
Thread
{
public
static
List
<
PandamMessage
>
messages
=
new
Vector
<>();
}
src/main/java/com/zhiwei/live/danmu/
bilibili
/DataCallBack.java
→
src/main/java/com/zhiwei/live/danmu/
util
/DataCallBack.java
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
bilibili
;
package
com
.
zhiwei
.
live
.
danmu
.
util
;
import
com.zhiwei.live.danmu.bilibili.BilibiliMessage
;
import
com.zhiwei.live.danmu.douyu.DouYuMessage
;
import
com.zhiwei.live.danmu.pandam.PandamMessage
;
public
interface
DataCallBack
{
...
...
@@ -10,6 +13,10 @@ public interface DataCallBack {
* @param attr
* @return void
*/
void
onData
(
BilibiliMessage
data
);
void
onData
(
Object
message
);
}
src/main/java/com/zhiwei/live/danmu/
douyu/util/STT
Util.java
→
src/main/java/com/zhiwei/live/danmu/
util/DouYu
Util.java
View file @
325fad04
package
com
.
zhiwei
.
live
.
danmu
.
douyu
.
util
;
package
com
.
zhiwei
.
live
.
danmu
.
util
;
import
java.lang.reflect.Field
;
import
java.util.HashMap
;
import
java.util.Map
;
...
...
@@ -21,7 +20,7 @@ import java.util.Map;
* @date: 2018-07-08 18:18:50
* 修改日志:
*/
public
class
STT
Util
{
public
class
DouYu
Util
{
/**
* STT字符串转换为Map
...
...
@@ -50,25 +49,6 @@ public class STTUtil {
return
map
;
}
/**
* STT字符串转换为bean
*
* @param sttString
* @param beanClass
* @param <T>
* @return
*/
public
static
<
T
>
T
toBean
(
String
sttString
,
Class
<
T
>
beanClass
)
{
T
obj
=
ReflectUtil
.
newInstance
(
beanClass
);
Map
<
String
,
Object
>
dataMap
=
toMap
(
sttString
);
Field
[]
fields
=
ReflectUtil
.
getFields
(
beanClass
);
for
(
Field
field
:
fields
)
{
String
fieldName
=
field
.
getName
();
Object
value
=
dataMap
.
get
(
fieldName
);
ReflectUtil
.
setFieldValue
(
obj
,
field
,
value
);
}
return
obj
;
}
/**
* 解码key或value中的转码字符<br>
...
...
@@ -90,18 +70,4 @@ public class STTUtil {
return
str
;
}
public
static
void
main
(
String
[]
args
)
{
String
msg
=
"type@=loginres/userid@=0/roomgroup@=0/pg@=0/sessionid@=0/username@=/nickname@=/live_stat@=0/is_illegal@=0/ill_ct@=/ill_ts@=0/now@=0/ps@=0/es@=0/it@=0/its@=0/npv@=0/best_dlev@=0/cur_lev@=0/nrc@=0/ih@=0/sid@=72983/sahf@=0/sceneid@=0/"
;
msg
=
"type@=uenter/rid@=4835718/uid@=20003668/nn@=须予银鞍绣毂迎倾心人/level@=39/rg@=4/ic@=avatar_v3@S201807@S79596c14f4a7b4dd245d7a0a33f63ca5/nl@=3/rni@=0/el@=eid@AA=1500000113@ASetp@AA=1@ASsc@AA=1@ASef@AA=0@AS@S/sahf@=0/wgei@=0/cbid@=11011/fl@=18/"
;
Map
<
String
,
Object
>
dataMap
=
STTUtil
.
toMap
(
msg
);
for
(
String
key
:
dataMap
.
keySet
())
{
System
.
out
.
println
(
"key:"
+
key
+
" val:"
+
dataMap
.
get
(
key
));
}
System
.
out
.
println
(
decrypt
(
"eid@AA=1500000113@ASetp@AA=1@ASsc@AA=1@ASef@AA=0@AS@S"
));
}
}
src/main/java/com/zhiwei/live/roominfo/DouYuRoomInfoCrawler.java
View file @
325fad04
...
...
@@ -29,6 +29,29 @@ public class DouYuRoomInfoCrawler {
*/
public
static
RoomInfo
getRoomInfoByRoomId
(
String
roomId
)
throws
Exception
{
String
url
=
"http://open.douyucdn.cn/api/RoomApi/room/"
+
roomId
;
String
htmlBody
=
httpBoot
.
syncCall
(
RequestUtils
.
wrapGet
(
url
)).
body
().
string
();
if
(!
StringUtils
.
isBlank
(
htmlBody
))
{
JSONObject
data
=
JSONObject
.
parseObject
(
htmlBody
).
getJSONObject
(
"data"
);
String
room_name
=
data
.
getString
(
"room_name"
);
String
user_name
=
data
.
getString
(
"owner_name"
);
Integer
hn
=
data
.
getInteger
(
"hn"
);
int
online
=
data
.
getInteger
(
"online"
);
return
new
RoomInfo
(
PT
,
roomId
,
room_name
,
user_name
,
hn
);
}
else
{
logger
.
info
(
"此次采集页面中不包含房间信息字段, 此次页面信息为:{}"
,
htmlBody
);
return
null
;
}
}
/**
* 根据房间id获取房间信息
* @param roomId
* @return
* @throws Exception
*/
public
static
RoomInfo
getRoomInfoProxyByRoomId
(
String
roomId
)
throws
Exception
{
String
url
=
"http://open.douyucdn.cn/api/RoomApi/room/"
+
roomId
;
String
htmlBody
=
httpBoot
.
syncCall
(
RequestUtils
.
wrapGet
(
url
),
ProxyHolder
.
NAT_PROXY
).
body
().
string
();
if
(!
StringUtils
.
isBlank
(
htmlBody
))
{
JSONObject
data
=
JSONObject
.
parseObject
(
htmlBody
).
getJSONObject
(
"data"
);
...
...
src/test/java/com/zhiwei/live/test/danmu/BilibiliDanMuTest.java
0 → 100644
View file @
325fad04
package
com
.
zhiwei
.
live
.
test
.
danmu
;
import
com.zhiwei.live.danmu.bilibili.BilibiliClient
;
import
com.zhiwei.live.danmu.bilibili.BilibiliMessage
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
public
class
BilibiliDanMuTest
{
public
static
void
main
(
String
[]
args
)
throws
InterruptedException
{
String
roomUrl
=
"https://live.bilibili.com/139"
;
String
roomId
=
roomUrl
.
replaceAll
(
"https://live.bilibili.com/"
,
""
);
try
{
BilibiliClient
.
getDanmu
(
new
DataCallBack
()
{
@Override
public
void
onData
(
Object
message
)
{
if
(
message
instanceof
BilibiliMessage
)
{
BilibiliMessage
bilibiliMessage
=
(
BilibiliMessage
)
message
;
System
.
out
.
println
(
"-------------"
+
bilibiliMessage
.
toString
());
}
}
},
roomId
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
src/test/java/com/zhiwei/live/test/danmu/DouYuDanMuTest.java
0 → 100644
View file @
325fad04
package
com
.
zhiwei
.
live
.
test
.
danmu
;
import
com.zhiwei.live.danmu.douyu.DouYuMessage
;
import
com.zhiwei.live.danmu.douyu.DouyuClient
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
public
class
DouYuDanMuTest
{
public
static
void
main
(
String
[]
args
)
throws
InterruptedException
{
String
roomUrl
=
"https://live.bilibili.com/139"
;
String
roomId
=
roomUrl
.
replaceAll
(
"https://live.bilibili.com/"
,
""
);
try
{
DouyuClient
.
getDanmu
(
new
DataCallBack
()
{
@Override
public
void
onData
(
Object
message
)
{
if
(
message
instanceof
DouYuMessage
)
{
DouYuMessage
douyuMessage
=
(
DouYuMessage
)
message
;
System
.
out
.
println
(
"-------------"
+
douyuMessage
.
toString
());
}
}
},
roomId
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
src/test/java/com/zhiwei/live/test/danmu/PanDamDanMuTest.java
0 → 100644
View file @
325fad04
package
com
.
zhiwei
.
live
.
test
.
danmu
;
import
com.zhiwei.live.danmu.pandam.PandamClient
;
import
com.zhiwei.live.danmu.pandam.PandamMessage
;
import
com.zhiwei.live.danmu.util.DataCallBack
;
public
class
PanDamDanMuTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
roomId
=
"337852"
;
try
{
PandamClient
.
getDanmu
(
new
DataCallBack
()
{
@Override
public
void
onData
(
Object
message
)
{
if
(
message
instanceof
PandamMessage
)
{
PandamMessage
pandamMessage
=
(
PandamMessage
)
message
;
System
.
out
.
println
(
"-------------"
+
pandamMessage
.
toString
());
}
}
},
roomId
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment