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 BarrageGrab.ProtoEntity;
using ColorConsole;
using Fleck;
using Newtonsoft.Json;
using static BarrageGrab.ProtoEntity.Image;
namespace BarrageGrab
{
///
/// 弹幕服务
///
internal class WsBarrageService
{
WebSocketServer socketServer;
Dictionary socketList = new Dictionary();
Timer dieout = new Timer(10000);
ConsoleWriter console = new ConsoleWriter();
WssBarrageGrab grab = new WssBarrageGrab();
Appsetting Appsetting = Appsetting.Current;
bool debug = false;
public WsBarrageService()
{
#if DEBUG
debug = true;
#endif
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 bool CheckRoomId(long roomid)
{
return Appsetting.RoomIds.Length == 0 || Appsetting.RoomIds.Contains(roomid);
}
//解析用户
private MsgUser GetUser(ProtoEntity.User data)
{
MsgUser user = new MsgUser()
{
DisplayId = data.displayId,
Gender = data.Gender,
Id = data.Id,
Level = data.Level,
Nickname = data.Nickname
};
return user;
}
//粉丝团
private void Grab_OnFansclubMessage(object sender, ProtoEntity.FansclubMessage e)
{
if (!CheckRoomId(e.commonInfo.roomId)) return;
var enty = new FansclubMsg()
{
Content = e.Content,
RoomId = e.commonInfo.roomId,
Type = e.Type,
User = GetUser(e.User)
};
Print(enty.User.GenderToString() + " " + enty.Content, ConsoleColor.Blue, BarrageMsgType.粉丝团消息);
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)
{
if (!CheckRoomId(e.Common.roomId)) return;
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, BarrageMsgType.直播间统计);
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)
{
if (!CheckRoomId(e.Common.roomId)) return;
var enty = new GiftMsg()
{
RoomId = e.Common.roomId,
Content = e.Common.Describe,
DiamondCount = e.Gift.diamondCount,
GiftCount = e.repeatCount,
GroupCount = e.groupCount,
GiftId = e.giftId,
GiftName = e.Gift.Name,
User = GetUser(e.User)
};
Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Red, BarrageMsgType.礼物消息);
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)
{
if (!CheckRoomId(e.Common.roomId)) return;
var enty = new Msg()
{
Content = $"{e.User.Nickname} 关注了主播",
RoomId = e.Common.roomId,
User = GetUser(e.User)
};
Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Yellow, BarrageMsgType.关注消息);
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)
{
if (!CheckRoomId(e.Common.roomId)) return;
var enty = new JsonEntity.MemberMessage()
{
Content = $"{e.User.Nickname} 来了 直播间人数:{e.memberCount}",
RoomId = e.Common.roomId,
CurrentCount = e.memberCount,
User = GetUser(e.User)
};
Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Green, BarrageMsgType.进直播间);
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)
{
if (!CheckRoomId(e.Common.roomId)) return;
var enty = new LikeMsg()
{
Count = e.Count,
Content = $"{e.User.Nickname} 为主播点了{e.Count}个赞,总点赞{e.Total}",
RoomId = e.Common.roomId,
Total = e.Total,
User = GetUser(e.User)
};
Print($"{enty.User.GenderToString()} {enty.Content}", ConsoleColor.Cyan, BarrageMsgType.点赞消息);
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)
{
if (!CheckRoomId(e.Common.roomId)) return;
var enty = new Msg()
{
Content = e.Content,
RoomId = e.Common.roomId,
User = GetUser(e.User)
};
Print($"{enty.User.GenderToString()} {enty.User.Nickname}: {enty.Content}", ConsoleColor.White, BarrageMsgType.弹幕消息);
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.弹幕消息);
var json = JsonConvert.SerializeObject(pack);
this.Broadcast(json);
}
private void Print(string msg, ConsoleColor color, BarrageMsgType bartype)
{
if (!Appsetting.PrintFilter.Any(a => a == bartype.GetHashCode())) return;
if (Appsetting.PrintBarrage)
{
console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")} [{bartype.ToString()}] " + 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;
}
}
}
}