.directory
demo/danmu.log
+a.json
数据为WS_OP_MESSAGE类型的
*/
-var msglog = p.Logf().New().Open("danmu.log").Level(0)
+var msglog = p.Logf().New().Base(-1, "Msg.go>").Open("danmu.log").Level(1)
func Msg(b []byte, compress bool) {
if compress {
s := string(b[16:packL])
b = b[packL:]
if cmd := p.Json().GetValFromS(s, "cmd");cmd == nil {
- msglog.E("->", "cmd", s)
+ msglog.E("cmd", s)
return
} else {
switch cmd.(string) {
- case "COMBO_SEND":;
- case "INTERACT_WORD":;
- case "ACTIVITY_BANNER_UPDATE_V2":;
- case "SEND_GIFT":;//礼物
- case "NOTICE_MSG":;//礼物公告
- case "ROOM_BANNER":;//未知
- case "ONLINERANK":;//未知
- case "WELCOME":;//进入提示
- case "ROOM_SILENT_OFF", "ROOM_SILENT_ON":;
- case "HOUR_RANK_AWARDS":;
- case "ROOM_RANK":;
- case "WELCOME_GUARD":;
- case "GUARD_BUY":;
- case "ROOM_SHIELD":;
- case "USER_TOAST_MSG":;
- case "ROOM_BLOCK_MSG":room_block_msg(s)
- case "PREPARING":preparing(s)
- case "LIVE":live(s)
- case "SUPER_CHAT_MESSAGE", "SUPER_CHAT_MESSAGE_JPN":super_chat_message(s)
- case "PANEL":panel(s)
- case "ENTRY_EFFECT":entry_effect(s)
- case "ROOM_REAL_TIME_MESSAGE_UPDATE":roominfo(s)
- case "DANMU_MSG":danmu(s)
+ case "COMBO_SEND":
+ case "INTERACT_WORD":
+ case "ACTIVITY_BANNER_UPDATE_V2":
+ case "NOTICE_MSG":
+ case "ROOM_BANNER":
+ case "ONLINERANK":
+ case "WELCOME":
+ case "HOUR_RANK_AWARDS":
+ case "ROOM_RANK":
+ case "ROOM_SHIELD":
+ case "USER_TOAST_MSG":
+ case "GUARD_BUY"://大航海购买
+ case "WELCOME_GUARD"://welcome_guard(s)//大航海进入
+ case "ROOM_SILENT_OFF", "ROOM_SILENT_ON":roomsilent(s);//禁言
+ case "SEND_GIFT":send_gift(s)//礼物
+ case "ROOM_BLOCK_MSG":room_block_msg(s)//封禁
+ case "PREPARING":preparing(s)//下播
+ case "LIVE":live(s)//开播
+ case "SUPER_CHAT_MESSAGE", "SUPER_CHAT_MESSAGE_JPN":super_chat_message(s)//打赏
+ case "PANEL":panel(s)//排行榜
+ case "ENTRY_EFFECT":entry_effect(s)//进入特效
+ case "ROOM_REAL_TIME_MESSAGE_UPDATE":roominfo(s)//粉丝数
+ case "DANMU_MSG":danmu(s)//弹幕
default:msglog.I("Unknow cmd", s)
}
}
return
}
+func welcome_guard(s string){
+ username := p.Json().GetValFromS(s, "data.username");
+ guard_level := p.Json().GetValFromS(s, "data.guard_level");
+
+ var sh = []interface{}{"欢迎"}
+
+ if username != nil {
+ sh = append(sh, username.(string), "进入直播间")
+ }
+ if guard_level != nil {
+ sh = append(sh, "等级", int64(guard_level.(float64)))
+ }
+ if len(sh) == 0 {return}
+
+ msglog.I(sh...)
+}
+
+func send_gift(s string){
+ coin_type := p.Json().GetValFromS(s, "data.coin_type");
+ num := p.Json().GetValFromS(s, "data.num");
+ uname := p.Json().GetValFromS(s, "data.uname");
+ action := p.Json().GetValFromS(s, "data.action");
+ giftName := p.Json().GetValFromS(s, "data.giftName");
+ price := p.Json().GetValFromS(s, "data.price");
+
+ var sh []interface{}
+
+ if uname != nil {
+ sh = append(sh, uname.(string))
+ }
+ if action != nil {
+ sh = append(sh, action.(string))
+ }
+ if num != nil {
+ sh = append(sh, int64(num.(float64)), "x")
+ }
+ if giftName != nil {
+ sh = append(sh, giftName.(string))
+ }
+ if price != nil {
+ sh = append(sh, "(", int64(price.(float64)), "x 金瓜子 )")
+ }
+
+ if len(sh) == 0 {return}
+
+ if coin_type.(string) == "silver" {msglog.T(sh...);return}
+ msglog.I(sh...)
+}
+
func room_block_msg(s string) {
if uname := p.Json().GetValFromS(s, "uname");uname == nil {
- msglog.E("->", "uname", uname)
+ msglog.E("uname", uname)
return
} else {
- msglog.I("用户", uname.(string), "已被封禁")
+ msglog.I("用户", uname, "已被封禁")
}
}
func preparing(s string) {
if roomid := p.Json().GetValFromS(s, "roomid");roomid == nil {
- msglog.E("->", "roomid", roomid)
+ msglog.E("roomid", roomid)
return
} else {
msglog.I("房间", roomid.(string), "下播了")
func live(s string) {
if roomid := p.Json().GetValFromS(s, "roomid");roomid == nil {
- msglog.E("->", "roomid", roomid)
+ msglog.E("roomid", roomid)
return
} else {
msglog.I("房间", roomid.(string), "开播了")
message := p.Json().GetValFromS(s, "data.message");
message_jpn := p.Json().GetValFromS(s, "data.message_jpn");
- var sh []interface{}
+ var sh = []interface{}{"打赏: "}
if uname != nil {
- sh = append(sh, []interface{}{uname.(string)})
+ sh = append(sh, uname.(string))
}
if price != nil {
- sh = append(sh, []interface{}{"¥", int64(price.(float64))})
+ sh = append(sh, "¥", int64(price.(float64)))
}
if message != nil {
- sh = append(sh, []interface{}{message.(string)})
+ sh = append(sh, message.(string))
}
if message_jpn != nil {
- sh = append(sh, []interface{}{message_jpn.(string)})
+ sh = append(sh, message_jpn.(string))
}
- if len(sh) != 0 {msglog.I("打赏: ", sh)}
+ if len(sh) != 0 {msglog.I(sh...)}
}
func panel(s string){
if note := p.Json().GetValFromS(s, "data.note");note == nil {
- msglog.E("->", "note", note)
+ msglog.E("note", note)
return
} else {
- msglog.I(note.(string))
+ msglog.I("排行", note.(string))
}
-
}
func entry_effect(s string){
if copy_writing := p.Json().GetValFromS(s, "data.copy_writing");copy_writing == nil {
- msglog.E("->", "copy_writing", copy_writing)
+ msglog.E("copy_writing", copy_writing)
return
} else {
msglog.I(copy_writing.(string))
func roomsilent(s string){
if level := p.Json().GetValFromS(s, "data.level");level == nil {
- msglog.E("->", "level", level)
+ msglog.E("level", level)
return
} else {
if level.(float64) == 0 {msglog.I("主播关闭了禁言")}
msglog.I("主播开启了等级禁言:", int64(level.(float64)))
}
-
}
func roominfo(s string){
var sh []interface{}
if fans != nil {
- sh = append(sh, []interface{}{"粉丝总人数:", int64(fans.(float64))})
+ sh = append(sh, "粉丝总人数:", int64(fans.(float64)))
}
if fans_club != nil {
- sh = append(sh, []interface{}{"粉丝团人数:", int64(fans_club.(float64))})
+ sh = append(sh, "粉丝团人数:", int64(fans_club.(float64)))
}
- if len(sh) != 0 {msglog.I(sh)}
+ if len(sh) != 0 {msglog.I(sh...)}
}
func danmu(s string) {
if info := p.Json().GetValFromS(s, "info");info == nil {
- msglog.E("->", "info", info)
+ msglog.E("info", info)
return
} else {
infob := info.([]interface{})
## bilibili 直播弹幕机
+### 当前支持功能列表
+```
+Msg.go
+case 后有函数调用的为支持,无调用的为未支持,注释掉的为未启用
+
+case "COMBO_SEND":
+case "INTERACT_WORD":
+case "ACTIVITY_BANNER_UPDATE_V2":
+case "NOTICE_MSG":
+case "ROOM_BANNER":
+case "ONLINERANK":
+case "WELCOME":
+case "HOUR_RANK_AWARDS":
+case "ROOM_RANK":
+case "ROOM_SHIELD":
+case "USER_TOAST_MSG":
+case "GUARD_BUY"://大航海购买
+case "WELCOME_GUARD"://welcome_guard(s)//大航海进入
+case "ROOM_SILENT_OFF", "ROOM_SILENT_ON":roomsilent(s);//禁言
+case "SEND_GIFT":send_gift(s)//礼物
+case "ROOM_BLOCK_MSG":room_block_msg(s)//封禁
+case "PREPARING":preparing(s)//下播
+case "LIVE":live(s)//开播
+case "SUPER_CHAT_MESSAGE", "SUPER_CHAT_MESSAGE_JPN":super_chat_message(s)//打赏
+case "PANEL":panel(s)//排行榜
+case "ENTRY_EFFECT":entry_effect(s)//进入特效
+case "ROOM_REAL_TIME_MESSAGE_UPDATE":roominfo(s)//粉丝数
+case "DANMU_MSG":danmu(s)//弹幕
+
+```
+
### demo
```
git clone https://github.com/qydysky/bili_danmu.git
go run main.go
```
```
-输入房间号: 213
-INFO: 2020/09/14 21:02:58 [send hello to wss://tx-sh-live-comet-02.chat.bilibili.com/sub]
-ERROR: 2020/09/14 21:02:58 [-> websocket: close 1006 (abnormal closure): unexpected EOF]
-INFO: 2020/09/14 21:02:59 [send hello to wss://tx-gz-live-comet-01.chat.bilibili.com/sub]
-ERROR: 2020/09/14 21:02:59 [-> websocket: close 1006 (abnormal closure): unexpected EOF]
-INFO: 2020/09/14 21:03:00 [send hello to wss://broadcastlv.chat.bilibili.com/sub]
-INFO: 2020/09/14 21:03:00 [wss://broadcastlv.chat.bilibili.com/sub hello!]
-INFO: 2020/09/14 21:06:56 [祸美人M : 鬼来了]
-INFO: 2020/09/14 21:06:56 [泽北SAMAい : wc]
-INFO: 2020/09/14 21:06:57 [OurTube丶Now : 偷窥]
-INFO: 2020/09/14 21:06:57 [云又云又云 : 什么游戏?]
-INFO: 2020/09/14 21:06:57 [GNsetusna : 草]
-INFO: 2020/09/14 21:06:58 [amuseustillwedie : 闸总你出来!]
-INFO: 2020/09/14 21:06:58 [Kinoko7pro : 游戏名:零~月蚀之假面~]
-INFO: 2020/09/14 21:07:00 [mousebat04 : 就是能登麻美子]
-INFO: 2020/09/14 21:07:02 [紅魔の月時計 : 毫无感觉]
-INFO: 2020/09/14 21:07:03 [0小牙0 : 想到了冲自己冲冲冲]
-INFO: 2020/09/14 21:07:03 [gamestarts0 : 拿到武器必遇怪]
-INFO: 2020/09/14 21:07:04 [为什么鸽 : 我敲]
-INFO: 2020/09/14 21:07:04 [欢迎舰长 <%林嘉驹%> 进入直播间]
-INFO: 2020/09/14 21:07:04 [Icarus丶 : 这不就是小圆]
-INFO: 2020/09/14 21:07:05 [伶伶miss : 妖孽!哪里逃]
-INFO: 2020/09/14 21:07:07 [阿克酱 : 胆子好大啊]
-INFO: 2020/09/14 21:07:08 [Fdalmir : 偷窥]
-INFO: 2020/09/14 21:07:08 [欣泠丶 : 那个是圆香吧]
-INFO: 2020/09/14 21:07:08 [[[粉丝总人数: 599214] [粉丝团人数: 13796]]]
-INFO: 2020/09/14 21:07:09 [_墨轩- : 要是我直接哭了]
-INFO: 2020/09/14 21:07:09 [百合花业余植物学家 : 要是等流歌来可能就不会全灭了]
-INFO: 2020/09/14 21:07:09 [单机 第70名]
-INFO: 2020/09/14 21:07:11 [红脸的野郎 : 小姐姐;爱玩啊]
-INFO: 2020/09/14 21:07:11 [三月三日三重樱 : 大威天龙!]
+输入房间号: 13946381
+INFO: 2020/09/15 06:40:21 [bili_danmu.go>测试] [连接到房间 13946381]
+INFO: 2020/09/15 06:40:21 [bili_danmu.go>测试] [连接 wss://tx-sh-live-comet-01.chat.bilibili.com/sub]
+INFO: 2020/09/15 06:40:21 [bili_danmu.go>测试] [已连接到房间 13946381]
+INFO: 2020/09/15 06:40:22 [bili_danmu.go>测试] [开始心跳]
+INFO: 2020/09/15 06:40:29 [Msg.go>] [pek0pek0 : 外掛]
+INFO: 2020/09/15 06:40:30 [Msg.go>] [NealxS : 明显是挂了]
+INFO: 2020/09/15 06:40:33 [Msg.go>] [懒得起昵称丶 : 真大哥]
+INFO: 2020/09/15 06:40:36 [Msg.go>] [恩里克-普奇-神父 : 这场战役我们失去了天义佬]
+INFO: 2020/09/15 06:40:36 [Msg.go>] [ntwww 投喂 1 x 冰阔落 ( 1000 x 金瓜子 )]
+INFO: 2020/09/15 06:40:38 [Msg.go>] [方舟之下幽兰呆鹅 : 外挂]
+INFO: 2020/09/15 06:40:38 [Msg.go>] [一般通りのまこちゅう : 科技大佬]
+^CINFO: 2020/09/15 06:46:14 [ws.go>心跳] [fin]
+INFO: 2020/09/15 06:46:14 [ws.go>关闭] [*ws.Close]
+INFO: 2020/09/15 06:46:14 [ws.go>关闭] [ok]
-ctrl+c退出,弹幕会同时追加记录到文件danmu.log中
+ctrl+c退出,日志会同时追加记录到文件danmu.log中
```
更多内容详见注释,如有疑问请发issues
\ No newline at end of file
}
func New_api(Roomid int) (o *api) {
- l := p.Logf().New().Level(LogLevel).T("New_api")
+ l := p.Logf().New().Base(-1, "api.go>新建").Level(LogLevel).T("New_api")
defer l.Block()
- l.T("->", "ok")
+ l.T("ok")
o = new(api)
o.Roomid = Roomid
o.Get_info()
func (i *api) Get_info() (o *api) {
o = i
- l := p.Logf().New().Level(LogLevel).T("*api.Get_info")
+ l := p.Logf().New().Base(-1, "api.go>获取房号").Level(LogLevel).T("*api.Get_info")
defer l.Block()
if o.Roomid == 0 {
- l.E("->", "还未New_api")
+ l.E("还未New_api")
return
}
Roomid := strconv.Itoa(o.Roomid)
Timeout:10,
Retry:2,
});err != nil {
- l.E("->", err)
+ l.E(err)
return
}
res := string(req.Respon)
if msg := p.Json().GetValFrom(res, "msg");msg == nil || msg != "ok" {
- l.E("->", "msg", msg)
+ l.E("msg", msg)
return
}
if Uid := p.Json().GetValFrom(res, "data.uid");Uid == nil {
- l.E("->", "data.uid", Uid)
+ l.E("data.uid", Uid)
return
} else {
o.Uid = int(Uid.(float64))
}
if room_id := p.Json().GetValFrom(res, "data.room_id");room_id == nil {
- l.E("->", "data.room_id", room_id)
+ l.E("data.room_id", room_id)
return
} else {
- l.T("->", "ok")
+ l.T("ok")
o.Roomid = int(room_id.(float64))
}
return
func (i *api) Get_host_Token() (o *api) {
o = i
- l := p.Logf().New().Level(LogLevel).T("*api.Get_host_Token")
+ l := p.Logf().New().Base(-1, "api.go>获取host key").Level(LogLevel).T("*api.Get_host_Token")
defer l.Block()
if o.Roomid == 0 {
- l.E("->", "还未New_api")
+ l.E("还未New_api")
return
}
Roomid := strconv.Itoa(o.Roomid)
Timeout:10,
Retry:2,
});err != nil {
- l.E("->", err)
+ l.E(err)
return
}
res := string(req.Respon)
if msg := p.Json().GetValFrom(res, "message");msg == nil || msg != "0" {
- l.E("->", "message", msg)
+ l.E("message", msg)
return
}
_Token := p.Json().GetValFrom(res, "data.token")
if _Token == nil {
- l.E("->", "data.token", _Token, res)
+ l.E("data.token", _Token, res)
return
}
o.Token = _Token.(string)
if host_list := p.Json().GetValFrom(res, "data.host_list");host_list == nil {
- l.E("->", "data.host_list", host_list)
+ l.E("data.host_list", host_list)
return
} else {
for k, v := range host_list.([]interface{}) {
if _host := p.Json().GetValFrom(v, "host");_host == nil {
- l.E("->", "data.host_list[", k, "].host", _host)
+ l.E("data.host_list[", k, "].host", _host)
continue
} else {
o.Url = append(o.Url, "wss://" + _host.(string) + "/sub")
}
}
- l.T("->", "ok")
+ l.T("ok")
}
return
const LogLevel = 1
func Demo() {
- l:=p.Logf().New().Open("danmu.log").Level(LogLevel)
+ l:=p.Logf().New().Open("danmu.log").Base(-1, "bili_danmu.go>测试").Level(LogLevel)
defer l.Block()
//ctrl+c退出
for !break_sign {
//获取房间相关信息
api := New_api(room).Get_host_Token()
- if len(api.Url) == 0 || api.Roomid == 0 || api.Token == "" {
+ if len(api.Url) == 0 || api.Roomid == 0 || api.Token == "" || api.Uid == 0 {
l.E("some err")
return
}
//SendChan 传入发送[]byte
//RecvChan 接收[]byte
- l.I("send hello to", v)
+ l.I("连接", v)
ws.SendChan <- hello_send(api.Roomid, api.Token)
if hello_ok(<- ws.RecvChan) {
- l.I(v, "hello!")
- l.I("已连接", room)
+ l.I("已连接到房间", room)
//开始心跳
go func(){
p.Sys().MTimeoutf(500)//500ms
+ l.I("开始心跳")
heartbeatmsg, heartinterval := heartbeat()
ws.Heartbeat(1000 * heartinterval, heartbeatmsg)
}()
//返回数据分派
func Reply(b []byte) {
- l := p.Logf().New().Level(LogLevel)
+ l := p.Logf().New().Base(-1, "bili_danmu.go>返回分派").Level(LogLevel)
defer l.Block()
if ist, _ := headChe(b[:16], len(b), WS_BODY_PROTOCOL_VERSION_DEFLATE, WS_OP_MESSAGE, 0, 4); ist {
func headChe(head []byte, datalenght,Bodyv,Opeation,Sequence,show int) (bool,int32) {
if len(head) != WS_PACKAGE_HEADER_TOTAL_LENGTH {return false, 0}
- l := p.Logf().New().Level(show)
+ l := p.Logf().New().Base(-1, "bili_danmu.go>头检查").Level(show)
defer l.Block()
packL := Btoi32(head[:4])
//认证生成与检查
func hello_send(roomid int, key string) []byte {
- l := p.Logf().New().Level(LogLevel).T("hello_ws")
+ l := p.Logf().New().Base(-1, "bili_danmu.go>头生成").Level(LogLevel).T("hello_ws")
defer l.Block()
if roomid == 0 || key == "" {
- l.E("->", "roomid == 0 || key == \"\"")
+ l.E("roomid == 0 || key == \"\"")
return []byte("")
}
github.com/qydysky/bili_danmu v0.0.0-20200914143111-fe17ba7dd5a9/go.mod h1:hejetn5M5YL0dZpEBtswTWEOwS9Rq8eRiN3SFco3JXA=
github.com/qydysky/part v0.0.0-20200914123330-afade058e33d h1:um1WzsGzwD6h+1W3jqGcWJPVr4kT5gmRRaXXVwO7nb4=
github.com/qydysky/part v0.0.0-20200914123330-afade058e33d/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
+github.com/qydysky/part v0.0.0-20200914222559-436abc80976a h1:Wurgg5wiPemdfbO9lzOywZWst0DyEI610gUo3HV/ros=
+github.com/qydysky/part v0.0.0-20200914222559-436abc80976a/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.8+incompatible h1:8c7Atn0FAUZJo+f4wYbN0iVpdWniCQk7IYwGtgdh1mY=
github.com/shirou/gopsutil v2.20.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
require (
github.com/gorilla/websocket v1.4.2
github.com/klauspost/compress v1.11.0 // indirect
- github.com/qydysky/part v0.0.0-20200914123330-afade058e33d
+ github.com/qydysky/part v0.0.0-20200914225111-80645055bc83
github.com/shirou/gopsutil v2.20.8+incompatible // indirect
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
github.com/qydysky/part v0.0.0-20200912061031-0f3a305b4afb/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
github.com/qydysky/part v0.0.0-20200914123330-afade058e33d h1:um1WzsGzwD6h+1W3jqGcWJPVr4kT5gmRRaXXVwO7nb4=
github.com/qydysky/part v0.0.0-20200914123330-afade058e33d/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
+github.com/qydysky/part v0.0.0-20200914222559-436abc80976a h1:Wurgg5wiPemdfbO9lzOywZWst0DyEI610gUo3HV/ros=
+github.com/qydysky/part v0.0.0-20200914222559-436abc80976a/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
+github.com/qydysky/part v0.0.0-20200914225111-80645055bc83 h1:iAqwOKLRNeJ2kwgFOWRifJGEomYPKvCpygSQqSXzdSM=
+github.com/qydysky/part v0.0.0-20200914225111-80645055bc83/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
github.com/shirou/gopsutil v2.20.7+incompatible h1:Ymv4OD12d6zm+2yONe39VSmp2XooJe8za7ngOLW/o/w=
github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.8+incompatible h1:8c7Atn0FAUZJo+f4wYbN0iVpdWniCQk7IYwGtgdh1mY=
}
func New_ws(url string) (o *ws) {
- l := p.Logf().New().Level(LogLevel).T("New_ws")
+ l := p.Logf().New().Base(-1, "ws.go>新建").Level(LogLevel).T("New_ws")
defer l.Block()
- l.T("->", "ok")
+ l.T("ok")
o = new(ws)
o.url = url
o.SendChan = make(chan []byte, 1e4)
func (i *ws) Handle() (o *ws) {
o = i
- l := p.Logf().New().Level(LogLevel).T("*ws.handle")
+ l := p.Logf().New().Base(-1, "ws.go>处理").Level(LogLevel).T("*ws.handle")
defer l.Block()
if o.used {
- l.E("->", "o.used")
+ l.E("o.used")
return
}
if o.url == "" {
- l.E("->", "o.url == \"\"")
+ l.E("o.url == \"\"")
return
}
c, _, err := websocket.DefaultDialer.Dial(o.url, nil)
if err != nil {
- l.E("->", err)
+ l.E(err)
return
}
defer c.Close()
- l.T("->", "ok")
+ l.T("ok")
o.interrupt = make(chan struct{})
done := make(chan struct{})
_, message, err := c.ReadMessage()
if err != nil {
if !websocket.IsCloseError(err, websocket.CloseNormalClosure) {
- l.E("->", err)
+ l.E(err)
}
return
}
case t := <- o.SendChan:
err := c.WriteMessage(websocket.TextMessage, t)
if err != nil {
- l.E("->", "write:", err)
+ l.E("write:", err)
return
}
case <- o.interrupt:
- l.I("->", "interrupt")
+ l.I("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
- l.E("->", err)
+ l.E(err)
}
select {
case <- done:
func (i *ws) Heartbeat(Millisecond int, msg []byte) (o *ws) {
o = i
- l := p.Logf().New().Level(LogLevel).T("*ws.heartbeat")
+ l := p.Logf().New().Base(-1, "ws.go>心跳").Level(LogLevel).T("*ws.heartbeat")
defer l.Block()
if !o.used {
- l.E("->", "!o.used")
+ l.E("!o.used")
return
}
o.SendChan <- msg
- l.T("->", "ok")
+ l.T("ok")
go func(){
ticker := time.NewTicker(time.Duration(Millisecond)*time.Millisecond)
case <-ticker.C:
o.SendChan <- msg
case <- o.interrupt:
- l.I("->", "fin")
+ l.I("fin")
return
}
}
}
func (o *ws) Close() {
- l := p.Logf().New().Level(LogLevel).I("*ws.Close")
+ l := p.Logf().New().Base(-1, "ws.go>关闭").Level(LogLevel).I("*ws.Close")
defer l.Block()
if !o.used {
- l.I("->", "!o.used")
+ l.I("!o.used")
return
}
o.used = false
close(o.interrupt)
- l.I("->", "ok")
+ l.I("ok")
}
func (o *ws) Isclose() bool {