C#版Websocket服务端实例
Socket服务类代码
1 public class SocketSendHelper 2 { 4 //实例 5 private static SocketSendHelper _ins; 6 public static SocketSendHelper Ins => _ins ?? (_ins = new SocketSendHelper()); 7 /// <summary> 8 /// 边界锁 9 /// </summary> 10 private static object SocketsLockFlag = new object(); 11 /// <summary> 12 /// 所有Socket连接 13 /// </summary> 14 List<WebSocketModel> Sockets = new List<WebSocketModel>(); 15 /// <summary> 16 /// 启动Socket发送信息服务 17 /// </summary> 18 public void StartSocketSend() 19 { 20 //获取配置 21 var sendSocketLink= GetSocketSendLink(); 22 //初始化服务 23 var server = new WebSocketServer(sendSocketLink); 24 //配置日志级别 25 FleckLog.Level = LogLevel.Error; 26 //建立连接 27 server.Start(socket => 28 { 29 socket.OnOpen = () => 30 { 31 32 lock (SocketsLockFlag) 33 { 34 Console.WriteLine("OnOpen访客 :{0} 请求打开", socket.ConnectionInfo.ClientPort); 35 //将每个建立Socket连接的实例添加到WebSocketModel容器内。 36 //如果出现异常断电等特殊情况,WebSocketModel内的socket实例可能会出现重复 37 Sockets.Add(new WebSocketModel() 38 { 39 Socket = socket 40 }); 41 } 42 }; 43 44 socket.OnClose = () => 45 { 46 lock (SocketsLockFlag) 47 { 48 //查询当前Socket 49 var webSocketModel = Sockets.FirstOrDefault(v => v.Socket == socket); 50 if (webSocketModel == null) 51 return; 52 //#region 业务代码,将要关闭的Socket客户端(这里是用户信息也可以是其他信息)信息返回给客户端,便于客户端移除当前socket 53 ////webSocketModel内socket实例为启动Socket的OnOpen委托添加,userInfo为接收信息时的OnMessage委托添加 54 //var json = JsonConvert.SerializeObject(webSocketModel.userInfo); 55 ////将关闭的socket用户信息发回客户端 56 //socket.Send(json); 57 ////从webSocketModel内移除当前socket的所有实例,正常只有一个,兼容处理 58 //foreach (var item in Sockets) 59 //{ 60 // if (item.Socket == socket) 61 // Sockets.Remove(item); 62 //} 63 //#endregion 64 //发送关闭socket的用户信息给客户端 65 SendCloseOrErrorSocketUserInfoToClient(webSocketModel); 66 //从Sockets移除当前socket所有实例 67 Sockets.Remove(webSocketModel); 68 69 //当连接出现意外中断或中断时 70 Console.WriteLine("OnClose访客 :{0} 请求断开,访客信息:{1}", socket.ConnectionInfo.ClientPort, JsonConvert.SerializeObject(webSocketModel.userInfo)); 71 72 } 73 }; 74 75 socket.OnError = (ex) => 76 { 77 Console.WriteLine("Socket连接出现错误:{0},网络可能正在切换中!", ex.Message); 78 lock (SocketsLockFlag) 79 { 80 var webSocketModel = Sockets.FirstOrDefault(v => v.Socket == socket); 81 if (webSocketModel == null) 82 return; 83 //发送报错socket的用户信息给客户端 84 SendCloseOrErrorSocketUserInfoToClient(webSocketModel); 85 //从Sockets移除当前socket所有实例 86 Sockets.Remove(webSocketModel); 87 88 //当连接出现意外中断或中断时 89 Console.WriteLine("OnClose访客 :{0} 请求断开,访客信息:{1}", socket.ConnectionInfo.ClientPort,JsonConvert.SerializeObject(webSocketModel.userInfo)); 90 91 } 92 }; 93 94 socket.OnMessage = message => 95 { 96 ForwardStuentToBigScreen(message, socket); 97 }; 98 }); 99 } 100 /// <summary> 101 /// 获取Socket发送连接 102 /// </summary> 103 /// <returns></returns> 104 public string GetSocketSendLink() 105 { 106 ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); 107 configurationBuilder.AddJsonFile("config.json", optional: false, reloadOnChange: false); 108 IConfigurationRoot config = configurationBuilder.Build(); 109 var sendSocketLink = config.GetSection("Socket:SendSocketLink").Value; 110 Console.WriteLine($"socket地址:{sendSocketLink}"); 111 return sendSocketLink; 112 } 113 /// <summary> 114 /// 发送关闭socket或报错socket的用户信息给客户端 115 /// </summary> 116 /// <param name="webSocketModel"></param> 117 public void SendCloseOrErrorSocketUserInfoToClient(WebSocketModel webSocketModel) 118 { 119 #region 业务代码,将要关闭的Socket客户端(这里是用户信息也可以是其他信息)信息返回给客户端,便于客户端移除当前socket 120 //webSocketModel内socket实例为启动Socket的OnOpen委托添加,userInfo为接收信息时的OnMessage委托添加 121 var json = JsonConvert.SerializeObject(webSocketModel.userInfo); 122 //将关闭的socket用户信息发回客户端 123 webSocketModel.Socket.Send(json); 124 125 #endregion 126 } 127 ///// <summary> 128 ///// 从Sockets移除当前socket所有实例 129 ///// </summary> 130 //public void RemoveCurSocketFromWebSocketModel(WebSocketModel webSocketModel) 131 //{ 132 // //从webSocketModel内移除当前socket的所有实例,正常只有一个,兼容处理 133 // List<WebSocketModel> socketsDeepCopy = new List<WebSocketModel>(Sockets.ToArray()); 134 // foreach (var item in socketsDeepCopy) 135 // { 136 // if (item.Socket == webSocketModel.Socket) 137 // Sockets.Remove(item); 138 // } 139 //} 140 /// <summary> 141 /// 转发学生端信息到大屏 142 /// </summary> 143 /// <param name="message"></param> 144 /// <param name="socket"></param> 145 public void ForwardStuentToBigScreen(string message, IWebSocketConnection socket) 146 { 147 WebSocketModel webSocketModel = null; 148 149 lock (SocketsLockFlag) 150 { 151 webSocketModel = Sockets.FirstOrDefault(v => v.Socket == socket); 152 153 if (webSocketModel == null) 154 return; 155 #region 保存客户端发送的用户信息 156 var dynamicData = JsonConvert.DeserializeObject<dynamic>(message); 157 if (dynamicData == null) 158 { 159 Console.WriteLine("请求Message:{0}格式错误", message); 160 return; 161 } 162 webSocketModel.userInfo.ClientId = dynamicData.ClientId; 163 webSocketModel.userInfo.UserId = dynamicData.UserId; 164 webSocketModel.userInfo.ProtocolType = dynamicData.ProtocolType; 165 #endregion 166 //如果客户端为学生端,将信息转发大屏 167 if (webSocketModel.userInfo.ClientId != "BigScreenClient") 168 { 169 170 SendMsg(message); 171 } 172 } 173 174 } 175 176 /// <summary> 177 /// 根据传入WebSocket的类型,在已建立的封装的Socket model中查找是否有该枚举类型,如果有则发送信息 178 /// </summary> 179 /// <param name="type">Socket发送的枚举类型</param> 180 /// <param name="data">实体数据</param> 181 public void SendMsg(string data) 182 { 183 lock (SocketsLockFlag) 184 { 185 var bigScreenSocket = Sockets.Where(v => v.Socket.IsAvailable && v.userInfo?.ClientId == "BigScreenClient").FirstOrDefault(); 186 //var bigScreenSocket = Sockets.Where(v => v.Socket.IsAvailable ).FirstOrDefault(); 187 if (bigScreenSocket != null) 188 bigScreenSocket.Socket.Send(data); 189 } 190 } 191 192 193 }
调用代码
1 SocketSendHelper.Ins.StartSocketSend(); 2 SocketSendHelper.Ins.SendMsg("1111");
参考地址:https://www.cnblogs.com/zhangwei595806165/p/4791589.html

浙公网安备 33010602011771号