socket客户端与服务端正常通信,服务端过了一段时间就接收不到客户端的数据了
服务程序是接收数据的,然后大概1天左右都是正常的,突然一个时间点收不到数据了的问题解决
硬件与服务端通信,通过socket获取硬件数据,刚开始能够正常的接收数据,但是一段时间过后,服务端这边就无法接收到数据了,而且日志中也没有报错,暂时未知原因(因为是死循环,猜测是线程阻塞与等待),所以对服务端的Socket接收代码进行了优化后问题解决。
网上有各种骚操作,比如说,拔掉网线,重新启动,服务器可以恢复正常,有说关闭所有线程,手工启动,服务器能恢复正常,但这些都是治标不治本的办法,真正的原因还是因为线程阻塞了,当然每个场景不同,可能出现的问题不同,我这下面的解决主要就是针对线程阻塞导致,如有其他原因,可在 玩咖指针 首页添加我的微信给我发信息,一起探索交流。
以下是修改的关键代码:
以下是线程执行方法:
private void ClientReviceWorkThread(object obj) { int bytes; IDbContext db = DbList[0]; byte[] reviceBytes = new byte[1024]; string reviceContent = string.Empty; string reviceReturnJson = "\"return \":\"{0}\",\"id\":\"{1}\",\"res\":\"{2}\""; while (true) { SocketThread socketThread = obj as SocketThread; Socket socketClient = socketThread.socket; Thread.Sleep(100); string guid = Guid.NewGuid().ToString("N"); try { if (App.ServerLogIsWrite) DataOperation.WriteSys_ServerReivceLog(db, "接收模块", guid, socketThread.guid, "开始任务"); //接收请求如果已经断开连接了,就退出当前循环 if (!socketClient.Connected) { this.TryAction(() => { socketThread.socket.Close(); //关闭客户端Socket,清理资源 socketThread.status = SocketThreadStatus.NoConnectionWaitStop; }, (ex1) => { }); break; } //数据请求预处理 bool isNormal = false; bool isException = false; this.TryAction(() => { if (socketClient.Available <= 0) isNormal = false; else isNormal = true; }, (ex) => { isException = true; }); //连接已关闭,退出循环 if (isException) { this.TryAction(() => { socketThread.socket.Close(); //关闭客户端Socket,清理资源 socketThread.status = SocketThreadStatus.NoAvailableWaitStop; }, (ex1) => { }); break; } //如果没有数据可以接收,跳出当前循环 if (!isNormal) continue; if (App.ServerLogIsWrite) DataOperation.WriteSys_ServerReivceLog(db, "接收模块", guid, socketThread.guid, "接收数据开始"); socketClient.ReceiveTimeout = 1000 * 10; do { bytes = socketClient.Receive(reviceBytes, reviceBytes.Length, 0); //从客户端接受消息 reviceContent = Encoding.Default.GetString(reviceBytes, 0, bytes); } while (bytes == 1024); if (App.ServerLogIsWrite) DataOperation.WriteSys_ServerReivceLog(db, "接收模块", guid, socketThread.guid, "接收数据结束"); VoidResult result = null; if (reviceContent.IsEmptys()) { result = SocketHelper.SendDataToDeviceRevice(socketClient, "数据接收中断"); continue; } ReviceJson revice = JsonHelper.TryJsonToObject<ReviceJson>(reviceContent); if (revice == null) { result = SocketHelper.SendDataToDeviceRevice(socketClient, "指令错误"); continue; } string remoteEndPoint = socketClient.RemoteEndPoint.ToString(); string key = remoteEndPoint + "_DevID_" + revice.id; //数据接收成功,开始执行开始函数 if (ProcessWorkBegin != null && socketClient.Connected) this.ProcessWorkBegin(null, key + ":" + reviceContent); //一个设备只能有一个连接,有多个时,需要断开之前或者不允许这个连接 string currConnectionKey = string.Empty; DateTime clientLastReviceHeartbeatTime = DateTime.Now; ClientInfo client = null; foreach (var connectKey in ReviceConnectClientArrayObject.Keys) { if (connectKey == key) { continue; } if (connectKey.Contains("_DevID_" + revice.id)) { currConnectionKey = connectKey; break; } if (connectKey.Contains(remoteEndPoint)) { ReviceConnectClientArrayObject.TryGetValue(connectKey, out client); break; } } //如果当前连接已经绑定了设备,无法再绑定其他设备 if (client != null) { result = SocketHelper.SendDataToDeviceRevice(socketClient, "已经绑定设备,其他设备的指令无法解析"); continue; } //如果已经有其他连接在使用设备,需移除已经连接的设备 if (!currConnectionKey.IsEmptys() && ReviceConnectClientArrayObject.TryGetValue(currConnectionKey, out client)) { this.TryAction(() => { clientLastReviceHeartbeatTime = client.LastReviceHeartbeatTime; //移除前,先设定设备为离线状态 if (client.State == true) { client.State = false; DataOperation.UpdateDeviceOnlineStatusByDeviceCode(db, client.ReviceDeviceCode, false); } this.TryAction(() => { client.ClientSocket.Shutdown(SocketShutdown.Both); Thread.Sleep(10); client.ClientSocket.Close(); }, (ex) => { }); ReviceConnectClientArrayObject.TryRemove(currConnectionKey, out client); }, (ex) => { }); } //如果请求连接不存在 if (!ReviceConnectClientArrayObject.ContainsKey(key)) { client = new ClientInfo() { ClientID = key, RemoteEndPoint = remoteEndPoint, ReviceDeviceCode = revice.id }; client.ClientSocket = socketClient; client.State = true; //新连接设置当前时间为心跳检测的最新时间 client.LastReviceHeartbeatTime = clientLastReviceHeartbeatTime; this.ReviceConnectClientArrayObject.TryAdd(key, client); } else { //连接存在,并且连接是心跳包,更新当前时间为心跳检测的最新时间 if (ReviceConnectClientArrayObject.TryGetValue(key, out client) && revice.fun == "alive") { client.LastReviceHeartbeatTime = clientLastReviceHeartbeatTime; } } //返回给客户端信息 string msg = string.Format(reviceReturnJson, revice.fun, revice.id, "ok"); msg = "{" + msg + "}"; SocketHelper.SendDataToDeviceRevice(socketClient, msg); //不用队列处理 T_DeviceModel device = DataOperation.GetDeviceByReviceDeviceCode(db, GetAreaList(), revice.id); if (device != null) { WriteReviceInfoReal(dbMain, device, revice); } //数据接收完毕,开始执行结束函数 if (ProcessWorkEnd != null && socketClient.Connected) this.ProcessWorkEnd(socketClient, "数据已接收"); } catch (Exception ex) { DataOperation.WriteSys_ServerLog(db, "接收模块", ex); } } }