24小时一体机服务
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

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; }
}
}