2025-07-04 09:50:02 +08:00

216 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Fleck;
using MyCode.Project.Domain.Message.Response.WebSocket;
using MyCode.Project.Domain.Model;
using MyCode.Project.Infrastructure.Common;
using MyCode.Project.Infrastructure.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace MyCode.Project.Services.BLL
{
public class WebSocketBLL
{
//所有的连接对象
public static List<ConnUser<IWebSocketConnection>> _connections = new List<ConnUser<IWebSocketConnection>>();
public WebSocketBLL()
{ }
#region GetConnUser()
/// <summary>
/// 根据请求路径得到当前的连接对象
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public ConnUser<IWebSocketConnection> GetConnUser(string path)
{
path = path.Replace("/", "");
//path = path.Replace("?");
var nv = HttpUtility.ParseQueryString(path);
if (nv.Count == 0) { return null; }
var id = Convert.ToInt64(nv.Get("id"));
var type = Convert.ToInt32(nv.Get("type"));
var timeStamp = Convert.ToInt64(nv.Get("t"));
if (id == 0) { return null; }
return new ConnUser<IWebSocketConnection>
{
Type = type,
TimeStamp = timeStamp,
Id = id
};
}
#endregion
#region OnError()
/// <summary>
/// 出错事件
/// </summary>
/// <param name="exception"></param>
public void OnError(Exception exception,IWebSocketConnection conn)
{
var error = $"{DateTime.Now}OnError{conn.ConnectionInfo.Path},{exception}";
Console.WriteLine(error);
FleckLog.Error(error);
DingDingHelper.SendMsg(error);
//出错则要关闭
OnCloseEvent(conn);
}
#endregion
#region OnCloseEvent()
/// <summary>
/// 关闭事件
/// </summary>
public void OnCloseEvent(IWebSocketConnection conn)
{
//关闭
var connUser = GetConnUser(conn.ConnectionInfo.Path);
var matchUser = _connections.Find(p => p.Type == connUser.Type && p.Id == connUser.Id && p.TimeStamp == connUser.TimeStamp);
if (matchUser != null) { _connections.Remove(matchUser); }
Console.WriteLine($"{DateTime.Now}CheckOnline{CheckOnline()}");
}
#endregion
#region OnOpenEvent()
/// <summary>
/// 连接上事件
/// </summary>
/// <param name="conn"></param>
public void OnOpenEvent(IWebSocketConnection conn)
{
string clientUrl = conn.ConnectionInfo.ClientIpAddress + ":" + conn.ConnectionInfo.ClientPort;
Console.WriteLine($"{DateTime.Now}OnOpenEvent{conn.ConnectionInfo.Path}");
//加入,如果里面存在,则先移除
var connUser = GetConnUser(conn.ConnectionInfo.Path);
if (connUser == null) { return; }
var matchUser = _connections.Find(p => p.Type == connUser.Type && p.Id == connUser.Id && p.TimeStamp == connUser.TimeStamp);
if (matchUser != null) { _connections.Remove(matchUser); }
connUser.Conn = conn;
_connections.Add(connUser);
Console.WriteLine($"{DateTime.Now}CheckOnline{CheckOnline()}");
}
#endregion
#region GetOnlineUsers(线)
/// <summary>
/// 得到在线用户
/// </summary>
/// <returns></returns>
public static List<ConnUser<IWebSocketConnection>> GetOnlineUsers(int type = 0)
{
if (_connections == null || _connections.Count == 0) { return new List<ConnUser<IWebSocketConnection>>(); }
return _connections.Where(p => p.Conn.IsAvailable == true && p.Type == type).ToList();
}
#endregion
#region SendSocketMsg(Socket消息)
/// <summary>
/// 发送websocket信息
/// </summary>
/// <param name="memberId"></param>
/// <param name="msg"></param>
public static bool SendSocketMsg(long id, string jsonMessage,int positonType = 0)
{
var conns = GetOnlineUsers(positonType);
if (conns == null || conns.Count == 0)
{
Console.WriteLine($"{DateTime.Now} 发送Socket消息失败因为{id}不在线");
return false;
}
var memberConns = conns.Where(p => p.Id == id).ToList();
if (memberConns == null || memberConns.Count == 0)
{
Console.WriteLine($"{DateTime.Now} 发送Socket消息失败因为{id}不在线");
return false;
}
foreach (var memberConn in memberConns)
{
memberConn.Conn.Send(jsonMessage);
Console.WriteLine($"{DateTime.Now} 给{memberConn.Id}-{memberConn.TimeStamp},发送消息{jsonMessage}成功");
//LogHelper.Info($"{DateTime.Now} 给{memberConn.UserId}-{memberConn.TimeStamp},发送消息{jsonMessage}成功:{jsonMessage}");
}
return true;
}
#endregion
#region CheckOnline(线)
/// <summary>
/// 根据条件判断客户端是否在线
/// </summary>
/// <returns></returns>
private string CheckOnline()
{
if (_connections == null || _connections.Count == 0) { return "当前没有任何连接"; }
var msg = "";
foreach (var u in _connections)
{
msg = msg + $"id={u.Id}&type={u.Type}&timestamp={u.TimeStamp}在线状态为{u.Conn.IsAvailable}{Environment.NewLine}";
}
return msg;
}
#endregion
#region CheckOnline(/线)
/// <summary>
/// 判断某人/某客户端是否在线
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static bool CheckOnline(long id,int type = 0)
{
//尝试在线再开始
int r = 1;
Console.WriteLine($"{DateTime.Now} 开始检测{id}客户端是否存在");
while (1 == 1)
{
var conns = GetOnlineUsers(type);
var memberConns = conns.Where(p => p.Id == id).ToList();
if (memberConns == null || memberConns.Count == 0)
{
if (r > 30) { throw new BaseException($"id={id}没有在线"); }
Console.WriteLine($"{DateTime.Now} 开始检测{id}客户端是否存在,第{r}次检测");
System.Threading.Thread.Sleep(1000);
r++;
continue;
}
break;
}
Console.WriteLine($"{DateTime.Now} 检测到{id}客户端存在");
return true;
}
#endregion
}
}