You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
482 lines
20 KiB
482 lines
20 KiB
using com.sun.org.apache.xpath.@internal.operations; |
|
using Elight.Entity; |
|
using Elight.Logic; |
|
using Elight.Utility; |
|
using Elight.Utility.Code; |
|
using Elight.Utility.Extensions; |
|
using java.awt; |
|
using javax.xml.crypto; |
|
using Microsoft.AspNetCore.Authorization; |
|
using Microsoft.AspNetCore.Mvc; |
|
using Newtonsoft.Json; |
|
using SqlSugar; |
|
using System.Data; |
|
using System.Net.WebSockets; |
|
using System.Runtime.Serialization; |
|
using System.Text; |
|
using static com.sun.tools.@internal.xjc.reader.xmlschema.bindinfo.BIConversion; |
|
using User = Elight.Utility.User; |
|
|
|
namespace _24Hour.Controllers.Common |
|
{ |
|
[Authorize] |
|
[ApiController] |
|
public class WebSocketController : Controller |
|
{ |
|
private readonly SqlSugarClient _db;//数据库 |
|
App_Sys_UserModel _userdata = new App_Sys_UserModel();//当前用户 |
|
private readonly ILogger<LoginController> _logger;//日志 |
|
private readonly IConfiguration _configuration; |
|
private static object obj=new object(); |
|
Result result = new Result(); |
|
private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池 |
|
private static Dictionary<string, WebSocketSending> meeting_pool = new Dictionary<string, WebSocketSending>();//会议连接池 |
|
private static Dictionary<string, string> userzx = new Dictionary<string, string>();//检察官在线池 |
|
//private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池 |
|
public WebSocketController(ILogger<LoginController> logger, SqlSugarClient db,User userdata,IConfiguration configuration) |
|
{ |
|
_logger = logger; |
|
_db = db; |
|
_userdata = userdata.Userdata(); |
|
_configuration = configuration; |
|
} |
|
[HttpGet("/ws")] |
|
public async Task WebSocketServer() |
|
{ |
|
if (HttpContext.WebSockets.IsWebSocketRequest) |
|
{ |
|
try |
|
{ |
|
var socket = await HttpContext.WebSockets.AcceptWebSocketAsync(); |
|
await ProcessChat(socket); |
|
} |
|
catch (Exception ex) |
|
{ |
|
} |
|
} |
|
} |
|
private async Task ProcessChat(WebSocket socket) |
|
{ |
|
string user = _userdata.Id; |
|
|
|
try |
|
{ |
|
#region 用户添加连接池 |
|
//第一次open时,添加到连接池中 |
|
if (!CONNECT_POOL.ContainsKey(user)) |
|
CONNECT_POOL.Add(user, socket);//不存在,添加 |
|
else |
|
if (socket != CONNECT_POOL[user])//当前对象不一致,更新 |
|
CONNECT_POOL[user] = socket; |
|
#endregion |
|
|
|
string descUser = string.Empty;//目的用户 |
|
while (true) |
|
{ |
|
if (socket.State == WebSocketState.Open) |
|
{ |
|
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]); |
|
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None); |
|
if (result.MessageType == WebSocketMessageType.Close) |
|
{ |
|
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); |
|
if (meeting_pool.ContainsKey(user)) meeting_pool.Remove(user);//删除会议 |
|
if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除socket |
|
//判断当前检察官是否在线 |
|
if (_userdata.usertype == 0 && userzx.ContainsKey(user)) |
|
{ |
|
userzx.Remove(user);//删除在线用户 |
|
} |
|
socket.Dispose(); |
|
break; |
|
} |
|
else |
|
{ |
|
var data = Encoding.UTF8.GetString(buffer); |
|
Console.WriteLine(data); |
|
} |
|
} |
|
else |
|
{ |
|
Console.WriteLine("断开连接"); |
|
break; |
|
} |
|
}//while end |
|
} |
|
catch (Exception ex) |
|
{ |
|
//整体异常处理 |
|
if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 消息发送 |
|
/// </summary> |
|
/// <param name="Sendingdata"></param> |
|
/// <returns></returns> |
|
[HttpPost] |
|
[Route("WebSocketSend")] |
|
public async Task WebSocketSend(WebSocketSending Sendingdata) |
|
{ |
|
try |
|
{ |
|
//获取发送人连接 |
|
var socket = CONNECT_POOL.Where(q => q.Key == _userdata.Id).Select(q => q.Value).First(); |
|
while (true) |
|
{ |
|
if (socket.State == WebSocketState.Open) |
|
{ |
|
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]); |
|
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None); |
|
|
|
#region 消息处理(消息转发) |
|
try |
|
{ |
|
#region 关闭Socket处理,删除连接池 |
|
if (socket.State != WebSocketState.Open)//连接关闭 |
|
{ |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id);//删除连接池 |
|
break; |
|
} |
|
#endregion |
|
|
|
|
|
#region 消息发送 |
|
var content = JsonConvert.SerializeObject(Sendingdata); |
|
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(content)); |
|
|
|
if (CONNECT_POOL.ContainsKey(Sendingdata.recipient))//判断客户端是否在线 |
|
{ |
|
WebSocket destSocket = CONNECT_POOL[Sendingdata.recipient];//目的客户端 |
|
if (destSocket != null && destSocket.State == WebSocketState.Open) |
|
await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); |
|
else |
|
{ |
|
//添加未读 |
|
} |
|
} |
|
else |
|
{ |
|
//添加未读 |
|
//添加一条未读消息 |
|
//Task.Run(() => |
|
//{ |
|
// if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中 |
|
// MESSAGE_POOL.Add(descUser, new List<MessageInfo>()); |
|
// MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息 |
|
//}); |
|
} |
|
#endregion |
|
} |
|
catch (Exception exs) |
|
{ |
|
//消息转发异常处理,本次消息忽略 继续监听接下来的消息 |
|
} |
|
#endregion |
|
} |
|
else |
|
{ |
|
} |
|
}//while end |
|
} |
|
catch (Exception) |
|
{ |
|
//整体异常处理 |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id); |
|
} |
|
} |
|
|
|
|
|
/// <summary> |
|
/// 消息发送 |
|
/// </summary> |
|
/// <param name="Sendingdata"></param> |
|
/// <returns></returns> |
|
[HttpPost] |
|
[Route("text")] |
|
public async Task<Result> text() |
|
{ |
|
try |
|
{ |
|
//获取发送人连接 |
|
var socket = CONNECT_POOL.Where(q => q.Key == _userdata.Id).Select(q => q.Value).First(); |
|
if (socket.State == WebSocketState.Open) |
|
{ |
|
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]); |
|
//WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None); |
|
|
|
#region 消息处理(消息转发) |
|
try |
|
{ |
|
#region 关闭Socket处理,删除连接池 |
|
if (socket.State != WebSocketState.Open)//连接关闭 |
|
{ |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id);//删除连接池 |
|
result.IsSucceed = true; |
|
result.result = ""; |
|
return result; |
|
} |
|
#endregion |
|
|
|
|
|
#region 消息发送 |
|
var content = "测试test"; |
|
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(content)); |
|
await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); |
|
#endregion |
|
} |
|
catch (Exception exs) |
|
{ |
|
//消息转发异常处理,本次消息忽略 继续监听接下来的消息 |
|
} |
|
#endregion |
|
} |
|
else |
|
{ |
|
} |
|
} |
|
catch (Exception) |
|
{ |
|
//整体异常处理 |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id); |
|
} |
|
result.IsSucceed = true; |
|
result.result = ""; |
|
return result; |
|
} |
|
|
|
|
|
/// <summary> |
|
/// 视频推送 |
|
/// </summary> |
|
/// <param name="Sendingdata"></param> |
|
/// <returns></returns> |
|
[HttpPost] |
|
[Route("Video")] |
|
public async Task<Result> Video(WebSocketSending Senddata) |
|
{ |
|
try |
|
{ |
|
//获取发送人连接 |
|
var socket = CONNECT_POOL.Where(q => q.Key == _userdata.Id).Select(q => q.Value).FirstOrDefault(); |
|
lock (obj) |
|
{ |
|
//判断当前发送人是否是检察官 |
|
if (_userdata.usertype == 0&&!userzx.ContainsKey(_userdata.Id)) |
|
{ |
|
userzx.Add(_userdata.Id, "1"); |
|
} |
|
//判断接收人是否在线, |
|
if (_userdata.usertype == 1 && userzx.ContainsKey(Senddata.recipient)) |
|
{ |
|
result.IsSucceed = false; |
|
result.result = "占线中"; |
|
return result; |
|
} |
|
} |
|
if (socket!=null&&socket.State == WebSocketState.Open) |
|
{ |
|
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]); |
|
//WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None); |
|
|
|
#region 消息处理(消息转发) |
|
try |
|
{ |
|
#region 关闭Socket处理,删除连接池 |
|
if (socket.State != WebSocketState.Open)//连接关闭 |
|
{ |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id);//删除连接池 |
|
if (meeting_pool.ContainsKey(_userdata.Id)) meeting_pool.Remove(_userdata.Id);//删除会议 |
|
//判断当前检察官是否在线 |
|
if (_userdata.usertype == 0 && userzx.ContainsKey(_userdata.Id)) |
|
{ |
|
userzx.Remove(_userdata.Id);//删除在线用户 |
|
} |
|
//result.IsSucceed = true; |
|
//result.result = "未上线"; |
|
//return result; |
|
} |
|
#endregion |
|
|
|
#region 消息发送 |
|
var content = ""; |
|
//data.type等于1 为视频推送 |
|
if (Senddata.typenum == "1" && Senddata.deviceno.NotNull()) |
|
{ |
|
//设备发送给app |
|
Senddata.content = $"{_configuration.GetSection("Videoaddress:rtsp").Value}{Senddata.deviceno}"; |
|
//对象序列化 |
|
content = JsonConvert.SerializeObject(Senddata); |
|
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(content)); |
|
} |
|
else |
|
{ |
|
//app发送给设备 |
|
Senddata.content = $"{_configuration.GetSection("Videoaddress:rtmp").Value}{_userdata.Id}"; |
|
//对象序列化 |
|
content = JsonConvert.SerializeObject(Senddata); |
|
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(content)); |
|
} |
|
//判断客户端是否在线 |
|
if (CONNECT_POOL.ContainsKey(Senddata.recipient)) |
|
{ |
|
//获取目的客户端 |
|
WebSocket destSocket = CONNECT_POOL[Senddata.recipient]; |
|
//判断客户端是否连接 |
|
if (destSocket != null && destSocket.State == WebSocketState.Open) |
|
{ |
|
if (meeting_pool.ContainsKey(Senddata.recipient)) |
|
{ |
|
// |
|
var data = meeting_pool[Senddata.recipient]; |
|
//当前用户消息对象序列化 |
|
var dqcontent = JsonConvert.SerializeObject(data); |
|
var dqbuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(dqcontent)); |
|
//当前用户socket发送 |
|
await socket.SendAsync(dqbuffer, WebSocketMessageType.Text, true, CancellationToken.None); |
|
} |
|
//目的客户端发送 |
|
await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); |
|
} |
|
else |
|
{ |
|
meeting_pool.Add(_userdata.Id, Senddata); |
|
} |
|
} |
|
else |
|
{ |
|
meeting_pool.Add(_userdata.Id, Senddata); |
|
//result.IsSucceed = false; |
|
//result.result = "用户未上线"; |
|
//return result; |
|
} |
|
#endregion |
|
} |
|
catch (Exception exs) |
|
{ |
|
//消息转发异常处理,本次消息忽略 继续监听接下来的消息 |
|
} |
|
#endregion |
|
} |
|
else |
|
{ |
|
//判断当前检察官是否在线 |
|
if (_userdata.usertype == 0 && userzx.ContainsKey(_userdata.Id)) |
|
{ |
|
userzx.Remove(_userdata.Id); |
|
} |
|
} |
|
} |
|
catch (Exception) |
|
{ |
|
//整体异常处理 |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id); |
|
} |
|
result.IsSucceed = true; |
|
result.result = ""; |
|
return result; |
|
} |
|
|
|
|
|
/// <summary> |
|
/// 推出会议 |
|
/// </summary> |
|
/// <param name="Sendingdata"></param> |
|
/// <returns></returns> |
|
[HttpGet] |
|
[Route("close")] |
|
public async Task<Result> close() |
|
{ |
|
if (meeting_pool.ContainsKey(_userdata.Id)) meeting_pool.Remove(_userdata.Id);//删除会议 |
|
result.IsSucceed = true; |
|
result.result = ""; |
|
return result; |
|
} |
|
|
|
/// <summary> |
|
/// 系统消息发送 |
|
/// </summary> |
|
/// <param name="Id"></param> |
|
/// <returns></returns> |
|
[HttpGet] |
|
[Route("system")] |
|
public async Task<bool> system(string Id) |
|
{ |
|
try |
|
{ |
|
//获取发送人连接 |
|
var socket = CONNECT_POOL.Where(q => q.Key == Id).Select(q => q.Value).FirstOrDefault(); |
|
if (socket != null && socket.State == WebSocketState.Open) |
|
{ |
|
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]); |
|
#region 消息处理(消息转发) |
|
try |
|
{ |
|
#region 关闭Socket处理,删除连接池 |
|
if (socket.State != WebSocketState.Open)//连接关闭 |
|
{ |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id);//删除连接池 |
|
return true; |
|
} |
|
#endregion |
|
|
|
#region 消息发送 |
|
var content = "system"; |
|
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(content)); |
|
//当前用户socket发送 |
|
await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); |
|
#endregion |
|
} |
|
catch (Exception exs) |
|
{ |
|
//消息转发异常处理,本次消息忽略 继续监听接下来的消息 |
|
} |
|
#endregion |
|
} |
|
else |
|
{ |
|
} |
|
} |
|
catch (Exception) |
|
{ |
|
//整体异常处理 |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id); |
|
} |
|
return true; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 消息发送 |
|
/// </summary> |
|
public class WebSocketSending |
|
{ |
|
/// <summary> |
|
/// 发送人 |
|
/// </summary> |
|
[DataMember] |
|
public string? sender { get; set; } |
|
|
|
/// <summary> |
|
/// 发送内容 |
|
/// </summary> |
|
[DataMember] |
|
public string? content { get; set; } |
|
/// <summary> |
|
/// 接收人 |
|
/// </summary> |
|
[DataMember] |
|
public string? recipient { get; set; } |
|
/// <summary> |
|
/// 类型 0:消息,1:视频地址 |
|
/// </summary> |
|
[DataMember] |
|
public string? typenum { get; set; } |
|
/// <summary> |
|
/// 设备编号 |
|
/// </summary> |
|
[DataMember] |
|
public string? deviceno { get; set; } |
|
} |
|
}
|
|
|