using System; using System.Collections.Generic; using System.Linq; using System.Net.WebSockets; using System.Text; using System.Threading.Tasks; using System.Timers; using BarrageGrab.JsonEntity; using ColorConsole; using Fleck; using Newtonsoft.Json; namespace BarrageGrab { /// /// 弹幕服务 /// internal class WssBarrageService { WebSocketServer socketServer; Dictionary socketList = new Dictionary(); Timer dieout = new Timer(10000); ConsoleWriter console = new ConsoleWriter(); WssBarrageGrab grab = new WssBarrageGrab(); Appsetting Appsetting = Appsetting.Get(); public WssBarrageService() { var socket = new WebSocketServer($"ws://127.0.0.1:{Appsetting.WsProt}"); socket.RestartAfterListenError = true;//异常重启 dieout.Elapsed += Dieout_Elapsed; this.grab.OnChatMessage += Grab_OnChatMessage; this.grab.OnLikeMessage += Grab_OnLikeMessage; this.grab.OnMemberMessage += Grab_OnMemberMessage; this.grab.OnSocialMessage += Grab_OnSocialMessage; this.grab.OnGiftMessage += Grab_OnGiftMessage; this.grab.OnRoomUserSeqMessage += Grab_OnRoomUserSeqMessage; this.grab.OnFansclubMessage += Grab_OnFansclubMessage; ; //this.grab.OnControlMessage += Grab_OnControlMessage; this.socketServer = socket; //dieout.Start(); } private MsgUser GetUser(dynamic obj) { MsgUser user = new MsgUser() { DisplayId = obj.User.displayId, Gender = obj.User.Gender, Id = obj.User.Id, Level = obj.User.Level, Nickname = obj.User.Nickname }; return user; } private void Grab_OnFansclubMessage(object sender, ProtoEntity.FansclubMessage e) { var enty = new FansclubMsg() { Content = e.Content, RoomId = e.commonInfo.roomId, Type = e.Type, User = GetUser(e) }; Print($"[粉丝团消息] {enty.User.GenderToString()} " + enty.Content, ConsoleColor.Blue); var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.粉丝团信息); var json = JsonConvert.SerializeObject(pack); this.Broadcast(json); } private void Grab_OnRoomUserSeqMessage(object sender, ProtoEntity.RoomUserSeqMessage e) { var enty = new UserSeqMsg() { OnlineUserCount = e.Total, TotalUserCount = e.totalUser, TotalUserCountStr = e.totalPvForAnchor, OnlineUserCountStr = e.onlineUserForAnchor, RoomId = e.Common.roomId, Content = $"当前直播间人数 {e.onlineUserForAnchor},累计直播间人数 {e.totalPvForAnchor}", User = null }; Print($"[直播间统计] " + enty.Content, ConsoleColor.Magenta); var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.直播间统计); var json = JsonConvert.SerializeObject(pack); this.Broadcast(json); } private void Grab_OnGiftMessage(object sender, ProtoEntity.GiftMessage e) { var enty = new GiftMsg() { RoomId = e.Common.roomId, Content = e.Common.Describe, GiamondCount = e.Gift.diamondCount, GiftCount = e.repeatCount, GiftId = e.giftId, GiftName = e.Gift.Name, User = GetUser(e) }; Print($"[礼物消息] " + $"{enty.User.GenderToString()} " + enty.Content, ConsoleColor.Red); var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.送礼); var json = JsonConvert.SerializeObject(pack); this.Broadcast(json); } private void Grab_OnSocialMessage(object sender, ProtoEntity.SocialMessage e) { var enty = new Msg() { Content = $"{e.User.Nickname} 关注了主播", RoomId = e.Common.roomId, User = GetUser(e) }; Print($"[关注消息] {enty.User.GenderToString()} " + enty.Content, ConsoleColor.Yellow); var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.关注主播); var json = JsonConvert.SerializeObject(pack); this.Broadcast(json); } private void Grab_OnMemberMessage(object sender, ProtoEntity.MemberMessage e) { var enty = new Msg() { Content = $"{e.User.Nickname} 来了", RoomId = e.Common.roomId, User = GetUser(e) }; Print($"[进直播间] {enty.User.GenderToString()} " + enty.Content, ConsoleColor.Green); var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.进入直播间); var json = JsonConvert.SerializeObject(pack); this.Broadcast(json); } private void Grab_OnLikeMessage(object sender, ProtoEntity.LikeMessage e) { var enty = new LikeMsg() { Count = e.Count, Content = $"{e.User.Nickname} 为主播点了{e.Count}个赞", RoomId = e.Common.roomId, User = GetUser(e) }; Print($"[点赞消息] {enty.User.GenderToString()} " + enty.Content, ConsoleColor.Cyan); var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.点赞); var json = JsonConvert.SerializeObject(pack); this.Broadcast(json); } private void Grab_OnChatMessage(object sender, ProtoEntity.ChatMessage e) { var enty = new Msg() { Content = e.Content, RoomId = e.Common.roomId, User = GetUser(e) }; Print($"[弹幕消息] {enty.User.GenderToString()} {enty.User.Nickname}: {enty.Content}", ConsoleColor.White); var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.消息); var json = JsonConvert.SerializeObject(pack); this.Broadcast(json); } private void Print(string msg, ConsoleColor color) { if (Appsetting.PrintBarrage) { console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")} " + msg + "\n", color); } } private void Dieout_Elapsed(object sender, ElapsedEventArgs e) { var now = DateTime.Now; var dieoutKvs = socketList.Where(w => w.Value.LastPing.AddSeconds(dieout.Interval * 3) < now).ToList(); dieoutKvs.ForEach(f => f.Value.Socket.Close()); } private void Listen(IWebSocketConnection socket) { //客户端url string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort; if (!socketList.ContainsKey(clientUrl)) { socketList.Add(clientUrl, new UserState(socket)); console.WriteLine($"{DateTime.Now.ToLongTimeString()} 已经建立与[{clientUrl}]的连接", ConsoleColor.Green); } else { socketList[clientUrl].Socket = socket; } socket.OnClose = () => { socketList.Remove(clientUrl); console.WriteLine($"{DateTime.Now.ToLongTimeString()} 已经关闭与[{clientUrl}]的连接", ConsoleColor.Red); }; socket.OnPing = (data) => { socketList[clientUrl].LastPing = DateTime.Now; socket.SendPong(Encoding.UTF8.GetBytes("pong")); }; } /// /// 广播消息 /// /// public void Broadcast(string msg) { foreach (var user in socketList) { var socket = user.Value; socket.Socket.Send(msg); } } public void StartListen() { this.grab.Start(); //启动代理 this.socketServer.Start(Listen);//启动监听 console.WriteLine($"{this.socketServer.Location} 弹幕服务已启动...", ConsoleColor.Green); Console.Title = $"抖音弹幕监听推送 [{this.socketServer.Location}]"; } /// /// 关闭服务器连接 /// public void Close() { socketList.Values.ToList().ForEach(f => f.Socket.Close()); socketList.Clear(); socketServer.Dispose(); grab.Dispose(); console.WriteLine("服务器已关闭..."); } class UserState { /// /// 套接字 /// public IWebSocketConnection Socket { get; set; } /// /// 上次发起心跳包时间 /// public DateTime LastPing { get; set; } = DateTime.Now; public UserState() { } public UserState(IWebSocketConnection socket) { Socket = socket; } } } }