Browse Source

[fix] 修改 tcp 震动服务初始化命令逻辑

master
fajiao 1 year ago
parent
commit
81d67e773d
  1. 6
      JiLinApp.Docking/Alarm/AlarmCodeHelper.cs
  2. 2
      JiLinApp.Docking/JiLinApp.Docking.csproj
  3. 6
      JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs
  4. 55
      JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs
  5. 87
      JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs
  6. 0
      JiLinApp.Docking/config/alarmcodes.json
  7. 4
      JiLinApp/Core/Global.cs
  8. 2
      JiLinApp/JiLinApp.csproj
  9. 7
      JiLinApp/Pages/PtzManage/Main.xaml.cs
  10. 0
      JiLinApp/config/appconfig.json

6
JiLinApp.Docking/Alarm/AlarmCodeHelper.cs

@ -14,7 +14,9 @@ public class AlarmCodeHelper
static AlarmCodeHelper() static AlarmCodeHelper()
{ {
using StreamReader r = new(Path.Combine("config", "alarmcode.json")); string filePath = Path.Combine("config", "alarmcodes.json");
if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);
using StreamReader r = new(filePath);
string jsonStr = r.ReadToEnd(); string jsonStr = r.ReadToEnd();
List<AlarmCode> list = JsonConvert.DeserializeObject<List<AlarmCode>>(jsonStr) ?? new(); List<AlarmCode> list = JsonConvert.DeserializeObject<List<AlarmCode>>(jsonStr) ?? new();
AlarmCodeDict = list.ToDictionary(item => item.Id, item => item); AlarmCodeDict = list.ToDictionary(item => item.Id, item => item);
@ -28,7 +30,7 @@ public class AlarmCodeHelper
public static AlarmCode Get(string id) public static AlarmCode Get(string id)
{ {
return AlarmCodeDict[id]; return AlarmCodeDict[id] ?? AlarmCodeDict["1000"];
} }
public static bool TryGet(string id, out AlarmCode alarmCode) public static bool TryGet(string id, out AlarmCode alarmCode)

2
JiLinApp.Docking/JiLinApp.Docking.csproj

@ -17,7 +17,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="config\alarmcode.json"> <None Update="config\alarmcodes.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>

6
JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs

@ -22,6 +22,12 @@ public class ClientMessage
} }
} }
public bool Init_0_21 { get; set; }
public bool Init_1_24 { get; set; }
public bool Init_2_17 { get; set; }
public ConcurrentDictionary<int, SensorState> SensorDict { get; } = new(); public ConcurrentDictionary<int, SensorState> SensorDict { get; } = new();
public int SensorTotal public int SensorTotal

55
JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs

@ -2,6 +2,7 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
namespace JiLinApp.Docking.VibrateAlarm; namespace JiLinApp.Docking.VibrateAlarm;
@ -67,7 +68,7 @@ public class AsyncTcpServer : IDisposable
Encoding = Encoding.Default; Encoding = Encoding.Default;
Listener = new(address, port); Listener = new(address, port);
Clients = new(); Clients = new();
Listener.AllowNatTraversal(true); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) Listener.AllowNatTraversal(true);
} }
~AsyncTcpServer() ~AsyncTcpServer()
@ -111,6 +112,9 @@ public class AsyncTcpServer : IDisposable
{ {
Listener.Stop(); Listener.Stop();
} }
catch
{
}
finally finally
{ {
foreach (var client in Clients.Values) foreach (var client in Clients.Values)
@ -178,28 +182,20 @@ public class AsyncTcpServer : IDisposable
private void AcceptTcpClient(TcpListener listener) private void AcceptTcpClient(TcpListener listener)
{ {
listener.BeginAcceptTcpClient(HandleTcpClientAccepted, listener); TaskUtil.RunCatch(() => listener.BeginAcceptTcpClient(HandleTcpClientAccepted, listener));
} }
private void HandleTcpClientAccepted(IAsyncResult ar) private void HandleTcpClientAccepted(IAsyncResult ar)
{ {
if (!IsRunning()) return;
if (ar.AsyncState is not TcpListener listener) return;
TcpClient? client;
try try
{ {
client = listener.EndAcceptTcpClient(ar); if (ar.AsyncState is not TcpListener listener) return;
TcpClient? client = listener.EndAcceptTcpClient(ar);
if (client == null || !client.Connected) if (client == null || !client.Connected)
{ {
client?.Client.Disconnect(false); client?.Client.Disconnect(false);
return; return;
} }
}
catch (Exception)
{
return;
}
// add client connection to cache // add client connection to cache
string clientAddr = client.ClientAddr(); string clientAddr = client.ClientAddr();
@ -213,18 +209,29 @@ public class AsyncTcpServer : IDisposable
// keep listening to accept next connection // keep listening to accept next connection
AcceptTcpClient(listener); AcceptTcpClient(listener);
} }
catch (Exception)
{
}
}
private void ReadBuffer(TcpClientState clientState) private void ReadBuffer(TcpClientState clientState)
{ {
try try
{ {
NetworkStream stream = clientState.GetStream; NetworkStream stream = clientState.GetStream;
if (clientState.IsRead) return; int tryTime = 3, tryInterval = 200;
bool sleepFlag = false;
for (int i = 0; i < tryTime; i++)
{
if (sleepFlag) Thread.Sleep(tryInterval);
lock (clientState.IsReadLock) lock (clientState.IsReadLock)
{ {
if (clientState.IsRead) return; sleepFlag = clientState.IsRead;
if (sleepFlag) continue;
clientState.IsRead = true; clientState.IsRead = true;
stream.BeginRead(clientState.Buffer, 0, clientState.Buffer.Length, HandleDatagramReceived, clientState); stream.BeginRead(clientState.Buffer, 0, clientState.Buffer.Length, HandleDatagramReceived, clientState);
break;
}
} }
} }
catch (IOException e) catch (IOException e)
@ -242,9 +249,7 @@ public class AsyncTcpServer : IDisposable
private void HandleDatagramReceived(IAsyncResult ar) private void HandleDatagramReceived(IAsyncResult ar)
{ {
if (!IsRunning()) return;
if (ar.AsyncState is not TcpClientState clientState) return; if (ar.AsyncState is not TcpClientState clientState) return;
int readNum; int readNum;
string clientAddr = clientState.Client.ClientAddr(); string clientAddr = clientState.Client.ClientAddr();
try try
@ -269,11 +274,8 @@ public class AsyncTcpServer : IDisposable
Buffer.BlockCopy(clientState.Buffer, 0, receivedBytes, 0, readNum); Buffer.BlockCopy(clientState.Buffer, 0, receivedBytes, 0, readNum);
RaiseDatagramReceived(clientState, receivedBytes); RaiseDatagramReceived(clientState, receivedBytes);
lock (clientState.IsReadLock)
{
clientState.IsRead = false;
}
// continue listening for tcp datagram packets // continue listening for tcp datagram packets
lock (clientState.IsReadLock) clientState.IsRead = false;
ReadBuffer(clientState); ReadBuffer(clientState);
} }
@ -319,10 +321,7 @@ public class AsyncTcpServer : IDisposable
public void SendToAll(byte[] datagram) public void SendToAll(byte[] datagram)
{ {
if (!IsRunning()) return; if (!IsRunning()) return;
foreach (var client in Clients.Values) foreach (var client in Clients.Values) Send(client.Client, datagram);
{
Send(client.Client, datagram);
}
} }
/// <summary> /// <summary>
@ -331,7 +330,6 @@ public class AsyncTcpServer : IDisposable
/// <param name="datagram">报文</param> /// <param name="datagram">报文</param>
public void SendToAll(string datagram) public void SendToAll(string datagram)
{ {
if (!IsRunning()) return;
SendToAll(Encoding.GetBytes(datagram)); SendToAll(Encoding.GetBytes(datagram));
} }
@ -375,10 +373,7 @@ public class AsyncTcpServer : IDisposable
public void SendToAllAsync(byte[] datagram) public void SendToAllAsync(byte[] datagram)
{ {
if (!IsRunning()) return; if (!IsRunning()) return;
foreach (var client in Clients.Values) foreach (var client in Clients.Values) SendAsync(client.Client, datagram);
{
SendAsync(client.Client, datagram);
}
} }
/// <summary> /// <summary>
@ -387,7 +382,6 @@ public class AsyncTcpServer : IDisposable
/// <param name="datagram">报文</param> /// <param name="datagram">报文</param>
public void SendToAllAsync(string datagram) public void SendToAllAsync(string datagram)
{ {
if (!IsRunning()) return;
SendToAllAsync(Encoding.GetBytes(datagram)); SendToAllAsync(Encoding.GetBytes(datagram));
} }
@ -402,6 +396,7 @@ public class AsyncTcpServer : IDisposable
{ {
string clientAddr = client.ClientAddr(); string clientAddr = client.ClientAddr();
RaiseClientDisconnected(clientAddr, client); RaiseClientDisconnected(clientAddr, client);
return;
} }
} }

87
JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs

@ -151,9 +151,12 @@ public class TcpManager
#region Analysis #region Analysis
private int SendCmdInterval { get; } = 3000;
private void AnalysisClientMessage(ref ClientMessage clientMsg) private void AnalysisClientMessage(ref ClientMessage clientMsg)
{ {
List<byte[]> msgList = clientMsg.GetMessageList(); List<byte[]> msgList = clientMsg.GetMessageList();
ClientMessage taskClientMsg = clientMsg;
foreach (byte[] msg in msgList) foreach (byte[] msg in msgList)
{ {
bool vaild = msg.Length >= 19 && msg[0] == 0xAA && msg[1] == 0xAA; bool vaild = msg.Length >= 19 && msg[0] == 0xAA && msg[1] == 0xAA;
@ -167,10 +170,18 @@ public class TcpManager
case 0x00: case 0x00:
Console.WriteLine("主机登录:{0}", clientMsg.ClientAddr); Console.WriteLine("主机登录:{0}", clientMsg.ClientAddr);
ResponseHostLogin_10(clientMsg, mm); ResponseHostLogin_10(clientMsg, mm);
Thread.Sleep(200);
RequestHostAutoUploadState_24(clientMsg); if (clientMsg.Init_0_21) break;
Thread.Sleep(200); if (!Monitor.TryEnter(clientMsg.Init_0_21, 500)) break;
RequestSensorList_07(clientMsg); Task.Run(() =>
{
while (!taskClientMsg.Init_0_21)
{
Thread.Sleep(SendCmdInterval);
RequestSensorsTurnOn_21(taskClientMsg);
}
Monitor.Exit(taskClientMsg.Init_0_21);
});
break; break;
case 0x01: case 0x01:
@ -206,6 +217,7 @@ public class TcpManager
case 0x17: case 0x17:
Console.WriteLine("主机返回传感器列表:{0}", clientMsg.ClientAddr); Console.WriteLine("主机返回传感器列表:{0}", clientMsg.ClientAddr);
clientMsg.Init_2_17 = true;
for (int j = 0; j < mm.Data.Length; j++) for (int j = 0; j < mm.Data.Length; j++)
{ {
sensorAddr = Convert.ToByte((mm.Data[j] + mm.Data[++j] * 256)); sensorAddr = Convert.ToByte((mm.Data[j] + mm.Data[++j] * 256));
@ -240,12 +252,36 @@ public class TcpManager
case 0x31: case 0x31:
Console.WriteLine("传感器全部启动响应:{0}", clientMsg.ClientAddr); Console.WriteLine("传感器全部启动响应:{0}", clientMsg.ClientAddr);
clientMsg.Init_0_21 = true;
if (clientMsg.Init_1_24) break;
if (!Monitor.TryEnter(clientMsg.Init_1_24, 500)) break;
Task.Run(() =>
{
while (!taskClientMsg.Init_1_24)
{
Thread.Sleep(SendCmdInterval);
RequestHostAutoUploadState_24(taskClientMsg);
}
Monitor.Exit(taskClientMsg.Init_1_24);
});
SetDataResponse(mm, 0x21); SetDataResponse(mm, 0x21);
break; break;
case 0x34: case 0x34:
Console.WriteLine("主机启动自动上传响应:{0}", clientMsg.ClientAddr); Console.WriteLine("主机启动自动上传响应:{0}", clientMsg.ClientAddr);
clientMsg.Init_1_24 = true;
if (clientMsg.Init_2_17) break;
if (!Monitor.TryEnter(clientMsg.Init_2_17, 500)) break;
Task.Run(() =>
{
while (!taskClientMsg.Init_2_17)
{
Thread.Sleep(SendCmdInterval);
RequestSensorList_07(taskClientMsg);
}
Monitor.Exit(taskClientMsg.Init_2_17);
});
SetDataResponse(mm, 0x24); SetDataResponse(mm, 0x24);
break; break;
@ -434,7 +470,7 @@ public class TcpManager
{ {
Request = msg Request = msg
}; };
return SendRequestMust(ref request); return SendRequestTry(ref request);
} }
/// <summary> /// <summary>
@ -560,7 +596,7 @@ public class TcpManager
{ {
Request = msg Request = msg
}; };
return SendRequestMust(ref request); return SendRequestTry(ref request);
} }
/// <summary> /// <summary>
@ -643,13 +679,13 @@ public class TcpManager
private byte FrameInc private byte FrameInc
{ get { return (byte)(++Frame % byte.MaxValue); } } { get { return (byte)(++Frame % byte.MaxValue); } }
private int SendTryTime { get; set; } = 5; private int SendTryTime { get; set; } = 3;
private int SendTryInterval { get; set; } = 200; private int SendTryInterval { get; set; } = 300;
private int ReqWaitTime { get; set; } = 3 * 10; private int ReqWaitTime { get; set; } = 3;
private int ReqWaitInterval { get; set; } = 100; private int ReqWaitInterval { get; set; } = 2000;
private DataMessage GetSendMessageHead(int deviceId, ClientMessage client, byte funNum, byte dataLen) private DataMessage GetSendMessageHead(int deviceId, ClientMessage client, byte funNum, byte dataLen)
{ {
@ -686,37 +722,29 @@ public class TcpManager
{ {
if (request.Request == null) return false; if (request.Request == null) return false;
request.Request.FrameNum = FrameInc; request.Request.FrameNum = FrameInc;
bool send = SendMessage(request.Request.ReceiveIp, request.Request.Encode());
if (!send) return false;
bool respond = false;
SetDataRequest(request); SetDataRequest(request);
for (int i = 0; i < ReqWaitTime; i++) bool send = SendMessage(request.Request.ReceiveIp, request.Request.Encode());
{
respond = IsResponse(request);
if (respond) break;
Thread.Sleep(ReqWaitInterval);
}
RemoveDataRequest(request); RemoveDataRequest(request);
return respond; return send;
} }
private bool SendRequestMust(ref DataRequest request) private bool SendRequestMust(ref DataRequest request)
{ {
if (request.Request == null) return false; if (request.Request == null) return false;
request.Request.FrameNum = FrameInc; request.Request.FrameNum = FrameInc;
SetDataRequest(request);
bool send, respond = false; bool send, respond = false;
do do
{ {
send = SendMessage(request.Request.ReceiveIp, request.Request.Encode()); send = SendMessage(request.Request.ReceiveIp, request.Request.Encode());
if (!send) continue; if (!send) { Thread.Sleep(SendTryInterval); continue; }
SetDataRequest(request);
for (int i = 0; i < ReqWaitTime; i++) for (int i = 0; i < ReqWaitTime; i++)
{ {
respond = IsResponse(request); respond = IsResponse(request);
if (respond) break; if (respond) break;
Thread.Sleep(ReqWaitInterval); Thread.Sleep(ReqWaitInterval);
} }
} while (!send && !respond); } while (!send || !respond);
RemoveDataRequest(request); RemoveDataRequest(request);
return true; return true;
} }
@ -739,27 +767,26 @@ public class TcpManager
private void SetDataRequest(DataRequest request) private void SetDataRequest(DataRequest request)
{ {
string key = $"{request.Request.FunctionNum}-{request.Request.FrameNum}"; string key = $"{request.Request.FunctionNum:X}-{request.Request.FrameNum}";
DataRequestDict[key] = request; DataRequestDict[key] = request;
} }
private void SetDataResponse(DataMessage msg, byte funcNum) private void SetDataResponse(DataMessage msg, byte funcNum)
{ {
string key = $"{funcNum}-{msg.FrameNum}"; string key = $"{funcNum:X}-{msg.FrameNum}";
DataRequest? item = DataRequestDict[key]; if (DataRequestDict.TryGetValue(key, out DataRequest? item)) item.Responce = msg;
if (item != null) item.Responce = msg;
} }
private void RemoveDataRequest(DataRequest request) private void RemoveDataRequest(DataRequest request)
{ {
string key = $"{request.Request.FunctionNum}-{request.Request.FrameNum}"; string key = $"{request.Request.FunctionNum:X}-{request.Request.FrameNum}";
DataRequestDict.Remove(key); DataRequestDict.Remove(key);
} }
private bool IsResponse(DataRequest request) private bool IsResponse(DataRequest request)
{ {
string key = $"{request.Request.FunctionNum}-{request.Request.FrameNum}"; string key = $"{request.Request.FunctionNum:X}-{request.Request.FrameNum}";
DataRequest? item = DataRequestDict[key]; DataRequestDict.TryGetValue(key, out DataRequest? item);
return item != null && item.Responce != null; return item != null && item.Responce != null;
} }

0
JiLinApp.Docking/config/alarmcode.json → JiLinApp.Docking/config/alarmcodes.json

4
JiLinApp/Core/Global.cs

@ -29,7 +29,9 @@ public static class Global
try try
{ {
// Config // Config
ConfigProvider = new() { FileName = Path.Combine("config", "config.json") }; string filePath = Path.Combine("config", "appconfig.json");
if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);
ConfigProvider = new() { FileName = filePath };
AppConfig = new AppConfig(); AppConfig = new AppConfig();
ConfigProvider.Bind(AppConfig); ConfigProvider.Bind(AppConfig);

2
JiLinApp/JiLinApp.csproj

@ -33,7 +33,7 @@
<ProjectReference Include="..\JiLinApp.Docking\JiLinApp.Docking.csproj" /> <ProjectReference Include="..\JiLinApp.Docking\JiLinApp.Docking.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="config\config.json"> <None Update="config\appconfig.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="config\log4net.config"> <None Update="config\log4net.config">

7
JiLinApp/Pages/PtzManage/Main.xaml.cs

@ -337,6 +337,7 @@ public partial class Main : UserControl
string cameraId = item.CameraId; string cameraId = item.CameraId;
ICameraSDK cameraSdk = GetCameraSdk(cameraId); ICameraSDK cameraSdk = GetCameraSdk(cameraId);
if (cameraSdk == null) { LogUnit.Error(this, $"CameraSdk(cameraId:{cameraId}) not found."); return; } if (cameraSdk == null) { LogUnit.Error(this, $"CameraSdk(cameraId:{cameraId}) not found."); return; }
if (cameraSdk.ConnectSuccess()) { MessageBox.Show($"Camera:{cameraSdk.CameraInfo.Ip}, connect failed."); return; }
if (realPlay) Dispatcher.Invoke(() => ShowLiveVideo(cameraSdk)); if (realPlay) Dispatcher.Invoke(() => ShowLiveVideo(cameraSdk));
// TODO: 设计 PriorityQueue // TODO: 设计 PriorityQueue
@ -435,7 +436,11 @@ public partial class Main : UserControl
foreach (var item in CameraSdkDict.Values) foreach (var item in CameraSdkDict.Values)
{ {
if (item == null) continue; if (item == null) continue;
if (cameraId.Equals(item.CameraInfo.Id)) return item; if (cameraId.Equals(item.CameraInfo.Id))
{
if (!item.ConnectSuccess()) item.Init();
return item;
}
} }
return null; return null;
} }

0
JiLinApp/config/config.json → JiLinApp/config/appconfig.json

Loading…
Cancel
Save