Files
wb_InteractiveClassroomMett…/‌WebSocketServer.cs

675 lines
25 KiB
C#
Raw Permalink Normal View History

2025-12-11 10:06:20 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using System.Xml;
using Fleck;
using Microsoft.VisualBasic.ApplicationServices;
using Newtonsoft.Json;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
public class WebSocketServer
{
//用户信息
public static List<ClassUserInfo> IWebSocketUserinfo = new List<ClassUserInfo>();
//socket信息
public static List<IWebSocketConnection> _clients = new List<IWebSocketConnection>();
//课程信息
public static List<ClassInfo> _classInfos = new List<ClassInfo>();
public Fleck.WebSocketServer _server;
public async void Start(string location)
{
var certPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fullchain.pfx");
if (!File.Exists(certPath))
{
MessageBox.Show("证书文件未找到!");
return;
}
var certificate = new X509Certificate2(certPath, "");
var _server = new Fleck.WebSocketServer(location)
{
Certificate = certificate,
EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12,
RestartAfterListenError = true
};
_server.Start(async socket =>
{
socket.OnOpen = () =>
{
try
{
Result r = new Result();
ClassUserInfo u = new ClassUserInfo();
var query = HttpUtility.ParseQueryString(socket.ConnectionInfo.Path);
u.UserName = HttpUtility.UrlDecode(query["UserName"]);
u.Class = Convert.ToInt64(query["Class"]);
u.Schoolclass = Convert.ToInt32(query["SchoolClass"]);
u.UserID = Convert.ToInt64(query["UserID"]);
u.UserType = Convert.ToInt32(query["UserType"]);//0学生 1老师 2教室
u.GUID = socket.ConnectionInfo.Id;
string token = query["Token"];
u.Linsocket = socket;
if (token != "123456")
{
r.IsSuccess = false;
r.Data = "Faile TokenNo";
r.MessageType = 0;
socket.Send(JsonConvert.SerializeObject(r));
return;
}
else
{
r.IsSuccess = true;
r.Data = "ok";
r.MessageType = 0;
socket.Send(JsonConvert.SerializeObject(r));
IWebSocketUserinfo.Add(u);
_clients.Add(socket);
//查询课程是否存在
bool exists = _classInfos.Any(c => c.CourseID == u.Class);
if (exists)
{
ClassInfo foundClass = _classInfos.FirstOrDefault(c => c.CourseID == u.Class);
if (u.UserType == 1 && u.UserID != 999998)
{
foundClass.CourseName = u.UserName;
foundClass.DisplayID = u.UserID;
foundClass.CourseStatus = 1;
foundClass.TeacherID = u.UserID;
foundClass.TeacherAudioIsOpen = true;
2025-12-11 10:06:38 +08:00
2025-12-11 10:06:20 +08:00
}
else if (u.UserID == 999998)
{
foundClass.DisplayID = foundClass.TeacherID;
}
//找到音频控制文件是否存在
if (!foundClass.userAudioStatus.Any(c => c.UserID == u.UserID))
{
//新加入用户默认静音
UserAudioStatus ux = new UserAudioStatus();
ux.UserID = u.UserID;
//需要判定默认是否是全屏静音状态
ux.IsOpen = foundClass.AudioIsOpen;
ux.UserType = u.UserType;
if (ux.UserType == 1)
{
ux.IsOpen = true;
}
foundClass.userAudioStatus.Add(ux);
}
else
{
UserAudioStatus ux = foundClass.userAudioStatus.FirstOrDefault(c => c.UserID == u.UserID);
ux.IsOpen = false;
}
}
else
{
//如果课程不存在则创建一个新的课程 并加入这个用户ID
ClassInfo c = new ClassInfo();
c.CourseID = u.Class;
c.CourseStatus = 0;
//c.AudioIsOpen = true;
c.AudioIsOpen = true;
c.TeacherAudioIsOpen = true;
if (u.UserType == 1 && u.UserID != 999998)
{
c.CourseName = u.UserName;
c.DisplayID = u.UserID;
c.CourseStatus =1;
c.TeacherID = u.UserID;
}
UserAudioStatus ux = new UserAudioStatus();
ux.UserID = u.UserID;
ux.IsOpen = true;
ux.UserType = u.UserType;
if (ux.UserType == 1)
{
ux.IsOpen = true;
}
c.userAudioStatus = new List<UserAudioStatus>();
c.userAudioStatus.Add(ux);
_classInfos.Add(c);
}
//如果有新用户加入 则需要通知所有客户端 更新用户列表
List<ClassUserInfo >lt = IWebSocketUserinfo.Where(c => c.Class == u.Class && c.UserType != 1 && u.UserID != 999999999).ToList();
var result = IWebSocketUserinfo.Where(c => c.Class == u.Class );
foreach (var c in result)
{
r = new Result();
r.MessageType = 100;
r.IsSuccess = true;
r.Data = JsonConvert.SerializeObject(lt);
c.Linsocket.Send(JsonConvert.SerializeObject(r));
}
}
}
catch { }
};
socket.OnClose = () =>
{
var query = HttpUtility.ParseQueryString(socket.ConnectionInfo.Path);
long UserID = Convert.ToInt64(query["UserID"]);
RemoveUserAudioStatus(_classInfos, UserID);
IWebSocketUserinfo.RemoveAll(P => P.GUID == socket.ConnectionInfo.Id);
_clients.Remove(socket);
//这里需要移除监控用户
};
socket.OnMessage = message =>
{
try
{
var user = IWebSocketUserinfo.First(p => p.GUID == socket.ConnectionInfo.Id);
OperaterSocketData(message, IWebSocketUserinfo, socket, user);
}
catch {
}
};
});
}
public static void RemoveUserAudioStatus(List<ClassInfo> classInfoX, long userId)
{
foreach (ClassInfo classInfo in classInfoX)
{
if (classInfo?.userAudioStatus != null)
{
classInfo.userAudioStatus.RemoveAll(u => u.UserID == userId);
}
}
}
//消息处理
public async void OperaterSocketData(string message, List<ClassUserInfo> ListUser, IWebSocketConnection socket, ClassUserInfo user)
{
try
{
ReciveSocketInfo recive = JsonConvert.DeserializeObject<ReciveSocketInfo>(message);
long Lclass=Convert.ToInt64(recive.Class);
//用户自己关闭声音
if (recive.Data == "StudentCloseAudio")
{
ClassInfo cl = _classInfos.First(c => c.CourseID == Lclass);
// 将所有IsOpen设置为true
foreach (var u in cl.userAudioStatus)
{
if (u.UserID ==user.UserID)
{
u.IsOpen = false;
}
}
return;
}
if (recive.Data == "StudentOpenAudio")
{
ClassInfo cl = _classInfos.First(c => c.CourseID == Lclass);
if (cl.AudioIsOpen == false)
{
Result r = new Result();
r.MessageType = 201;
r.IsSuccess = true;
r.Data = "TeacherCloseAudio";
socket.Send(JsonConvert.SerializeObject(r));
return;
}
else
{
// 将所有IsOpen设置为true
foreach (var u in cl.userAudioStatus)
{
if (u.UserID == user.UserID)
{
u.IsOpen = true;
}
}
}
}
if (recive.Data == "GetCourseUserInfo")
{
Result r = new Result();
r.MessageType = 902;
r.IsSuccess = true;
r.Data = JsonConvert.SerializeObject(IWebSocketUserinfo.Where(c => c.Class == Convert.ToInt64(recive.Class) && c.UserType != 3));
socket.Send(JsonConvert.SerializeObject(r));
return;
}
if (recive.Data == "GetCourseUserInfo")
{
Result r = new Result();
r.MessageType = 902;
r.IsSuccess = true;
r.Data = JsonConvert.SerializeObject(IWebSocketUserinfo.Where(c => c.Class == Convert.ToInt64(recive.Class) && c.UserType != 3));
socket.Send(JsonConvert.SerializeObject(r));
return;
}
if (recive.Data == "MasterScreenOpen")
{
if (IWebSocketUserinfo.Any(c => c.Class == Lclass && c.UserType == 1 && c.UserID != 999998))
{
_classInfos.First(c => c.CourseID == Lclass).CourseName = IWebSocketUserinfo.First(c => c.Class == Lclass && c.UserType == 1 && c.UserID != 999998).UserName;
_classInfos.First(c => c.CourseID == Lclass).DisplayID = IWebSocketUserinfo.First(c => c.Class == Lclass && c.UserType == 1 && c.UserID != 999998).UserID;
}
else {
_classInfos.First(c => c.CourseID == Lclass).DisplayID = 0;
Result r = new Result();
r.MessageType = 905;
r.IsSuccess = true;
r.Data ="SettingMasterScreenFalse";
socket.Send(JsonConvert.SerializeObject(r));
}
}
//如果是取信息 获取用户信息
if (recive.Data == "GetUserInfo")
{
Result r = new Result();
r.MessageType = 102;
r.IsSuccess = true;
r.Data = JsonConvert.SerializeObject(IWebSocketUserinfo.Where(c => c.Class == Convert.ToInt64(recive.Class) && c.UserType != 1));
socket.Send(JsonConvert.SerializeObject(r));
return;
}
//获取课程信息
if (recive.Data == "GetCourseInfo")
{
Result r = new Result();
r.MessageType = 101;
r.IsSuccess = true;
r.Data = JsonConvert.SerializeObject(_classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class)));
socket.Send(JsonConvert.SerializeObject(r));
return;
}
//全部开启声音 --继续走流程
if (recive.Data == "AllAudioOpen")
{
ClassInfo cl = _classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class));
cl.AudioIsOpen = true;
// 将所有IsOpen设置为true
foreach (var u in cl.userAudioStatus)
{
if (u.UserID != 999998)
{
u.IsOpen = true;
}
}
}
//全部关闭声音 --继续走流程
if (recive.Data == "AllAudioClose")
{
ClassInfo cl = _classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class));
cl.AudioIsOpen = false;
// 将所有IsOpen设置为true
foreach (var u in cl.userAudioStatus)
{
if (u.UserID != 999998)
{
u.IsOpen = false;
}
}
}
// 全部开启声音--继续走流程
if (recive.Data == "AudioOpen")
{
ClassInfo cl = _classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class));
foreach (var u in cl.userAudioStatus)
{
if (u.UserID != 999998 & u.UserID == recive.UserID)
{
u.IsOpen = true;
}
}
cl.AudioIsOpen = true;
}
//全部关闭声音 --继续走流程
if (recive.Data == "AudioClose")
{
ClassInfo cl = _classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class));
foreach (var u in cl.userAudioStatus)
{
if (u.UserID != 999998 & u.UserID == recive.UserID)
{
u.IsOpen = false;
}
}
}
//开始上课
if (recive.Data == "StartClass")
{
ClassInfo cl = _classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class));
cl.CourseStatus = 1;
cl.AudioIsOpen = true;
try
{
cl.CourseName = IWebSocketUserinfo.First(c => c.UserType == 1 && c.UserID != 999998).UserName;//课程附上教师名字
//cl.DisplayID = IWebSocketUserinfo.First(c => c.UserType == 1 && c.UserID != 999998&&c.UserID==).UserID;//得到用户视频音频ID
cl.DisplayID = user.UserID;//得到用户视频音频ID
}
catch { }
Result r = new Result();
r.MessageType = 103;
r.IsSuccess = true;
if (!IWebSocketUserinfo.Any(c => c.UserType == 1 && c.UserID != 999998 && c.Class == Convert.ToInt64(recive.Class)))
{
r.Data = "NoTeacher";
cl.CourseStatus = 0;
socket.Send(JsonConvert.SerializeObject(r));
}
else
{
}
}
//结束上课
if (recive.Data == "EndClass")
{
ClassInfo cl = _classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class));
cl.DisplayID = 0;
cl.CourseStatus = 0;
cl.AudioIsOpen = false;
}
//开启监控某一个画面
if (recive.Data.IndexOf("StudentJK_")>-1)
{
string[] dataList = recive.Data.Replace("StudentJK_", "").Split('_');
long jkID = Convert.ToInt64(dataList[0]);
long classID = Convert.ToInt64(dataList[1]);
string userName = IWebSocketUserinfo.First(C => C.UserID == jkID).UserName;
DisplayJK dsJK = new DisplayJK();
dsJK.UserID = jkID;
dsJK.Name = userName;
var ClassInfoT= _classInfos.First(C => C.CourseID == classID);
if (ClassInfoT.DisplayJK == null)
{
ClassInfoT.DisplayJK = new List<DisplayJK>();
ClassInfoT.DisplayJK.Add(dsJK);
}
else
{
if (!ClassInfoT.DisplayJK.Any(c => c.UserID == jkID))
{
ClassInfoT.DisplayJK.Add(dsJK);
}
}
}
//取消某一个监控画面
if (recive.Data.IndexOf("QXJK_") > -1)
{
string[] dataList = recive.Data.Replace("QXJK_", "").Split('_');
long jkID = Convert.ToInt64(dataList[0]);
long classID = Convert.ToInt64(dataList[1]);
string userName = IWebSocketUserinfo.First(C => C.UserID == jkID).UserName;
DisplayJK dsJK = new DisplayJK();
dsJK.UserID = jkID;
dsJK.Name = userName;
var ClassInfoT = _classInfos.First(C => C.CourseID == classID);
var target = ClassInfoT.DisplayJK.FirstOrDefault(c => c.UserID == jkID);
if (target != null)
{
ClassInfoT.DisplayJK.Remove(target);
}
}
if (recive.Data.IndexOf("ScreenSharing_") > -1)
{
if (IWebSocketUserinfo.Any(c => c.Class == Lclass && c.UserType == 1 && c.UserID != 999998))
{
string[] dataList = recive.Data.Replace("ScreenSharing_", "").Split('_');
long UserID = Convert.ToInt64(dataList[1].Trim());
long CourseID = Lclass;
_classInfos.First(c => c.CourseID == CourseID).DisplayID = UserID;
}
else
{
_classInfos.First(c => c.CourseID == Lclass).DisplayID = 0;
Result r = new Result();
r.MessageType = 906;
r.IsSuccess = true;
r.Data = "SettingMasterScreenFalse";
socket.Send(JsonConvert.SerializeObject(r));
return;
}
}
//设置为主屏幕
if (recive.Data.IndexOf("StudentMasterScreen_") > -1)
{
string[] dataList = recive.Data.Replace("StudentMasterScreen_", "").Split(',');
long UserID = Convert.ToInt64(dataList[0]);
long ClassID = Convert.ToInt64(dataList[1]);
////清空所有监控
//var ClassInfoT = _classInfos.First(C => C.CourseID == ClassID);
//ClassInfoT.DisplayJK.Clear();
DisplayJK dsJK = new DisplayJK();
dsJK.UserID = UserID;
string userName = IWebSocketUserinfo.First(C => C.UserID == UserID).UserName;
dsJK.Name = userName;
//if (ClassInfoT.DisplayJK == null || ClassInfoT.DisplayJK.Count == 0)
//{
// ClassInfoT.DisplayJK = new List<DisplayJK>();
// ClassInfoT.DisplayJK.Add(dsJK);
//}
//_classInfos.First(c => c.CourseID == ClassID).DisplayJK = ClassInfoT.DisplayJK;
_classInfos.First(c => c.CourseID == ClassID).CourseName = userName;
_classInfos.First(c => c.CourseID == ClassID).DisplayID = UserID;
}
//检查教师是否存在
if (recive.Data.IndexOf("CheckTeacherIsOnline") > -1)
{
if (IWebSocketUserinfo.Any(c => c.Class == Lclass && c.UserType == 1 && c.UserID != 999998))
{
Result r = new Result();
r.MessageType = 907;
r.IsSuccess = true;
r.Data = "";
socket.Send(JsonConvert.SerializeObject(r));
return;
}
else {
Result r = new Result();
r.MessageType = 908;
r.IsSuccess = true;
r.Data = "";
socket.Send(JsonConvert.SerializeObject(r));
return;
}
}
//踢出用户
if (recive.Data == "KickOut")
{
string x = "000";
}
//关闭教师声音
if (recive.Data == "CloseTeacherAudio")
{
_classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class)).TeacherAudioIsOpen=false;
}
//开启教师声音
if (recive.Data == "OpenTeacherAudio")
{
_classInfos.First(c => c.CourseID == Convert.ToInt64(recive.Class)).TeacherAudioIsOpen = true;
}
// 群发
if (recive.Type == 1)
{
SendDataOtherUser(recive, ListUser, user);
}
//单发
if (recive.Type == 0)
{
SendDataUserToUser(recive, ListUser, user);
}
}
catch {
}
}
//如果是发单人
public async void SendDataOtherUser(ReciveSocketInfo recive, List<ClassUserInfo> ListUser, ClassUserInfo user)
{
string userIDList = recive.UserIDS;
if (!string.IsNullOrEmpty(userIDList))
{
string[] userids = userIDList.Trim().Split(',');
foreach (ClassUserInfo c in ListUser)
{
foreach (string userID in userids)
{
if (c.UserID == Convert.ToInt64(userID)&&c.UserType == recive.UserType)
{
c.Linsocket.Send(recive.Data);
}
}
}
}
string rclass = recive.Class;
if (!string.IsNullOrEmpty(rclass))
{
string[] rclasslist = rclass.Trim().Split(',');
foreach (ClassUserInfo c in ListUser)
{
foreach (string r in rclasslist)
{
if (c.Class == Convert.ToInt64(r) && c.UserType == recive.UserType)
{
c.Linsocket.Send(recive.Data);
}
}
}
}
string rschoolclass = recive.SchoolClass;
if (!string.IsNullOrEmpty(rschoolclass))
{
string[] rschoolclasslist = rschoolclass.Trim().Split(',');
foreach (ClassUserInfo c in ListUser)
{
foreach (string r in rschoolclasslist)
{
if (c.Schoolclass == Convert.ToInt64(r) && c.UserType == recive.UserType)
{
c.Linsocket.Send(recive.Data);
}
}
}
}
}
private async void SendDataUserToUser(ReciveSocketInfo recive, List<ClassUserInfo> ListUser, ClassUserInfo user)
{
foreach (ClassUserInfo c in ListUser)
{
if (c.UserID == recive.UserID && c.UserType == recive.UserType)
{
c.Linsocket.Send(recive.Data);
}
}
}
private void CloseWindow(ReciveSocketInfo recive, List<ClassUserInfo> ListUser, ClassUserInfo user) {
string[] listClass = recive.Class.Trim(',').Split(',');
ReciveSocketInfo rsi = new ReciveSocketInfo();
Result r = new Result();
r.IsSuccess = true;
r.MessageType = 1;
r.Data = "CloseWindow";
//处理业务逻辑
foreach (string cl in listClass)
{
//给符合条件的机器发消息
List<ClassUserInfo> result = ListUser.Where(item => item.Class == Convert.ToInt32(cl)).ToList();
foreach (ClassUserInfo c in result)
{
if (c != user)
{
try
{
c.Linsocket.Send(JsonConvert.SerializeObject(r));
}
catch
{
ListUser.Remove(c);
}
}
}
}
}
public void Stop()
{
foreach (var client in _clients.ToList())
{
client.Close();
}
_clients.Clear();
// Console.WriteLine("WebSocket 服务器已停止");
}
}