Files
DanMuRead/BarrageGrab/WssBarrageService.cs
T
2022-10-06 17:44:08 +08:00

217 lines
7.0 KiB
C#

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
{
/// <summary>
/// 弹幕服务
/// </summary>
internal class WssBarrageService
{
WebSocketServer socketServer;
Dictionary<string, UserState> socketList = new Dictionary<string, UserState>();
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.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_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)
};
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.Common.Describe,
RoomId = e.Common.roomId,
User = GetUser(e)
};
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.Common.Describe,
RoomId = e.Common.roomId,
User = GetUser(e)
};
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.Common.Describe,
RoomId = e.Common.roomId,
User = GetUser(e)
};
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)
};
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.消息);
var json = JsonConvert.SerializeObject(pack);
this.Broadcast(json);
}
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"));
};
}
/// <summary>
/// 广播消息
/// </summary>
/// <param name="msg"></param>
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);
}
/// <summary>
/// 关闭服务器连接
/// </summary>
public void Close()
{
socketList.Values.ToList().ForEach(f => f.Socket.Close());
socketList.Clear();
socketServer.Dispose();
grab.Dispose();
console.WriteLine("服务器已关闭...");
}
class UserState
{
/// <summary>
/// 套接字
/// </summary>
public IWebSocketConnection Socket { get; set; }
/// <summary>
/// 上次发起心跳包时间
/// </summary>
public DateTime LastPing { get; set; } = DateTime.Now;
public UserState()
{
}
public UserState(IWebSocketConnection socket)
{
Socket = socket;
}
}
}
}