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. 77
      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()
{
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();
List<AlarmCode> list = JsonConvert.DeserializeObject<List<AlarmCode>>(jsonStr) ?? new();
AlarmCodeDict = list.ToDictionary(item => item.Id, item => item);
@ -28,7 +30,7 @@ public class AlarmCodeHelper
public static AlarmCode Get(string id)
{
return AlarmCodeDict[id];
return AlarmCodeDict[id] ?? AlarmCodeDict["1000"];
}
public static bool TryGet(string id, out AlarmCode alarmCode)

2
JiLinApp.Docking/JiLinApp.Docking.csproj

@ -17,7 +17,7 @@
</ItemGroup>
<ItemGroup>
<None Update="config\alarmcode.json">
<None Update="config\alarmcodes.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</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 int SensorTotal

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

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

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

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

2
JiLinApp/JiLinApp.csproj

@ -33,7 +33,7 @@
<ProjectReference Include="..\JiLinApp.Docking\JiLinApp.Docking.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="config\config.json">
<None Update="config\appconfig.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<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;
ICameraSDK cameraSdk = GetCameraSdk(cameraId);
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));
// TODO: 设计 PriorityQueue
@ -435,7 +436,11 @@ public partial class Main : UserControl
foreach (var item in CameraSdkDict.Values)
{
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;
}

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

Loading…
Cancel
Save