216 lines
7.2 KiB
C#
216 lines
7.2 KiB
C#
|
|
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}×tamp={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
|
|||
|
|
}
|
|||
|
|
}
|