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.
602 lines
26 KiB
602 lines
26 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, Addressda> meeting_pool = new Dictionary<string, Addressda>();//会议连接池 |
|
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<Result> WebSocketSend(WebSocketSending Sendingdata) |
|
{ |
|
try |
|
{ |
|
//获取发送人连接 |
|
var socket = CONNECT_POOL.Where(q => q.Key == _userdata.Id).Select(q => q.Value).FirstOrDefault(); |
|
if (socket!=null&&socket.State == WebSocketState.Open) |
|
{ |
|
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]); |
|
//WebSocketReceiveResult ret = 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);//删除连接池 |
|
} |
|
#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) |
|
{ |
|
result.IsSucceed = true; |
|
result.result = "已发送"; |
|
|
|
await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); |
|
} |
|
else |
|
{ |
|
result.IsSucceed = false; |
|
result.result = "用户未上线!"; |
|
} |
|
} |
|
else |
|
{ |
|
result.IsSucceed = false; |
|
result.result = "用户未上线!"; |
|
//添加未读 |
|
//添加一条未读消息 |
|
//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) |
|
{ |
|
result.IsSucceed = false; |
|
result.result = "用户未上线!"; |
|
//消息转发异常处理,本次消息忽略 继续监听接下来的消息 |
|
} |
|
#endregion |
|
} |
|
else |
|
{ |
|
result.IsSucceed = false; |
|
result.result = " 重新连接!"; |
|
} |
|
} |
|
catch (Exception ex) |
|
{ |
|
//整体异常处理 |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id); |
|
result.IsSucceed = false; |
|
result.result = "用户未上线!"; |
|
} |
|
return result; |
|
} |
|
|
|
|
|
/// <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)) |
|
//{ |
|
// if (userzx[Senddata.recipient] == "1") |
|
// { |
|
// userzx[Senddata.recipient] = "2"; |
|
// } |
|
// else |
|
// { |
|
// 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(Senddata.meetingnumber)) meeting_pool.Remove(Senddata.meetingnumber);//删除会议 |
|
////判断当前检察官是否在线 |
|
//if (_userdata.usertype == 0 && userzx.ContainsKey(_userdata.Id)) |
|
//{ |
|
// userzx.Remove(_userdata.Id);//删除在线用户 |
|
//} |
|
result.IsSucceed = true; |
|
result.result = ""; |
|
return result; |
|
} |
|
#endregion |
|
|
|
lock (obj) |
|
{ |
|
#region 消息发送 |
|
var content = ""; |
|
//data.type等于1 为视频推送 |
|
if (Senddata.typenum == "1" && Senddata.deviceno.NotNull()) |
|
{ |
|
//设备视频流地址存放 |
|
Addressda Address = new Addressda(); |
|
Address.deviceAddress = Senddata.content; |
|
if (!meeting_pool.ContainsKey(Senddata.meetingnumber)) |
|
meeting_pool.Add(Senddata.meetingnumber, Address);//添加到会议视频推送池 |
|
else |
|
{ |
|
//更新会议室视频流地址 |
|
var da = meeting_pool[Senddata.meetingnumber]; |
|
da.deviceAddress = Senddata.content; |
|
meeting_pool[Senddata.meetingnumber] = da; |
|
} |
|
//设备发送给app |
|
//Senddata.content = $"{_configuration.GetSection("Videoaddress:rtsp").Value}{Senddata.deviceno}"; |
|
//对象序列化 |
|
content = JsonConvert.SerializeObject(Senddata); |
|
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(content)); |
|
} |
|
else |
|
{ |
|
//app视频流地址存放 |
|
Addressda Address = new Addressda(); |
|
Address.appAddress = Senddata.content; |
|
if (!meeting_pool.ContainsKey(Senddata.meetingnumber)) |
|
meeting_pool.Add(Senddata.meetingnumber, Address);//添加到会议视频推送池 |
|
else |
|
{ |
|
//更新会议室视频流地址 |
|
var da = meeting_pool[Senddata.meetingnumber]; |
|
da.appAddress = Senddata.content; |
|
meeting_pool[Senddata.meetingnumber] = da; |
|
} |
|
//app发送给设备 |
|
Senddata.content = $"{_configuration.GetSection("Videoaddress:rtmp").Value}{Senddata.meetingnumber}"; |
|
//对象序列化 |
|
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.meetingnumber)) |
|
{ |
|
var bol = true; |
|
var socketSendstr = JsonConvert.SerializeObject(Senddata); |
|
var socketSend = JsonConvert.DeserializeObject<WebSocketSending>(socketSendstr); |
|
//获取接收人会议池消息 |
|
var data = meeting_pool[Senddata.meetingnumber]; |
|
if (Senddata.typenum == "1" && Senddata.deviceno.NotNull()) |
|
socketSend.content = data.appAddress; |
|
else |
|
socketSend.content = data.deviceAddress; |
|
if (!socketSend.content.NotNull()) bol = false; |
|
//对象序列化 |
|
var dqcontent = JsonConvert.SerializeObject(socketSend); |
|
var dqbuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(dqcontent)); |
|
//当前用户socket发送 |
|
if (bol) |
|
socket.SendAsync(dqbuffer, WebSocketMessageType.Text, true, CancellationToken.None); |
|
} |
|
//目的客户端发送 |
|
destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); |
|
} |
|
else |
|
{ |
|
Addressda Address = new Addressda(); |
|
if (!meeting_pool.ContainsKey(Senddata.meetingnumber)) |
|
{ |
|
if (Senddata.typenum == "1" && Senddata.deviceno.NotNull()) |
|
Address.deviceAddress = Senddata.content;//设备视频流地址存放 |
|
else |
|
Address.appAddress = Senddata.content;//app视频流地址存放 |
|
|
|
meeting_pool.Add(Senddata.meetingnumber, Address);//添加到会议视频推送池 |
|
} |
|
else |
|
{ |
|
if (Senddata.typenum == "1" && Senddata.deviceno.NotNull()) |
|
{ |
|
//更新会议室视频流地址 |
|
var da = meeting_pool[Senddata.meetingnumber]; |
|
da.deviceAddress = Senddata.content;//设备视频流地址存放 |
|
meeting_pool[Senddata.meetingnumber] = da; |
|
} |
|
else |
|
{ |
|
//更新会议室视频流地址 |
|
var da = meeting_pool[Senddata.meetingnumber]; |
|
da.appAddress = Senddata.content;//app视频流地址存放 |
|
meeting_pool[Senddata.meetingnumber] = da; |
|
} |
|
|
|
} |
|
} |
|
} |
|
else |
|
{ |
|
Addressda Address = new Addressda(); |
|
if (!meeting_pool.ContainsKey(Senddata.meetingnumber)) |
|
{ |
|
if (Senddata.typenum == "1" && Senddata.deviceno.NotNull()) |
|
Address.deviceAddress = Senddata.content;//设备视频流地址存放 |
|
else |
|
Address.appAddress = Senddata.content;//app视频流地址存放 |
|
|
|
meeting_pool.Add(Senddata.meetingnumber, Address);//添加到会议视频推送池 |
|
} |
|
else |
|
{ |
|
if (Senddata.typenum == "1" && Senddata.deviceno.NotNull()) |
|
{ |
|
//更新会议室视频流地址 |
|
var da = meeting_pool[Senddata.meetingnumber]; |
|
da.deviceAddress = Senddata.content;//设备视频流地址存放 |
|
meeting_pool[Senddata.meetingnumber] = da; |
|
} |
|
else |
|
{ |
|
//更新会议室视频流地址 |
|
var da = meeting_pool[Senddata.meetingnumber]; |
|
da.appAddress = Senddata.content;//app视频流地址存放 |
|
meeting_pool[Senddata.meetingnumber] = da; |
|
} |
|
|
|
} |
|
} |
|
#endregion |
|
} |
|
} |
|
catch (Exception exs) |
|
{ |
|
//消息转发异常处理,本次消息忽略 继续监听接下来的消息 |
|
} |
|
#endregion |
|
} |
|
else |
|
{ |
|
//判断当前检察官是否在线 |
|
//if (_userdata.usertype == 0 && userzx.ContainsKey(_userdata.Id)) |
|
//{ |
|
// userzx.Remove(_userdata.Id); |
|
//} |
|
} |
|
} |
|
catch (Exception ex) |
|
{ |
|
//整体异常处理 |
|
if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id); |
|
//整体异常处理 |
|
if (meeting_pool.ContainsKey(Senddata.meetingnumber)) meeting_pool.Remove(Senddata.meetingnumber); |
|
|
|
} |
|
result.IsSucceed = true; |
|
result.result = ""; |
|
return result; |
|
} |
|
|
|
|
|
/// <summary> |
|
/// 退出会议 |
|
/// </summary> |
|
/// <param name="Sendingdata"></param> |
|
/// <returns></returns> |
|
[HttpGet] |
|
[Route("close")] |
|
public async Task<Result> close(string meetingnumber) |
|
{ |
|
if (meeting_pool.ContainsKey(meetingnumber)) meeting_pool.Remove(meetingnumber);//删除会议 |
|
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 消息发送 |
|
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) |
|
{ |
|
} |
|
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; } |
|
/// <summary> |
|
/// 会议编号 |
|
/// </summary> |
|
[DataMember] |
|
public string? meetingnumber { get; set; } |
|
} |
|
|
|
|
|
/// <summary> |
|
/// 视频流地址 |
|
/// </summary> |
|
public class Addressda |
|
{ |
|
/// <summary> |
|
/// app地址 |
|
/// </summary> |
|
public string? appAddress { get; set; } |
|
|
|
/// <summary> |
|
/// 设备地址 |
|
/// </summary> |
|
public string? deviceAddress { get; set; } |
|
} |
|
}
|
|
|