diff --git a/langguanApi.xml b/langguanApi.xml index 8aa625d..6c80353 100644 --- a/langguanApi.xml +++ b/langguanApi.xml @@ -125,6 +125,13 @@ 缓存清洁数据 + + + redis缓存key + + + + redis 服务地址 @@ -183,6 +190,44 @@ 需要解密的字符串 解密后的字符串 + + + 客户端push消息 + + + + + 全部消息 + + + + + + + socket + + + + + // 客户端连接事件 + + + + + + // 自定义方法,用于向客户端推送消息 + + + + + + + 向指定用户发送 + + + + + export data 默认最近7天数据 @@ -1295,6 +1340,21 @@ deviceValue + + + //GPS历史信息 + + + + + 批次ID + + + + + GPSDTO + + 台账 @@ -2963,6 +3023,31 @@ + + + 新加gps历史记录 + + + + + + + 缓冲器 + + + + + 启动GPS服务 + + + + + + 发送GPS数据 + + + + 首页数据 diff --git a/langguanApi/Common/Redis/RedisKeylist.cs b/langguanApi/Common/Redis/RedisKeylist.cs index 8fbf7a8..d7fe243 100644 --- a/langguanApi/Common/Redis/RedisKeylist.cs +++ b/langguanApi/Common/Redis/RedisKeylist.cs @@ -23,5 +23,14 @@ /// 缓存清洁数据 /// public static string CleanData = "cleandata"; + /// + /// redis缓存key + /// + /// + /// + public static string GetBatchid(string key) + { + return $"batchtid_{key}"; + } } } diff --git a/langguanApi/Common/WebSocket/PushService.cs b/langguanApi/Common/WebSocket/PushService.cs new file mode 100644 index 0000000..63c36aa --- /dev/null +++ b/langguanApi/Common/WebSocket/PushService.cs @@ -0,0 +1,31 @@ +using langguanApi.Extensions.AutoDI; +using Microsoft.AspNetCore.SignalR; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json; + +namespace langguanApi.Common.WebSocket +{ + /// + /// 客户端push消息 + /// + [ServiceInjection(InjectionType.Singleton)] + public class PushService + { + private readonly IHubContext _hubContext; + /// + /// 全部消息 + /// + /// + /// + public async Task SendMessageToAll(object message) + { + var settings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + Console.WriteLine($"gps:{JsonConvert.SerializeObject(message, settings)}"); + var data = JsonConvert.SerializeObject(message, settings); + await _hubContext.Clients.All.SendAsync("ReceiveMessage", data); + } + } +} diff --git a/langguanApi/Common/WebSocket/SocketHub.cs b/langguanApi/Common/WebSocket/SocketHub.cs new file mode 100644 index 0000000..a564535 --- /dev/null +++ b/langguanApi/Common/WebSocket/SocketHub.cs @@ -0,0 +1,53 @@ +using Microsoft.AspNetCore.SignalR; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json; +using langguanApi.Extensions.AutoDI; + +namespace langguanApi.Common.WebSocket +{ + /// + /// socket + /// + [ServiceInjection(InjectionType.Singleton)] + public class SocketHub : Hub + { + /// + /// // 客户端连接事件 + /// + /// + public override async Task OnConnectedAsync() + { + var msg = JsonConvert.SerializeObject(new { msgType = "info", data = "hello" }); + // 发送消息给连接的客户端 + await Clients.Caller.SendAsync("ReceiveMessage", msg); + await base.OnConnectedAsync(); + } + /// + /// // 自定义方法,用于向客户端推送消息 + /// + /// + /// + public async Task SendMessageToClient(object message) + { + // 发送消息给所有客户端 + var connId = this.Context.ConnectionId; + var msg = JsonConvert.SerializeObject(message); + await this.Clients.All.SendAsync("ReceiveMessage", msg); + } + /// + /// 向指定用户发送 + /// + /// + /// + /// + public async Task SendMessageToUser(string user, object message) + { + var settings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + var msg = JsonConvert.SerializeObject(message, settings); + await Clients.All.SendAsync("ReceiveMessage", user, msg); + } + } +} diff --git a/langguanApi/Extensions/SocketExtension.cs b/langguanApi/Extensions/SocketExtension.cs index b48eda5..311ef8c 100644 --- a/langguanApi/Extensions/SocketExtension.cs +++ b/langguanApi/Extensions/SocketExtension.cs @@ -12,12 +12,12 @@ namespace langguanApi.Extensions { // services.AddSingleton(); services.AddTransient(); - services.AddSingleton(); // 808协议 + services.AddSingleton(); // gps协议 services.AddTransient(); IServiceProvider serviceProvider = services.BuildServiceProvider(); _ = serviceProvider.GetService().Start(); - _ = serviceProvider.GetService().Start(); + _ = serviceProvider.GetService().Start(); serviceProvider.GetService().CreatTask(); } } diff --git a/langguanApi/Model/Entity/GpsHistory.cs b/langguanApi/Model/Entity/GpsHistory.cs new file mode 100644 index 0000000..716aa55 --- /dev/null +++ b/langguanApi/Model/Entity/GpsHistory.cs @@ -0,0 +1,25 @@ +namespace langguanApi.Model.Entity +{ + /// + /// //GPS历史信息 + /// + public class GpsHistory : BaseModel + { + public string DeviceId { get; set; } + public string Lat { get; set; } + public string Lon { get; set; } + /// + /// 批次ID + /// + public long BatchId { get; set; } + } + /// + /// GPSDTO + /// + public class GpsHistoryDTO + { + public string DeviceId { get; set; } + public string Lat { get; set; } + public string Lon { get; set; } + } +} diff --git a/langguanApi/Program.cs b/langguanApi/Program.cs index fcec32e..3a236dd 100644 --- a/langguanApi/Program.cs +++ b/langguanApi/Program.cs @@ -93,17 +93,17 @@ app.UseCors("CorsPolicy"); app.MapControllers(); - -app.Run(); - - if (!await GetNowTimeAsync()) { Console.WriteLine("ǰʱ䲻ڿʱ䷶ΧڣϵӦ̡"); Environment.Exit(0); } -/// -/// ȡǰʱǷڿʱ䷶Χ +app.Run(); + + + + +//ȡǰʱǷڿʱ䷶Χ static async Task GetNowTimeAsync() { try @@ -111,14 +111,11 @@ static async Task GetNowTimeAsync() DateTime startTime = DateTime.Parse("2024-09-01"); //ӹϻȡǰʱ var url = "http://www.worldtimeapi.org/api/ip"; - var request = WebRequest.Create(url); - var response = await request.GetResponseAsync(); - var stream = response.GetResponseStream(); - var reader = new StreamReader(stream); - var content = reader.ReadToEnd(); - var time = JObject.Parse(content)["datetime"].ToString(); + var myClient = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }); + var response = await myClient.GetStringAsync(url); + var time = JObject.Parse(response)["datetime"].ToString(); var now = DateTime.Parse(time); - Console.WriteLine($"ǰʱ䣺{now}ʱ䣺{startTime.AddDays(365)}ʱ仹У{(startTime.AddDays(30) - now).Days} "); + Console.WriteLine($"ǰʱ䣺{now}ʱ䣺{startTime.AddDays(365)}ʱ仹У{(startTime.AddDays(365) - now).Days} "); return startTime.AddDays(365) > now ? true : false; } catch diff --git a/langguanApi/Service/GpsHistoryService.cs b/langguanApi/Service/GpsHistoryService.cs new file mode 100644 index 0000000..77315b5 --- /dev/null +++ b/langguanApi/Service/GpsHistoryService.cs @@ -0,0 +1,55 @@ +using langguanApi.Common.Redis; +using langguanApi.Common.WebSocket; +using langguanApi.Extensions.AutoDI; +using langguanApi.Model.Entity; +using Mapster; +using StackExchange.Redis; + +namespace langguanApi.Service +{ + [ServiceInjection(InjectionType.Transient)] + public class GpsHistoryService : BaseService + { + private readonly PushService _pushService; + private IDatabase _redis; + private IConfiguration _config; + public GpsHistoryService(IConfiguration config, PushService pushService, + RedisHelper redisHelper) : base(config, nameof(Model.Entity.GpsHistory)) + { + _pushService = pushService; + _redis = redisHelper._database; + _config = config; + } + /// + /// 新加gps历史记录 + /// + /// + /// + public async Task AddGpsHistory(GpsHistoryDTO input) + { + var entity = input.Adapt(); + var redisKey = RedisKeylist.GetBatchid(entity.DeviceId); + ///如果redis中不存在该设备的批次号,则生成一个批次号 + if (!await _redis.KeyExistsAsync(redisKey)) + { + int time = _config.GetValue("BatchId"); + long utc = DateTime.UtcNow.Ticks; + await _redis.StringSetAsync(redisKey, utc, TimeSpan.FromMinutes(time)); + } + else + { + //如果存在了,就把批次号延期30分钟 + await _redis.KeyExpireAsync(redisKey, TimeSpan.FromMinutes(30)); + } + entity.BatchId = (long)await _redis.StringGetAsync(redisKey); + await base.CreateAsync(entity); + await _pushService.SendMessageToAll(new + { + entity.Lat, + entity.DeviceId, + entity.Lon, + entity.BatchId + }); + } + } +} diff --git a/langguanApi/Service/GpsService.cs b/langguanApi/Service/GpsService.cs new file mode 100644 index 0000000..93882cf --- /dev/null +++ b/langguanApi/Service/GpsService.cs @@ -0,0 +1,53 @@ +using langguanApi.Model.Entity; +using MongoDB.Bson.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace langguanApi.Service +{ + + public class GpsService + { + private GpsHistoryService _service = ServiceLocator.Instance.GetService(); + /// + /// 缓冲器 + /// + private byte[] result = new byte[1024]; + private int port => 5002; + /// + /// 启动GPS服务 + /// + /// + public async Task Start() + { + // 创建本地IP地址和TCP端口号 + var ipEndPoint = new IPEndPoint(IPAddress.Any, port); + TcpListener listener = new(ipEndPoint); + try + { + listener.Start(); + Console.WriteLine($"Waiting for gps connection... port:{port}"); + using TcpClient handler = await listener.AcceptTcpClientAsync(); + await using NetworkStream stream = handler.GetStream(); + int received = await stream.ReadAsync(result); + var message = Encoding.UTF8.GetString(result, 0, received); + Console.WriteLine($"GPS received: \"{message}\""); + } + catch (Exception ex) + { + Console.WriteLine($"GPS error:{ex.Message}"); + } + } + /// + /// 发送GPS数据 + /// + /// + /// + public async Task Send(string message) + { + var json = Newtonsoft.Json.JsonConvert.DeserializeObject(message); + await _service.AddGpsHistory(json); + } + } +} diff --git a/langguanApi/appsettings.json b/langguanApi/appsettings.json index d9e74dd..1dfb0bc 100644 --- a/langguanApi/appsettings.json +++ b/langguanApi/appsettings.json @@ -30,5 +30,6 @@ "lat": 39.4716613, "lon": 107.1413332 } - } + }, + "BatchId": 30 //批次号间隔时间30分钟 } diff --git a/langguanApi/langguanApi.csproj b/langguanApi/langguanApi.csproj index c705e9f..6151fae 100644 --- a/langguanApi/langguanApi.csproj +++ b/langguanApi/langguanApi.csproj @@ -19,6 +19,7 @@ +