保留CAP组件,后续决定是否移除

This commit is contained in:
zenghongyao 2025-04-16 09:54:21 +08:00
parent e1106b3241
commit 0d4c780727
20 changed files with 299 additions and 45 deletions

View File

@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Protocol.T
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Cassandra", "src\JiShe.CollectBus.Cassandra\JiShe.CollectBus.Cassandra.csproj", "{443B4549-0AC0-4493-8F3E-49C83225DD76}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Cassandra", "src\JiShe.CollectBus.Cassandra\JiShe.CollectBus.Cassandra.csproj", "{443B4549-0AC0-4493-8F3E-49C83225DD76}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Kafka.Test", "src\JiShe.CollectBus.Kafka.Test\JiShe.CollectBus.Kafka.Test.csproj", "{FA762E8F-659A-DECF-83D6-5F364144450E}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -113,6 +115,10 @@ Global
{443B4549-0AC0-4493-8F3E-49C83225DD76}.Debug|Any CPU.Build.0 = Debug|Any CPU {443B4549-0AC0-4493-8F3E-49C83225DD76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{443B4549-0AC0-4493-8F3E-49C83225DD76}.Release|Any CPU.ActiveCfg = Release|Any CPU {443B4549-0AC0-4493-8F3E-49C83225DD76}.Release|Any CPU.ActiveCfg = Release|Any CPU
{443B4549-0AC0-4493-8F3E-49C83225DD76}.Release|Any CPU.Build.0 = Release|Any CPU {443B4549-0AC0-4493-8F3E-49C83225DD76}.Release|Any CPU.Build.0 = Release|Any CPU
{FA762E8F-659A-DECF-83D6-5F364144450E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA762E8F-659A-DECF-83D6-5F364144450E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA762E8F-659A-DECF-83D6-5F364144450E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA762E8F-659A-DECF-83D6-5F364144450E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -135,6 +141,7 @@ Global
{A3F3C092-0A25-450B-BF6A-5983163CBEF5} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} {A3F3C092-0A25-450B-BF6A-5983163CBEF5} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{A377955E-7EA1-6F29-8CF7-774569E93925} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} {A377955E-7EA1-6F29-8CF7-774569E93925} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{443B4549-0AC0-4493-8F3E-49C83225DD76} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} {443B4549-0AC0-4493-8F3E-49C83225DD76} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{FA762E8F-659A-DECF-83D6-5F364144450E} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD} SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD}

View File

@ -5,6 +5,7 @@ using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using DeviceDetectorNET.Class.Device; using DeviceDetectorNET.Class.Device;
using DotNetCore.CAP;
using JiShe.CollectBus.Common.BuildSendDatas; using JiShe.CollectBus.Common.BuildSendDatas;
using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Extensions;
@ -30,14 +31,16 @@ namespace JiShe.CollectBus.EnergySystem
private readonly IRepository<CsqRecord,Guid> _csqRecordRepository; private readonly IRepository<CsqRecord,Guid> _csqRecordRepository;
private readonly IRepository<ConrOnlineRecord,Guid> _conrOnlineRecordRepository; private readonly IRepository<ConrOnlineRecord,Guid> _conrOnlineRecordRepository;
private readonly IProducerService _producerService; private readonly IProducerService _producerService;
private readonly ICapPublisher _capBus;
public EnergySystemAppService(IRepository<FocusRecord, Guid> focusRecordRepository, IRepository<CsqRecord, Guid> csqRecordRepository, public EnergySystemAppService(IRepository<FocusRecord, Guid> focusRecordRepository, IRepository<CsqRecord, Guid> csqRecordRepository,
IRepository<ConrOnlineRecord, Guid> conrOnlineRecordRepository, IProducerService producerService) IRepository<ConrOnlineRecord, Guid> conrOnlineRecordRepository, IProducerService producerService, ICapPublisher capBus)
{ {
_focusRecordRepository = focusRecordRepository; _focusRecordRepository = focusRecordRepository;
_csqRecordRepository = csqRecordRepository; _csqRecordRepository = csqRecordRepository;
_conrOnlineRecordRepository = conrOnlineRecordRepository; _conrOnlineRecordRepository = conrOnlineRecordRepository;
_producerService = producerService; _producerService = producerService;
_capBus = capBus;
} }
/// <summary> /// <summary>
@ -71,7 +74,15 @@ namespace JiShe.CollectBus.EnergySystem
if (bytes == null) if (bytes == null)
return result; return result;
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -109,6 +120,15 @@ namespace JiShe.CollectBus.EnergySystem
foreach (var bytes in bytesList) foreach (var bytes in bytesList)
{ {
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -117,6 +137,7 @@ namespace JiShe.CollectBus.EnergySystem
Type = IssuedEventType.Data, Type = IssuedEventType.Data,
MessageId = NewId.NextGuid().ToString() MessageId = NewId.NextGuid().ToString()
}.Serialize()); }.Serialize());
} }
return result; return result;
@ -150,6 +171,14 @@ namespace JiShe.CollectBus.EnergySystem
}).ToList(); }).ToList();
var bytes = Build3761SendData.BuildAmmeterParameterSetSendCmd(address, meterParameters); var bytes = Build3761SendData.BuildAmmeterParameterSetSendCmd(address, meterParameters);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -179,6 +208,15 @@ namespace JiShe.CollectBus.EnergySystem
{ {
var dataUnit = Build645SendData.BuildReadMeterAddressSendDataUnit(detail.MeterAddress); var dataUnit = Build645SendData.BuildReadMeterAddressSendDataUnit(detail.MeterAddress);
var bytes =Build3761SendData.BuildTransparentForwardingSendCmd(address, detail.Port, detail.BaudRate.ToString(), dataUnit, StopBit.Stop1, Parity.None); var bytes =Build3761SendData.BuildTransparentForwardingSendCmd(address, detail.Port, detail.BaudRate.ToString(), dataUnit, StopBit.Stop1, Parity.None);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -262,6 +300,15 @@ namespace JiShe.CollectBus.EnergySystem
if (bytes != null) if (bytes != null)
{ {
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -321,6 +368,15 @@ namespace JiShe.CollectBus.EnergySystem
var bytes = Build3761SendData.BuildCommunicationParametersSetSendCmd(address, masterIP, materPort, var bytes = Build3761SendData.BuildCommunicationParametersSetSendCmd(address, masterIP, materPort,
backupIP, backupPort, input.Data.APN); backupIP, backupPort, input.Data.APN);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -348,6 +404,15 @@ namespace JiShe.CollectBus.EnergySystem
var address = $"{input.AreaCode}{input.Address}"; var address = $"{input.AreaCode}{input.Address}";
var bytes = Build3761SendData.BuildTerminalCalendarClockSendCmd(address); var bytes = Build3761SendData.BuildTerminalCalendarClockSendCmd(address);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -376,6 +441,14 @@ namespace JiShe.CollectBus.EnergySystem
bool isManual = !input.AreaCode.Equals("5110");//低功耗集中器不是长连接,在连接的那一刻再发送 bool isManual = !input.AreaCode.Equals("5110");//低功耗集中器不是长连接,在连接的那一刻再发送
var bytes = Build3761SendData.BuildConrCheckTimeSendCmd(address,DateTime.Now, isManual); var bytes = Build3761SendData.BuildConrCheckTimeSendCmd(address,DateTime.Now, isManual);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -403,6 +476,14 @@ namespace JiShe.CollectBus.EnergySystem
var address = $"{input.AreaCode}{input.Address}"; var address = $"{input.AreaCode}{input.Address}";
var bytes = Build3761SendData.BuildConrRebootSendCmd(address); var bytes = Build3761SendData.BuildConrRebootSendCmd(address);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -431,6 +512,14 @@ namespace JiShe.CollectBus.EnergySystem
var address = $"{input.AreaCode}{input.Address}"; var address = $"{input.AreaCode}{input.Address}";
var pnList = input.Data.Split(',').Select(it => int.Parse(it)).ToList(); var pnList = input.Data.Split(',').Select(it => int.Parse(it)).ToList();
var bytes = Build3761SendData.BuildAmmeterParameterReadingSendCmd(address, pnList); var bytes = Build3761SendData.BuildAmmeterParameterReadingSendCmd(address, pnList);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -480,6 +569,15 @@ namespace JiShe.CollectBus.EnergySystem
foreach (var bytes in bytesList) foreach (var bytes in bytesList)
{ {
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -488,7 +586,7 @@ namespace JiShe.CollectBus.EnergySystem
Type = IssuedEventType.Data, Type = IssuedEventType.Data,
MessageId = NewId.NextGuid().ToString() MessageId = NewId.NextGuid().ToString()
}.Serialize()); }.Serialize());
} }
result.Status = true; result.Status = true;
result.Msg = "操作成功"; result.Msg = "操作成功";
@ -549,6 +647,14 @@ namespace JiShe.CollectBus.EnergySystem
foreach (var bytes in bytesList) foreach (var bytes in bytesList)
{ {
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -578,6 +684,14 @@ namespace JiShe.CollectBus.EnergySystem
var address = $"{code.AreaCode}{code.Address}"; var address = $"{code.AreaCode}{code.Address}";
var bytes = Build3761SendData.BuildAmmeterReportCollectionItemsSetSendCmd(address,input.Detail.Pn, input.Detail.Unit,input.Detail.Cycle,input.Detail.BaseTime, var bytes = Build3761SendData.BuildAmmeterReportCollectionItemsSetSendCmd(address,input.Detail.Pn, input.Detail.Unit,input.Detail.Cycle,input.Detail.BaseTime,
input.Detail.CurveRatio,input.Detail.Details.Select(it => new PnFn(it.Pn,it.Fn)).ToList()); input.Detail.CurveRatio,input.Detail.Details.Select(it => new PnFn(it.Pn,it.Fn)).ToList());
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -606,6 +720,14 @@ namespace JiShe.CollectBus.EnergySystem
{ {
var address = $"{code.AreaCode}{code.Address}"; var address = $"{code.AreaCode}{code.Address}";
var bytes = Build3761SendData.BuildAmmeterAutoUpSwitchSetSendCmd(address, input.Detail.Pn,input.Detail.IsOpen); var bytes = Build3761SendData.BuildAmmeterAutoUpSwitchSetSendCmd(address, input.Detail.Pn,input.Detail.IsOpen);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -632,6 +754,14 @@ namespace JiShe.CollectBus.EnergySystem
var result = new BaseResultDto(); var result = new BaseResultDto();
var address = $"{input.AreaCode}{input.Address}"; var address = $"{input.AreaCode}{input.Address}";
var bytes = Build3761SendData.BuildAmmeterReadAutoUpSwitchSendCmd(address, input.Detail.Pn); var bytes = Build3761SendData.BuildAmmeterReadAutoUpSwitchSendCmd(address, input.Detail.Pn);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -659,6 +789,14 @@ namespace JiShe.CollectBus.EnergySystem
{ {
var address = $"{data.AreaCode}{data.Address}"; var address = $"{data.AreaCode}{data.Address}";
var bytes = Build3761SendData.BuildTerminalVersionInfoReadingSendCmd(address); var bytes = Build3761SendData.BuildTerminalVersionInfoReadingSendCmd(address);
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,
@ -714,6 +852,14 @@ namespace JiShe.CollectBus.EnergySystem
foreach (var bytes in bytesList) foreach (var bytes in bytesList)
{ {
//await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
//{
// //ClientId = messageReceived.ClientId,
// DeviceNo = address,
// Message = bytes,
// Type = IssuedEventType.Data,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
{ {
//ClientId = messageReceived.ClientId, //ClientId = messageReceived.ClientId,

View File

@ -15,6 +15,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DotNetCore.CAP" Version="8.3.1" />
<PackageReference Include="MassTransit.Kafka" Version="8.4.0" /> <PackageReference Include="MassTransit.Kafka" Version="8.4.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="8.3.3" /> <PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="8.3.3" />

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using DeviceDetectorNET.Parser.Device; using DeviceDetectorNET.Parser.Device;
using DotNetCore.CAP;
using JiShe.CollectBus.Ammeters; using JiShe.CollectBus.Ammeters;
using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Extensions;
@ -27,6 +28,7 @@ namespace JiShe.CollectBus.Plugins
{ {
public partial class TcpMonitor : PluginBase, ITransientDependency, ITcpReceivedPlugin, ITcpConnectingPlugin, ITcpConnectedPlugin, ITcpClosedPlugin public partial class TcpMonitor : PluginBase, ITransientDependency, ITcpReceivedPlugin, ITcpConnectingPlugin, ITcpConnectedPlugin, ITcpClosedPlugin
{ {
private readonly ICapPublisher _producerBus;
private readonly IProducerService _producerService; private readonly IProducerService _producerService;
private readonly ILogger<TcpMonitor> _logger; private readonly ILogger<TcpMonitor> _logger;
private readonly IRepository<Device, Guid> _deviceRepository; private readonly IRepository<Device, Guid> _deviceRepository;
@ -39,11 +41,12 @@ namespace JiShe.CollectBus.Plugins
/// <param name="logger"></param> /// <param name="logger"></param>
/// <param name="deviceRepository"></param> /// <param name="deviceRepository"></param>
/// <param name="ammeterInfoCache"></param> /// <param name="ammeterInfoCache"></param>
public TcpMonitor(IProducerService producerService, public TcpMonitor(ICapPublisher producerBus, IProducerService producerService,
ILogger<TcpMonitor> logger, ILogger<TcpMonitor> logger,
IRepository<Device, Guid> deviceRepository, IRepository<Device, Guid> deviceRepository,
IDistributedCache<AmmeterInfo> ammeterInfoCache) IDistributedCache<AmmeterInfo> ammeterInfoCache)
{ {
_producerBus = producerBus;
_producerService = producerService; _producerService = producerService;
_logger = logger; _logger = logger;
_deviceRepository = deviceRepository; _deviceRepository = deviceRepository;
@ -171,6 +174,10 @@ namespace JiShe.CollectBus.Plugins
DeviceNo = deviceNo, DeviceNo = deviceNo,
MessageId = NewId.NextGuid().ToString() MessageId = NewId.NextGuid().ToString()
}; };
//await _producerBus.PublishAsync(ProtocolConst.SubscriberLoginReceivedEventName, messageReceivedLoginEvent);
await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginReceivedEventName, messageReceivedLoginEvent.Serialize()); await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginReceivedEventName, messageReceivedLoginEvent.Serialize());
//await _producerBus.Publish( messageReceivedLoginEvent); //await _producerBus.Publish( messageReceivedLoginEvent);
@ -218,6 +225,8 @@ namespace JiShe.CollectBus.Plugins
DeviceNo = deviceNo, DeviceNo = deviceNo,
MessageId = NewId.NextGuid().ToString() MessageId = NewId.NextGuid().ToString()
}; };
//await _producerBus.PublishAsync(ProtocolConst.SubscriberHeartbeatReceivedEventName, messageReceivedHeartbeatEvent);
await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatReceivedEventName, messageReceivedHeartbeatEvent.Serialize()); await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatReceivedEventName, messageReceivedHeartbeatEvent.Serialize());
//await _producerBus.Publish(messageReceivedHeartbeatEvent); //await _producerBus.Publish(messageReceivedHeartbeatEvent);
} }
@ -242,10 +251,18 @@ namespace JiShe.CollectBus.Plugins
// MessageId = NewId.NextGuid().ToString() // MessageId = NewId.NextGuid().ToString()
//}); //});
//string topicName = string.Format(ProtocolConst.AFNTopicNameFormat, aFn); //string topicName = string.Format(ProtocolConst.AFNTopicNameFormat, aFn);
//todo 如何确定时标?目前集中器的采集频率,都是固定,数据上报的时候,根据当前时间,往后推测出应当采集的时间点作为时标。但是如果由于网络问题,数据一直没上报的情况改怎么计算? //todo 如何确定时标?目前集中器的采集频率,都是固定,数据上报的时候,根据当前时间,往后推测出应当采集的时间点作为时标。但是如果由于网络问题,数据一直没上报的情况改怎么计算?
//await _producerBus.PublishAsync(ProtocolConst.SubscriberReceivedEventName, new MessageReceived
//{
// ClientId = client.Id,
// ClientIp = client.IP,
// ClientPort = client.Port,
// MessageHexString = messageHexString,
// DeviceNo = deviceNo,
// MessageId = NewId.NextGuid().ToString()
//});
await _producerService.ProduceAsync(ProtocolConst.SubscriberReceivedEventName, new MessageReceived await _producerService.ProduceAsync(ProtocolConst.SubscriberReceivedEventName, new MessageReceived
{ {
ClientId = client.Id, ClientId = client.Id,

View File

@ -215,7 +215,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
return aa == null; return aa == null;
} }
[KafkaSubscribe(["test-topic"])] [KafkaSubscribe("test-topic1")]
public async Task<ISubscribeAck> KafkaSubscribeAsync(object obj) public async Task<ISubscribeAck> KafkaSubscribeAsync(object obj)
{ {

View File

@ -1,4 +1,5 @@
using JiShe.CollectBus.Ammeters; using DotNetCore.CAP;
using JiShe.CollectBus.Ammeters;
using JiShe.CollectBus.Common.BuildSendDatas; using JiShe.CollectBus.Common.BuildSendDatas;
using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.Consts;
using JiShe.CollectBus.Common.DeviceBalanceControl; using JiShe.CollectBus.Common.DeviceBalanceControl;
@ -31,14 +32,16 @@ namespace JiShe.CollectBus.ScheduledMeterReading
private readonly IIoTDBProvider _dbProvider; private readonly IIoTDBProvider _dbProvider;
private readonly IMeterReadingRecordRepository _meterReadingRecordRepository; private readonly IMeterReadingRecordRepository _meterReadingRecordRepository;
private readonly IProducerService _producerService; private readonly IProducerService _producerService;
private readonly ICapPublisher _producerBus;
public BasicScheduledMeterReadingService( public BasicScheduledMeterReadingService(
ILogger<BasicScheduledMeterReadingService> logger, ILogger<BasicScheduledMeterReadingService> logger,
ICapPublisher producerBus,
IMeterReadingRecordRepository meterReadingRecordRepository, IMeterReadingRecordRepository meterReadingRecordRepository,
IProducerService producerService, IProducerService producerService,
IIoTDBProvider dbProvider) IIoTDBProvider dbProvider)
{ {
_producerBus = producerBus;
_logger = logger; _logger = logger;
_dbProvider = dbProvider; _dbProvider = dbProvider;
_meterReadingRecordRepository = meterReadingRecordRepository; _meterReadingRecordRepository = meterReadingRecordRepository;
@ -377,6 +380,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading
FocusAddress = ammerterItem.Value.FocusAddress, FocusAddress = ammerterItem.Value.FocusAddress,
TimeDensity = timeDensity.ToString(), TimeDensity = timeDensity.ToString(),
}; };
//_ = _producerBus.PublishDelayAsync(TimeSpan.FromMicroseconds(500), ProtocolConst.AmmeterSubscriberWorkerOneMinuteIssuedEventName, tempMsg);
_ = _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerOneMinuteIssuedEventName, tempMsg.Serialize()); _ = _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerOneMinuteIssuedEventName, tempMsg.Serialize());
//_= _producerBus.Publish(tempMsg); //_= _producerBus.Publish(tempMsg);
@ -441,6 +446,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading
FocusAddress = ammerterItem.Value.FocusAddress, FocusAddress = ammerterItem.Value.FocusAddress,
TimeDensity = timeDensity.ToString(), TimeDensity = timeDensity.ToString(),
}; };
//_ = _producerBus.PublishDelayAsync(TimeSpan.FromMicroseconds(500), ProtocolConst.AmmeterSubscriberWorkerFiveMinuteIssuedEventName, tempMsg);
_ = _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerFiveMinuteIssuedEventName, tempMsg.Serialize()); _ = _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerFiveMinuteIssuedEventName, tempMsg.Serialize());
//_ = _producerBus.Publish(tempMsg); //_ = _producerBus.Publish(tempMsg);
@ -505,6 +512,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
FocusAddress = ammerterItem.Value.FocusAddress, FocusAddress = ammerterItem.Value.FocusAddress,
TimeDensity = timeDensity.ToString(), TimeDensity = timeDensity.ToString(),
}; };
//_ = _producerBus.PublishDelayAsync(TimeSpan.FromMicroseconds(500), ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempMsg);
_ = _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempMsg.Serialize()); _ = _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempMsg.Serialize());
@ -841,6 +849,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
FocusAddress = ammerterItem.Value.FocusAddress, FocusAddress = ammerterItem.Value.FocusAddress,
TimeDensity = timeDensity.ToString(), TimeDensity = timeDensity.ToString(),
}; };
//_ = _producerBus.PublishDelayAsync(TimeSpan.FromMicroseconds(500), ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempMsg);
_ = _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempMsg.Serialize()); _ = _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempMsg.Serialize());
@ -1149,6 +1158,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
FocusAddress = ammerterItem.Value.FocusAddress, FocusAddress = ammerterItem.Value.FocusAddress,
TimeDensity = timeDensity.ToString(), TimeDensity = timeDensity.ToString(),
}; };
//await _producerBus.PublishAsync(ProtocolConst.WatermeterSubscriberWorkerAutoReadingIssuedEventName, tempMsg); //await _producerBus.PublishAsync(ProtocolConst.WatermeterSubscriberWorkerAutoReadingIssuedEventName, tempMsg);
//_ = _producerBus.Publish(tempMsg); //_ = _producerBus.Publish(tempMsg);

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Confluent.Kafka; using Confluent.Kafka;
using DotNetCore.CAP;
using JiShe.CollectBus.Ammeters; using JiShe.CollectBus.Ammeters;
using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.Consts;
using JiShe.CollectBus.Common.DeviceBalanceControl; using JiShe.CollectBus.Common.DeviceBalanceControl;
@ -35,7 +36,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
{ {
string serverTagName = string.Empty; string serverTagName = string.Empty;
public EnergySystemScheduledMeterReadingService(ILogger<EnergySystemScheduledMeterReadingService> logger, public EnergySystemScheduledMeterReadingService(ILogger<EnergySystemScheduledMeterReadingService> logger,
IIoTDBProvider dbProvider, IMeterReadingRecordRepository meterReadingRecordRepository,IConfiguration configuration, IProducerService producerService) : base(logger, meterReadingRecordRepository, producerService,dbProvider) ICapPublisher producerBus, IIoTDBProvider dbProvider, IMeterReadingRecordRepository meterReadingRecordRepository,IConfiguration configuration, IProducerService producerService) : base(logger, producerBus, meterReadingRecordRepository, producerService,dbProvider)
{ {
serverTagName = configuration.GetValue<string>(CommonConst.ServerTagName)!; serverTagName = configuration.GetValue<string>(CommonConst.ServerTagName)!;
} }

View File

@ -1,4 +1,5 @@
using JiShe.CollectBus.Common.Enums; using DotNetCore.CAP;
using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Helpers;
using JiShe.CollectBus.Common.Models; using JiShe.CollectBus.Common.Models;
using JiShe.CollectBus.IoTDBProvider; using JiShe.CollectBus.IoTDBProvider;
@ -21,7 +22,7 @@ using Volo.Abp.Domain.Repositories;
namespace JiShe.CollectBus.Subscribers namespace JiShe.CollectBus.Subscribers
{ {
public class SubscriberAppService : CollectBusAppService, ISubscriberAppService, IKafkaSubscribe public class SubscriberAppService : CollectBusAppService, ISubscriberAppService, ICapSubscribe, IKafkaSubscribe
{ {
private readonly ILogger<SubscriberAppService> _logger; private readonly ILogger<SubscriberAppService> _logger;
private readonly ITcpService _tcpService; private readonly ITcpService _tcpService;
@ -65,6 +66,7 @@ namespace JiShe.CollectBus.Subscribers
} }
[KafkaSubscribe(ProtocolConst.SubscriberLoginIssuedEventName)] [KafkaSubscribe(ProtocolConst.SubscriberLoginIssuedEventName)]
//[CapSubscribe(ProtocolConst.SubscriberLoginIssuedEventName)]
public async Task<ISubscribeAck> LoginIssuedEvent(IssuedEventMessage issuedEventMessage) public async Task<ISubscribeAck> LoginIssuedEvent(IssuedEventMessage issuedEventMessage)
{ {
bool isAck = false; bool isAck = false;
@ -97,6 +99,7 @@ namespace JiShe.CollectBus.Subscribers
} }
[KafkaSubscribe(ProtocolConst.SubscriberHeartbeatIssuedEventName)] [KafkaSubscribe(ProtocolConst.SubscriberHeartbeatIssuedEventName)]
//[CapSubscribe(ProtocolConst.SubscriberHeartbeatIssuedEventName)]
public async Task<ISubscribeAck> HeartbeatIssuedEvent(IssuedEventMessage issuedEventMessage) public async Task<ISubscribeAck> HeartbeatIssuedEvent(IssuedEventMessage issuedEventMessage)
{ {
bool isAck = false; bool isAck = false;
@ -127,6 +130,7 @@ namespace JiShe.CollectBus.Subscribers
} }
[KafkaSubscribe(ProtocolConst.SubscriberReceivedEventName)] [KafkaSubscribe(ProtocolConst.SubscriberReceivedEventName)]
//[CapSubscribe(ProtocolConst.SubscriberReceivedEventName)]
public async Task<ISubscribeAck> ReceivedEvent(MessageReceived receivedMessage) public async Task<ISubscribeAck> ReceivedEvent(MessageReceived receivedMessage)
{ {
var currentTime = Clock.Now; var currentTime = Clock.Now;
@ -183,6 +187,7 @@ namespace JiShe.CollectBus.Subscribers
} }
[KafkaSubscribe(ProtocolConst.SubscriberHeartbeatReceivedEventName)] [KafkaSubscribe(ProtocolConst.SubscriberHeartbeatReceivedEventName)]
//[CapSubscribe(ProtocolConst.SubscriberHeartbeatReceivedEventName)]
public async Task<ISubscribeAck> ReceivedHeartbeatEvent(MessageReceivedHeartbeat receivedHeartbeatMessage) public async Task<ISubscribeAck> ReceivedHeartbeatEvent(MessageReceivedHeartbeat receivedHeartbeatMessage)
{ {
var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin"); var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin");
@ -199,6 +204,7 @@ namespace JiShe.CollectBus.Subscribers
} }
[KafkaSubscribe(ProtocolConst.SubscriberLoginReceivedEventName)] [KafkaSubscribe(ProtocolConst.SubscriberLoginReceivedEventName)]
//[CapSubscribe(ProtocolConst.SubscriberLoginReceivedEventName)]
public async Task<ISubscribeAck> ReceivedLoginEvent(MessageReceivedLogin receivedLoginMessage) public async Task<ISubscribeAck> ReceivedLoginEvent(MessageReceivedLogin receivedLoginMessage)
{ {
var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin"); var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin");

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using DeviceDetectorNET.Parser.Device; using DeviceDetectorNET.Parser.Device;
using DotNetCore.CAP;
using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.IotSystems.Devices;
using JiShe.CollectBus.IotSystems.MessageIssueds; using JiShe.CollectBus.IotSystems.MessageIssueds;
@ -25,7 +26,7 @@ namespace JiShe.CollectBus.Subscribers
/// 定时抄读任务消息消费订阅 /// 定时抄读任务消息消费订阅
/// </summary> /// </summary>
[Route($"/worker/app/subscriber")] [Route($"/worker/app/subscriber")]
public class WorkerSubscriberAppService : CollectBusAppService, IWorkerSubscriberAppService, IKafkaSubscribe public class WorkerSubscriberAppService : CollectBusAppService, IWorkerSubscriberAppService, ICapSubscribe, IKafkaSubscribe
{ {
private readonly ILogger<WorkerSubscriberAppService> _logger; private readonly ILogger<WorkerSubscriberAppService> _logger;
private readonly ITcpService _tcpService; private readonly ITcpService _tcpService;
@ -65,6 +66,7 @@ namespace JiShe.CollectBus.Subscribers
[HttpPost] [HttpPost]
[Route("ammeter/oneminute/issued-event")] [Route("ammeter/oneminute/issued-event")]
[KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerOneMinuteIssuedEventName)] [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerOneMinuteIssuedEventName)]
//[CapSubscribe(ProtocolConst.AmmeterSubscriberWorkerOneMinuteIssuedEventName)]
public async Task<ISubscribeAck> AmmeterScheduledMeterOneMinuteReadingIssuedEvent(ScheduledMeterReadingIssuedEventMessage receivedMessage) public async Task<ISubscribeAck> AmmeterScheduledMeterOneMinuteReadingIssuedEvent(ScheduledMeterReadingIssuedEventMessage receivedMessage)
{ {
_logger.LogInformation("1分钟采集电表数据下行消息消费队列开始处理"); _logger.LogInformation("1分钟采集电表数据下行消息消费队列开始处理");
@ -93,6 +95,7 @@ namespace JiShe.CollectBus.Subscribers
[HttpPost] [HttpPost]
[Route("ammeter/fiveminute/issued-event")] [Route("ammeter/fiveminute/issued-event")]
[KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerFiveMinuteIssuedEventName)] [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerFiveMinuteIssuedEventName)]
//[CapSubscribe(ProtocolConst.AmmeterSubscriberWorkerFiveMinuteIssuedEventName)]
public async Task<ISubscribeAck> AmmeterScheduledMeterFiveMinuteReadingIssuedEvent(ScheduledMeterReadingIssuedEventMessage receivedMessage) public async Task<ISubscribeAck> AmmeterScheduledMeterFiveMinuteReadingIssuedEvent(ScheduledMeterReadingIssuedEventMessage receivedMessage)
{ {
_logger.LogInformation("5分钟采集电表数据下行消息消费队列开始处理"); _logger.LogInformation("5分钟采集电表数据下行消息消费队列开始处理");
@ -121,6 +124,7 @@ namespace JiShe.CollectBus.Subscribers
[HttpPost] [HttpPost]
[Route("ammeter/fifteenminute/issued-event")] [Route("ammeter/fifteenminute/issued-event")]
[KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName)] [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName)]
//[CapSubscribe(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName)]
public async Task<ISubscribeAck> AmmeterScheduledMeterFifteenMinuteReadingIssuedEvent(ScheduledMeterReadingIssuedEventMessage receivedMessage) public async Task<ISubscribeAck> AmmeterScheduledMeterFifteenMinuteReadingIssuedEvent(ScheduledMeterReadingIssuedEventMessage receivedMessage)
{ {
_logger.LogInformation("15分钟采集电表数据下行消息消费队列开始处理"); _logger.LogInformation("15分钟采集电表数据下行消息消费队列开始处理");
@ -160,6 +164,7 @@ namespace JiShe.CollectBus.Subscribers
[HttpPost] [HttpPost]
[Route("watermeter/fifteenminute/issued-event")] [Route("watermeter/fifteenminute/issued-event")]
[KafkaSubscribe(ProtocolConst.WatermeterSubscriberWorkerAutoReadingIssuedEventName)] [KafkaSubscribe(ProtocolConst.WatermeterSubscriberWorkerAutoReadingIssuedEventName)]
//[CapSubscribe(ProtocolConst.WatermeterSubscriberWorkerAutoReadingIssuedEventName)]
public async Task<ISubscribeAck> WatermeterSubscriberWorkerAutoReadingIssuedEvent(ScheduledMeterReadingIssuedEventMessage receivedMessage) public async Task<ISubscribeAck> WatermeterSubscriberWorkerAutoReadingIssuedEvent(ScheduledMeterReadingIssuedEventMessage receivedMessage)
{ {
_logger.LogInformation("15分钟采集水表数据下行消息消费队列开始处理"); _logger.LogInformation("15分钟采集水表数据下行消息消费队列开始处理");

View File

@ -43,7 +43,7 @@ namespace JiShe.CollectBus.Host
ConfigureNetwork(context, configuration); ConfigureNetwork(context, configuration);
ConfigureJwtAuthentication(context, configuration); ConfigureJwtAuthentication(context, configuration);
ConfigureHangfire(context); ConfigureHangfire(context);
//ConfigureCap(context, configuration); ConfigureCap(context, configuration);
//ConfigureMassTransit(context, configuration); //ConfigureMassTransit(context, configuration);
//ConfigureKafkaTopic(context, configuration); //ConfigureKafkaTopic(context, configuration);
ConfigureAuditLog(context); ConfigureAuditLog(context);

View File

@ -183,6 +183,19 @@ namespace JiShe.CollectBus.Kafka.AdminClient
return partitions.Any(p => p.PartitionId == targetPartition); return partitions.Any(p => p.PartitionId == targetPartition);
} }
/// <summary>
/// 获取主题的分区数量
/// </summary>
/// <param name="topic"></param>
/// <returns></returns>
public int GetTopicPartitionsNum(string topic)
{
var metadata = Instance.GetMetadata(topic, TimeSpan.FromSeconds(10));
if (metadata.Topics.Count == 0)
return 0;
return metadata.Topics[0].Partitions.Count;
}
public void Dispose() public void Dispose()
{ {
Instance?.Dispose(); Instance?.Dispose();

View File

@ -52,5 +52,12 @@ namespace JiShe.CollectBus.Kafka.AdminClient
/// <param name="targetPartition"></param> /// <param name="targetPartition"></param>
/// <returns></returns> /// <returns></returns>
bool CheckPartitionsExist(string topic, int targetPartition); bool CheckPartitionsExist(string topic, int targetPartition);
/// <summary>
/// 获取主题的分区数量
/// </summary>
/// <param name="topic"></param>
/// <returns></returns>
int GetTopicPartitionsNum(string topic);
} }
} }

View File

@ -12,7 +12,7 @@ namespace JiShe.CollectBus.Kafka.Attributes
/// <summary> /// <summary>
/// 订阅的主题 /// 订阅的主题
/// </summary> /// </summary>
public string[] Topics { get; set; } public string Topic { get; set; }
/// <summary> /// <summary>
/// 分区 /// 分区
@ -24,28 +24,20 @@ namespace JiShe.CollectBus.Kafka.Attributes
/// </summary> /// </summary>
public string GroupId { get; set; } public string GroupId { get; set; }
public KafkaSubscribeAttribute(string[] topics, string groupId = "default") /// <summary>
{ /// 任务数(默认是多少个分区多少个任务)
this.Topics = topics; /// </summary>
this.GroupId = groupId; public int TaskCount { get; set; } = -1;
}
public KafkaSubscribeAttribute(string topic, string groupId = "default") public KafkaSubscribeAttribute(string topic, string groupId = "default")
{ {
this.Topics = new string[] { topic }; this.Topic = topic;
this.GroupId = groupId; this.GroupId = groupId;
} }
public KafkaSubscribeAttribute(string[] topics, int partition, string groupId = "default")
{
this.Topics = topics;
this.Partition = partition;
this.GroupId = groupId;
}
public KafkaSubscribeAttribute(string topic, int partition, string groupId = "default") public KafkaSubscribeAttribute(string topic, int partition, string groupId = "default")
{ {
this.Topics = new string[] { topic }; this.Topic = topic ;
this.Partition = partition; this.Partition = partition;
this.GroupId = groupId; this.GroupId = groupId;
} }

View File

@ -17,9 +17,9 @@ namespace JiShe.CollectBus.Kafka
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
// 注册Producer // 注册Producer
context.Services.AddTransient<IProducerService, ProducerService>(); context.Services.AddSingleton<IProducerService, ProducerService>();
// 注册Consumer // 注册Consumer
context.Services.AddTransient<IConsumerService, ConsumerService>(); context.Services.AddSingleton<IConsumerService, ConsumerService>();
} }
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)

View File

@ -9,6 +9,7 @@ using static Confluent.Kafka.ConfigPropertyNames;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NUglify.Html; using NUglify.Html;
using Serilog;
namespace JiShe.CollectBus.Kafka.Consumer namespace JiShe.CollectBus.Kafka.Consumer
{ {
@ -37,6 +38,7 @@ namespace JiShe.CollectBus.Kafka.Consumer
{ {
var config = BuildConsumerConfig(groupId); var config = BuildConsumerConfig(groupId);
return new ConsumerBuilder<TKey, TValue>(config) return new ConsumerBuilder<TKey, TValue>(config)
.SetLogHandler((_, log) => _logger.LogInformation($"消费者Log: {log.Message}"))
.SetErrorHandler((_, e) => _logger.LogError($"消费者错误: {e.Reason}")) .SetErrorHandler((_, e) => _logger.LogError($"消费者错误: {e.Reason}"))
.Build(); .Build();
} }
@ -50,7 +52,9 @@ namespace JiShe.CollectBus.Kafka.Consumer
BootstrapServers = _configuration["Kafka:BootstrapServers"], BootstrapServers = _configuration["Kafka:BootstrapServers"],
GroupId = groupId ?? "default", GroupId = groupId ?? "default",
AutoOffsetReset = AutoOffsetReset.Earliest, AutoOffsetReset = AutoOffsetReset.Earliest,
EnableAutoCommit = false // 禁止AutoCommit EnableAutoCommit = false, // 禁止AutoCommit
EnablePartitionEof = true, // 启用分区末尾标记
AllowAutoCreateTopics= true // 启用自动创建
}; };
if (enableAuth) if (enableAuth)
@ -119,6 +123,15 @@ namespace JiShe.CollectBus.Kafka.Consumer
try try
{ {
var result = consumer.Consume(cts.Token); var result = consumer.Consume(cts.Token);
if (result == null) continue;
if (result.Message.Value == null) continue;
if (result.IsPartitionEOF)
{
_logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition);
await Task.Delay(TimeSpan.FromSeconds(1));
continue;
}
bool sucess= await messageHandler(result.Message.Key, result.Message.Value); bool sucess= await messageHandler(result.Message.Key, result.Message.Value);
if (sucess) if (sucess)
{ {
@ -164,6 +177,15 @@ namespace JiShe.CollectBus.Kafka.Consumer
try try
{ {
var result = consumer.Consume(cts.Token); var result = consumer.Consume(cts.Token);
if (result == null) continue;
if (result.Message == null) continue;
if (result.IsPartitionEOF)
{
_logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition);
await Task.Delay(TimeSpan.FromSeconds(1));
continue;
}
bool sucess = await messageHandler(result.Message.Value); bool sucess = await messageHandler(result.Message.Value);
if (sucess) if (sucess)
consumer.Commit(result); // 手动提交 consumer.Commit(result); // 手动提交

View File

@ -2,6 +2,7 @@
using DeviceDetectorNET; using DeviceDetectorNET;
using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Helpers;
using JiShe.CollectBus.Kafka.AdminClient;
using JiShe.CollectBus.Kafka.Attributes; using JiShe.CollectBus.Kafka.Attributes;
using JiShe.CollectBus.Kafka.Consumer; using JiShe.CollectBus.Kafka.Consumer;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@ -41,6 +42,9 @@ namespace JiShe.CollectBus.Kafka
lifetime.ApplicationStarted.Register(() => lifetime.ApplicationStarted.Register(() =>
{ {
var logger = provider.GetRequiredService<ILogger<CollectBusKafkaModule>>();
int threadCount = 0;
int topicCount = 0;
foreach (var subscribeType in subscribeTypes) foreach (var subscribeType in subscribeTypes)
{ {
var subscribes = provider.GetServices(subscribeType).ToList(); var subscribes = provider.GetServices(subscribeType).ToList();
@ -48,10 +52,13 @@ namespace JiShe.CollectBus.Kafka
if(subscribe is IKafkaSubscribe) if(subscribe is IKafkaSubscribe)
{ {
BuildKafkaSubscriber(subscribe, provider); Tuple<int, int> tuple= BuildKafkaSubscriber(subscribe, provider, logger);
threadCount+= tuple.Item1;
topicCount+= tuple.Item2;
} }
}); });
} }
logger.LogInformation($"kafka订阅主题:{topicCount}数,共启动:{threadCount}线程");
}); });
} }
@ -60,16 +67,27 @@ namespace JiShe.CollectBus.Kafka
/// </summary> /// </summary>
/// <param name="subscribe"></param> /// <param name="subscribe"></param>
/// <param name="provider"></param> /// <param name="provider"></param>
private static void BuildKafkaSubscriber(object subscribe, IServiceProvider provider) private static Tuple<int,int> BuildKafkaSubscriber(object subscribe, IServiceProvider provider,ILogger<CollectBusKafkaModule> logger)
{ {
var subscribedMethods = subscribe.GetType().GetMethods() var subscribedMethods = subscribe.GetType().GetMethods()
.Select(m => new { Method = m, Attribute = m.GetCustomAttribute<KafkaSubscribeAttribute>() }) .Select(m => new { Method = m, Attribute = m.GetCustomAttribute<KafkaSubscribeAttribute>() })
.Where(x => x.Attribute != null) .Where(x => x.Attribute != null)
.ToArray(); .ToArray();
int threadCount = 0;
foreach (var sub in subscribedMethods) foreach (var sub in subscribedMethods)
{ {
Task.Run(() => StartConsumerAsync(provider, sub.Attribute!, sub.Method, subscribe)); var adminClientService = provider.GetRequiredService<IAdminClientService>();
int partitionCount = sub.Attribute!.TaskCount==-1?adminClientService.GetTopicPartitionsNum(sub.Attribute!.Topic) : sub.Attribute!.TaskCount;
if (partitionCount <= 0)
partitionCount = 1;
for (int i = 0; i < partitionCount; i++)
{
Task.Run(() => StartConsumerAsync(provider, sub.Attribute!, sub.Method, subscribe, logger));
threadCount++;
}
} }
return Tuple.Create(threadCount, subscribedMethods.Length);
} }
/// <summary> /// <summary>
@ -80,11 +98,11 @@ namespace JiShe.CollectBus.Kafka
/// <param name="method"></param> /// <param name="method"></param>
/// <param name="consumerInstance"></param> /// <param name="consumerInstance"></param>
/// <returns></returns> /// <returns></returns>
private static async Task StartConsumerAsync(IServiceProvider provider, KafkaSubscribeAttribute attr,MethodInfo method, object subscribe) private static async Task StartConsumerAsync(IServiceProvider provider, KafkaSubscribeAttribute attr,MethodInfo method, object subscribe, ILogger<CollectBusKafkaModule> logger)
{ {
var consumerService = provider.GetRequiredService<IConsumerService>(); var consumerService = provider.GetRequiredService<IConsumerService>();
var logger = provider.GetRequiredService<ILogger<CollectBusKafkaModule>>();
await consumerService.SubscribeAsync<string>(attr.Topics, async (message) => await consumerService.SubscribeAsync<string>(attr.Topic, async (message) =>
{ {
try try
{ {

View File

@ -15,6 +15,6 @@ namespace JiShe.CollectBus.Kafka.Producer
Task ProduceAsync<TKey, TValue>(string topic, TKey key, TValue value, int? partition, Action<DeliveryReport<TKey, TValue>>? deliveryHandler = null) where TKey : notnull where TValue : class; Task ProduceAsync<TKey, TValue>(string topic, TKey key, TValue value, int? partition, Action<DeliveryReport<TKey, TValue>>? deliveryHandler = null) where TKey : notnull where TValue : class;
Task ProduceAsync<TValue>(string topic, TValue value, int? partition = null, Action<DeliveryReport<Ignore, TValue>>? deliveryHandler = null) where TValue : class; Task ProduceAsync<TValue>(string topic, TValue value, int? partition = null, Action<DeliveryReport<string, TValue>>? deliveryHandler = null) where TValue : class;
} }
} }

View File

@ -9,6 +9,7 @@ using JiShe.CollectBus.Kafka.Consumer;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using YamlDotNet.Serialization;
namespace JiShe.CollectBus.Kafka.Producer namespace JiShe.CollectBus.Kafka.Producer
{ {
@ -62,6 +63,7 @@ namespace JiShe.CollectBus.Kafka.Producer
LingerMs = 20, // 修改等待时间为20ms LingerMs = 20, // 修改等待时间为20ms
Acks = Acks.All, // 表明只有所有副本Broker都收到消息才算提交成功, 可以 Acks.Leader Acks = Acks.All, // 表明只有所有副本Broker都收到消息才算提交成功, 可以 Acks.Leader
MessageSendMaxRetries = 50, // 消息发送失败最大重试50次 MessageSendMaxRetries = 50, // 消息发送失败最大重试50次
MessageTimeoutMs = 120000, // 消息发送超时时间为2分钟,设置值MessageTimeoutMs > LingerMs
}; };
if (enableAuth) if (enableAuth)
@ -114,8 +116,8 @@ namespace JiShe.CollectBus.Kafka.Producer
/// <returns></returns> /// <returns></returns>
public async Task ProduceAsync<TValue>(string topic, TValue value) where TValue : class public async Task ProduceAsync<TValue>(string topic, TValue value) where TValue : class
{ {
var producer = GetProducer<Ignore, TValue>(); var producer = GetProducer<string, TValue>();
await producer.ProduceAsync(topic, new Message<Ignore, TValue> { Value = value }); await producer.ProduceAsync(topic, new Message<string, TValue> { Value = value });
} }
/// <summary> /// <summary>
@ -160,13 +162,13 @@ namespace JiShe.CollectBus.Kafka.Producer
/// <param name="partition"></param> /// <param name="partition"></param>
/// <param name="deliveryHandler"></param> /// <param name="deliveryHandler"></param>
/// <returns></returns> /// <returns></returns>
public async Task ProduceAsync<TValue>(string topic, TValue value, int? partition=null, Action<DeliveryReport<Ignore, TValue>>? deliveryHandler = null) where TValue : class public async Task ProduceAsync<TValue>(string topic, TValue value, int? partition=null, Action<DeliveryReport<string, TValue>>? deliveryHandler = null) where TValue : class
{ {
var message = new Message<Ignore, TValue> var message = new Message<string, TValue>
{ {
Value = value Value = value
}; };
var producer = GetProducer<Ignore, TValue>(); var producer = GetProducer<string, TValue>();
if (partition.HasValue) if (partition.HasValue)
{ {
var topicPartition = new TopicPartition(topic, partition.Value); var topicPartition = new TopicPartition(topic, partition.Value);

View File

@ -13,11 +13,13 @@ using JiShe.CollectBus.IotSystems.Protocols;
using MassTransit; using MassTransit;
using JiShe.CollectBus.Kafka.Producer; using JiShe.CollectBus.Kafka.Producer;
using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Helpers;
using DotNetCore.CAP;
namespace JiShe.CollectBus.Protocol.Contracts.Abstracts namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
{ {
public abstract class BaseProtocolPlugin : IProtocolPlugin public abstract class BaseProtocolPlugin : IProtocolPlugin
{ {
private readonly ICapPublisher _producerBus;
private readonly IProducerService _producerService; private readonly IProducerService _producerService;
private readonly ILogger<BaseProtocolPlugin> _logger; private readonly ILogger<BaseProtocolPlugin> _logger;
private readonly IRepository<ProtocolInfo, Guid> _protocolInfoRepository; private readonly IRepository<ProtocolInfo, Guid> _protocolInfoRepository;
@ -38,7 +40,8 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
_logger = serviceProvider.GetRequiredService<ILogger<BaseProtocolPlugin>>(); _logger = serviceProvider.GetRequiredService<ILogger<BaseProtocolPlugin>>();
_protocolInfoRepository = serviceProvider.GetRequiredService<IRepository<ProtocolInfo, Guid>>(); _protocolInfoRepository = serviceProvider.GetRequiredService<IRepository<ProtocolInfo, Guid>>();
_producerService = serviceProvider.GetRequiredService<IProducerService>(); _producerService = serviceProvider.GetRequiredService<IProducerService>();
_producerBus = serviceProvider.GetRequiredService<ICapPublisher>();
} }
public abstract ProtocolInfo Info { get; } public abstract ProtocolInfo Info { get; }
@ -87,6 +90,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
Fn = 1 Fn = 1
}; };
var bytes = Build3761SendData.BuildSendCommandBytes(reqParam); var bytes = Build3761SendData.BuildSendCommandBytes(reqParam);
//await _producerBus.PublishAsync(ProtocolConst.SubscriberLoginIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId });
await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId }.Serialize()); await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId }.Serialize());
//await _producerBus.Publish(new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId }); //await _producerBus.Publish(new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId });
@ -127,6 +131,8 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
Fn = 1 Fn = 1
}; };
var bytes = Build3761SendData.BuildSendCommandBytes(reqParam); var bytes = Build3761SendData.BuildSendCommandBytes(reqParam);
//await _producerBus.PublishAsync(ProtocolConst.SubscriberHeartbeatIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Heartbeat, MessageId = messageReceived.MessageId });
await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Heartbeat, MessageId = messageReceived.MessageId }.Serialize()); await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Heartbeat, MessageId = messageReceived.MessageId }.Serialize());
//await _producerBus.Publish(new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Heartbeat, MessageId = messageReceived.MessageId }); //await _producerBus.Publish(new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Heartbeat, MessageId = messageReceived.MessageId });

View File

@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Confluent.Kafka" Version="2.9.0" /> <PackageReference Include="Confluent.Kafka" Version="2.9.0" />
<PackageReference Include="DotNetCore.CAP" Version="8.3.1" />
<PackageReference Include="MassTransit.Abstractions" Version="8.3.0" /> <PackageReference Include="MassTransit.Abstractions" Version="8.3.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
<PackageReference Include="TouchSocket" Version="2.1.9" /> <PackageReference Include="TouchSocket" Version="2.1.9" />