using Elight.Entity; using Elight.Logic; using Elight.Utility; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using SqlSugar; using System.Net.WebSockets; using System.Text; namespace _24Hour.Controllers.Common { [Authorize] public class WebSocketController : Controller { private readonly SqlSugarClient _db;//数据库 App_Sys_UserModel _userdata = new App_Sys_UserModel();//当前用户 private readonly ILogger _logger;//日志 private static Dictionary CONNECT_POOL = new Dictionary();//用户连接池 //private static Dictionary> MESSAGE_POOL = new Dictionary>();//离线消息池 public WebSocketController(ILogger logger, SqlSugarClient db, User user) { _logger = logger; _db = db; _userdata = user.Userdata(); } [HttpGet("/ws")] public async Task WebSocketServer() { if (HttpContext.WebSockets.IsWebSocketRequest) { try { var socket = await HttpContext.WebSockets.AcceptWebSocketAsync(); 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) { } else { 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).First(); while (true) { 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);//删除连接池 break; } #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) await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); else { //添加未读 } } else { //添加未读 //添加一条未读消息 //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) { //消息转发异常处理,本次消息忽略 继续监听接下来的消息 } #endregion } else { } }//while end } catch (Exception) { //整体异常处理 if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id); } } /// /// 消息发送 /// /// /// [HttpPost] [Route("text")] public async Task text(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 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);//删除连接池 break; } #endregion #region 消息发送 var content = JsonConvert.SerializeObject(Sendingdata); buffer = new ArraySegment(Encoding.UTF8.GetBytes(content)); await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); #endregion } catch (Exception exs) { //消息转发异常处理,本次消息忽略 继续监听接下来的消息 } #endregion } else { } }//while end } catch (Exception) { //整体异常处理 if (CONNECT_POOL.ContainsKey(_userdata.Id)) CONNECT_POOL.Remove(_userdata.Id); } } } /// /// 消息发送 /// public class WebSocketSending { /// /// 发送人 /// public string? sender { get; set; } /// /// 发送内容 /// public string? content { get; set; } /// /// 接收人 /// public string? recipient { get; set; } /// /// 类型 0:消息,1:视频地址 /// public string? type { get; set; } } }