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 _logger;//日志 private readonly IConfiguration _configuration; private static object obj = new object(); Result result = new Result(); private static Dictionary CONNECT_POOL = new Dictionary();//用户连接池 private static Dictionary meeting_pool = new Dictionary();//会议连接池 private static Dictionary userzx = new Dictionary();//检察官在线池 //private static Dictionary> MESSAGE_POOL = new Dictionary>();//离线消息池 public WebSocketController(ILogger 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 buffer = new ArraySegment(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); } } /// /// 消息发送 /// /// /// [HttpPost] [Route("WebSocketSend")] public async Task 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 buffer = new ArraySegment(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(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()); // 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; } /// /// 消息发送 /// /// /// [HttpPost] [Route("text")] public async Task text() { try { //获取发送人连接 var socket = CONNECT_POOL.Where(q => q.Key == _userdata.Id).Select(q => q.Value).First(); if (socket.State == WebSocketState.Open) { ArraySegment buffer = new ArraySegment(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(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; } /// /// 视频推送 /// /// /// [HttpPost] [Route("Video")] public async Task 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 buffer = new ArraySegment(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(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(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(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(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; } /// /// 退出会议 /// /// /// [HttpGet] [Route("close")] public async Task close(string meetingnumber) { if (meeting_pool.ContainsKey(meetingnumber)) meeting_pool.Remove(meetingnumber);//删除会议 result.IsSucceed = true; result.result = ""; return result; } /// /// 系统消息发送 /// /// /// [HttpGet] [Route("system")] public async Task 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 buffer = new ArraySegment(new byte[2048]); #region 消息处理(消息转发) try { #region 消息发送 var content = "system"; buffer = new ArraySegment(Encoding.UTF8.GetBytes(content)); //当前用户socket发送 await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); #endregion } catch (Exception exs) { //消息转发异常处理,本次消息忽略 继续监听接下来的消息 } #endregion } else { } } catch (Exception) { } return true; } } /// /// 消息发送 /// public class WebSocketSending { /// /// 发送人 /// [DataMember] public string? sender { get; set; } /// /// 发送内容 /// [DataMember] public string? content { get; set; } /// /// 接收人 /// [DataMember] public string? recipient { get; set; } /// /// 类型 0:消息,1:视频地址 /// [DataMember] public string? typenum { get; set; } /// /// 设备编号 /// [DataMember] public string? deviceno { get; set; } /// /// 会议编号 /// [DataMember] public string? meetingnumber { get; set; } } /// /// 视频流地址 /// public class Addressda { /// /// app地址 /// public string? appAddress { get; set; } /// /// 设备地址 /// public string? deviceAddress { get; set; } } }