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 IWebSocketUserinfo = new List(); //socket信息 public static List _clients = new List(); //课程信息 public static List _classInfos = new List(); 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; } 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(); c.userAudioStatus.Add(ux); _classInfos.Add(c); } //如果有新用户加入 则需要通知所有客户端 更新用户列表 Listlt = 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 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 ListUser, IWebSocketConnection socket, ClassUserInfo user) { try { ReciveSocketInfo recive = JsonConvert.DeserializeObject(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(); 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(); // 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 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 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 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 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 服务器已停止"); } }