using Application.Domain.Entities; using Application.Models; using Infrastructure.Data; using Infrastructure.Extensions; using Microsoft.AspNetCore.SignalR.Client; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; namespace IoT.Shared.Infrastructure { public class ClientService : BaseClientService { public ClientService(IServiceProvider applicationServices, IConfiguration configuration) : base(applicationServices, configuration) { } public override void OnConnected() { Console.WriteLine($"{_notifyHost} OnConnected"); using (var scope = this.applicationServices.CreateScope()) { //同步Node var nodeRepo = scope.ServiceProvider.GetService>(); var nodeDto = nodeRepo.ReadOnlyTable().FirstOrDefault().To(); this.SendToServer(Methods.EditNodeResponse, nodeDto); //同步Product var productRepo = scope.ServiceProvider.GetService>(); var products = productRepo.ReadOnlyTable() .Include(o => o.Category) .ToList(); foreach (var product in products) { var productDto = product.To(); productDto.CategoryNumber = product.Category.Number; this.SendToServer(Methods.EditProductResponse, productDto); } //同步设备及其数据 var deviceRepo = scope.ServiceProvider.GetService>(); var devices = deviceRepo.ReadOnlyTable() .Include(o => o.Product) .Include(o => o.Node) .Include(o => o.Data).ToList(); foreach (var device in devices) { var deviceDto = device.To(); deviceDto.ProductNumber = device.Product.Number; deviceDto.NodeNumber = device.Node.Number; this.SendToServer(Methods.EditDeviceResponse, deviceDto); var dataDtoList = new List(); foreach (var deviceData in device.Data.Where(o => !o.Hidden)) { var dataDto = deviceData.To(); dataDto.DeviceNumber = device.Number; dataDtoList.Add(dataDto); } this.SendToServer(Methods.EditDataResponse, dataDtoList); } //同步场景 var sceneRepo = scope.ServiceProvider.GetService>(); var scenes = sceneRepo.ReadOnlyTable().Include(o => o.Node).ToList(); foreach (var scene in scenes) { var sceneDto = scene.To(); sceneDto.NodeNumber = scene.Node.Number; this.SendToServer(Methods.EditSceneResponse, sceneDto); } } } public override void OnServerToClient(string method, string message, string fromConnectionId) { using (var scope = this.applicationServices.CreateScope()) { if (method == Methods.HealthCheckRequest) { this.ClientToServer(Methods.HealthCheckResponse, this._cfg["sn"]); } else if (method == Methods.GetProductRequest) { var productNumber = message; var productRepo = scope.ServiceProvider.GetService>(); var product = productRepo.ReadOnlyTable().Include(o => o.Category).FirstOrDefault(o => o.Number == productNumber); if (product == null) { throw new Exception($"not has infoNumber:{productNumber}"); } var model = product.To(); model.CategoryNumber = product.Category.Number; this.SendToServer(Methods.EditProductResponse, model); } else if (method == Methods.CallApi) { var cfg = scope.ServiceProvider.GetService(); var port = cfg["server.urls"].Split(':')[2]; var url = $"http://localhost:{port}{message}"; var httpClient = scope.ServiceProvider.GetService().CreateClient(); var result = httpClient.GetStringAsync(url).Result; this.Connection.SendAsync(Methods.ClientToServer, Methods.ApiCallback, result, cfg["sn"]); } else if (method == Methods.CallScene) { var commandRepo = scope.ServiceProvider.GetService>(); var commands = commandRepo.ReadOnlyTable() .Include(o => o.Api) .Include(o => o.Device) .Where(o => o.Scene.Name == message) .ToList(); foreach (var command in commands) { try { var cfg = scope.ServiceProvider.GetService(); var port = cfg["server.urls"].Split(':')[2]; var url = $"http://localhost:{port}{command.Api.Path}{command.Api.Command}?number={command.Device.Number}{(string.IsNullOrEmpty(command.QueryString) ? "" : "&")}{command.QueryString}"; var httpClient = scope.ServiceProvider.GetService().CreateClient(); var result = httpClient.GetStringAsync(url).Result; } catch (Exception ex) { ex.PrintStack(); } } } else if (method == Methods.EditNodeRequest) { var model = message.FromJson(); var nodeRepo = scope.ServiceProvider.GetService>(); var node = nodeRepo.Table().FirstOrDefault(o => o.Number == model.Number); if (node != null) { node.FromDto(model); nodeRepo.SaveChanges(); this.ClientToServer(Methods.EditNodeResponse, message); } } else if (method == Methods.EditDeviceRequest) { var model = message.FromJson(); var deviceRepo = scope.ServiceProvider.GetService>(); var device = deviceRepo.Table().FirstOrDefault(o => o.Number == model.Number); if (device != null) { device.FromDto(model); deviceRepo.SaveChanges(); this.ClientToServer(Methods.EditDeviceResponse, message); } } else if (method == Methods.DeleteDeviceRequest) { var deviceRepo = scope.ServiceProvider.GetService>(); var model = message.FromJson(); var device = deviceRepo.Table().FirstOrDefault(o => o.Number == model.Number); if (device != null) { deviceRepo.Delete(device); deviceRepo.SaveChanges(); this.ClientToServer(Methods.DeleteDeviceResponse, message); } } else if (method == Methods.EditDataRequest) { var model = message.FromJson(); var dataRepo = scope.ServiceProvider.GetService>(); var data = dataRepo.Table().FirstOrDefault(o => o.Device.Number == model.DeviceNumber && o.Key == model.Key); if (data != null) { data.FromDto(model); dataRepo.SaveChanges(); this.ClientToServer(Methods.EditDataResponse, new List() { model }.ToJson()); } } else if (method == Methods.DeleteDataRequest) { var model = message.FromJson(); var dataRepo = scope.ServiceProvider.GetService>(); var data = dataRepo.Table().FirstOrDefault(o => o.Device.Number == model.DeviceNumber && o.Key == model.Key); if (data != null) { dataRepo.Delete(data); dataRepo.SaveChanges(); this.ClientToServer(Methods.DeleteDataResponse, message); } } else if (method == Methods.EditSceneRequest) { var model = message.FromJson(); var nodeRepo = scope.ServiceProvider.GetService>(); var sceneRepo = scope.ServiceProvider.GetService>(); var scene = sceneRepo.Table().FirstOrDefault(o => o.Node.Number == model.NodeNumber && o.Name == model.Name); if (scene == null) { scene = new Scene(); scene.NodeId = nodeRepo.ReadOnlyTable().FirstOrDefault(o => o.Number == model.NodeNumber).Id; sceneRepo.Add(scene); } scene.FromDto(model); sceneRepo.SaveChanges(); this.ClientToServer(Methods.EditSceneResponse, message); } else if (method == Methods.DeleteSceneRequest) { var model = message.FromJson(); var sceneRepo = scope.ServiceProvider.GetService>(); var scene = sceneRepo.Table().FirstOrDefault(o => o.Node.Number == model.NodeNumber && o.Name == model.Name); if (scene != null) { sceneRepo.Delete(scene); sceneRepo.SaveChanges(); this.ClientToServer(Methods.DeleteSceneResponse, message); } } else if (method == Methods.EditCommandRequest) { var model = message.FromJson(); var commandRepo = scope.ServiceProvider.GetService>(); var sceneRepo = scope.ServiceProvider.GetService>(); var apiRepo = scope.ServiceProvider.GetService>(); var deviceRepo = scope.ServiceProvider.GetService>(); var device = deviceRepo.ReadOnlyTable().FirstOrDefault(o => o.Number == model.DeviceNumber); var command = commandRepo.Table() .Where(o => o.Device.Number == model.DeviceNumber) .Where(o => o.Api.ProductId == device.ProductId && o.Api.Name == model.ApiName) .Where(o => o.QueryString == model.QueryString) .FirstOrDefault(); if (command == null) { command = new Command(); command.SceneId = sceneRepo.ReadOnlyTable().FirstOrDefault(o => o.Name == model.SceneName).Id; command.DeviceId = device.Id; command.ApiId = apiRepo.ReadOnlyTable().Where(o => o.ProductId == device.ProductId && o.Name == model.ApiName).FirstOrDefault().Id; commandRepo.Add(command); } command.FromDto(model); commandRepo.SaveChanges(); this.ClientToServer(Methods.EditCommandResponse, message); } else if (method == Methods.DeleteCommandRequest) { var model = message.FromJson(); var commandRepo = scope.ServiceProvider.GetService>(); var deviceRepo = scope.ServiceProvider.GetService>(); var device = deviceRepo.ReadOnlyTable().FirstOrDefault(o => o.Number == model.DeviceNumber); var command = commandRepo.Table() .Where(o => o.Device.Number == model.DeviceNumber) .Where(o => o.Api.ProductId == device.ProductId && o.Api.Name == model.ApiName) .Where(o => o.QueryString == model.QueryString) .FirstOrDefault(); if (command != null) { commandRepo.Delete(command); commandRepo.SaveChanges(); this.ClientToServer(Methods.DeleteCommandResponse, message); } } } } public void SendToServer(string method, object data) { Task.Run(() => { try { Console.WriteLine($"send node to server {_notifyHost}"); this.ClientToServer(method, data.ToJson()); } catch (Exception ex) { ex.PrintStack(); } }); } } }