CrazyIter_Bin před 5 měsíci
rodič
revize
f6313d1d20

+ 3 - 3
TEAMModelBI/TEAMModelBI.csproj

@@ -65,9 +65,9 @@
 		<SpaRoot>ClientApp\</SpaRoot>
 		<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
 		<UserSecretsId>078b5d89-7d90-4f6a-88fc-7d96025990a8</UserSecretsId>
-		<Version>5.2501.1</Version>
-		<AssemblyVersion>5.2501.1.1</AssemblyVersion>
-		<FileVersion>5.2501.1.1</FileVersion>
+		<Version>5.2501.8</Version>
+		<AssemblyVersion>5.2501.8.1</AssemblyVersion>
+		<FileVersion>5.2501.8.1</FileVersion>
 		<Description>TEAMModelBI(BI)</Description>
 		<PackageReleaseNotes>BI版本说明版本切换标记2022000908</PackageReleaseNotes>
 		<PackageId>TEAMModelBI</PackageId>

+ 1 - 1
TEAMModelOS.Extension/HTEX.Complex/Services/SignalRScreenServerHub.cs

@@ -65,7 +65,7 @@ namespace HTEX.Complex.Services
                     };
                     await _azureRedis.GetRedisClient(8).HashSetAsync($"SignalRClient:connects:{serverDevice.deviceId}", connid, client.ToJsonString());
                     ScreenClient device = HttpUtility.UrlDecode(_device, Encoding.Unicode).ToObject<ScreenClient>();
-                    switch (true) 
+                    switch (true)  
                     {
                         case bool when grant_type.Equals(ScreenConstant.grant_type):
                             ScreenClient screenClient ;

+ 14 - 3
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Controllers/ManageController.cs

@@ -1,5 +1,6 @@
 using IES.ExamLib.Models;
 using IES.ExamServer.DI;
+using IES.ExamServer.DI.SignalRHost;
 using IES.ExamServer.Filters;
 using IES.ExamServer.Helper;
 using IES.ExamServer.Models;
@@ -23,8 +24,12 @@ namespace IES.ExamServer.Controllers
         private readonly ILogger<ManageController> _logger;
         private readonly LiteDBFactory _liteDBFactory;
         private readonly DataCenterConnectionService _connectionService;
-       
-        public ManageController(LiteDBFactory liteDBFactory,ILogger<ManageController> logger, IConfiguration configuration, IHttpClientFactory httpClientFactory, IMemoryCache memoryCache, DataCenterConnectionService connectionService)
+        private readonly int DelayMicro = 10;//微观数据延迟
+        private readonly int DelayMacro = 100;//宏观数据延迟
+
+        private readonly SignalRExamServerHub _signalRExamServerHub;
+        public ManageController(LiteDBFactory liteDBFactory,ILogger<ManageController> logger, IConfiguration configuration,
+            IHttpClientFactory httpClientFactory, IMemoryCache memoryCache, DataCenterConnectionService connectionService,SignalRExamServerHub signalRExamServerHub)
         {
             _logger = logger;
             _configuration=configuration;
@@ -32,6 +37,7 @@ namespace IES.ExamServer.Controllers
             _memoryCache=memoryCache;
             _liteDBFactory=liteDBFactory;
             _connectionService=connectionService;
+            _signalRExamServerHub=signalRExamServerHub;
         }
         [HttpPost("download-package")]
         [AuthToken("admin","teacher")]
@@ -40,7 +46,8 @@ namespace IES.ExamServer.Controllers
             
             //C#.NET 6 后端与前端流式通信
             //https://www.doubao.com/chat/collection/687687510791426?type=Thread
-            //下载日志记录:1.步骤,检查,2.获取描述信息,3.分类型,4下载文件,5.前端处理,6.返回结果 , 正在下载...==> https://www.doubao.com/chat/collection/687687510791426?type=Thread  Ok...
+            //下载日志记录:1.步骤,检查,2.获取描述信息,3.分类型,4下载文件,5.前端处理,6.返回结果 , 正在下载...==> [INFO]https://www.doubao.com/chat/collection/687687510791426?type=Thread [Size=180kb] Ok...
+            //进度条 展示下载文件总大小和已下载,末尾展示 文件总个数和已下载个数
             return Ok();
         }
         [HttpPost("check-short-code")]
@@ -161,18 +168,22 @@ namespace IES.ExamServer.Controllers
                 if (!Directory.Exists(packagePath))
                     Directory.CreateDirectory(packagePath);
                 string evaluationPath = Path.Combine(packagePath, evaluationLocal.id!);
+                await Task.Delay(DelayMacro);
                 if (!System.IO.File.Exists(Path.Combine(evaluationPath, "evaluation.json")))
                 {
                     file_intact.Add(0);
                 }
+                await Task.Delay(DelayMacro);
                 if (!System.IO.File.Exists(Path.Combine(evaluationPath, "groupList.json")))
                 {
                     file_intact.Add(0);
                 }
+                await Task.Delay(DelayMacro);
                 if (!System.IO.File.Exists(Path.Combine(evaluationPath, "source.json")))
                 {
                     file_intact.Add(0);
                 }
+                await Task.Delay(DelayMacro);
             }
 
             return Ok(new {code=200, evaluation= evaluationLocal,data,blob,webview,dataSize,blobSize,webviewSize,status });

+ 111 - 48
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/DI/SignalRHost/SignalRExamServerHub.cs

@@ -1,5 +1,11 @@
-using Microsoft.AspNetCore.SignalR;
+using IES.ExamServer.Helper;
+using IES.ExamServer.Models;
+using IES.ExamServer.Services;
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.Extensions.Caching.Memory;
 using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Primitives;
+using System.Text.Json;
 
 
 namespace IES.ExamServer.DI.SignalRHost
@@ -7,62 +13,119 @@ namespace IES.ExamServer.DI.SignalRHost
     public  class SignalRExamServerHub : Hub<IClient>
     {
         private readonly ILogger<SignalRExamServerHub> _logger;
+        private readonly IMemoryCache _memoryCache;
       
-        public SignalRExamServerHub(ILogger<SignalRExamServerHub> logger)
+        public SignalRExamServerHub(ILogger<SignalRExamServerHub> logger,IMemoryCache memoryCache)
         {
             _logger = logger;
-           
+            _memoryCache = memoryCache;
         }
-    }
-    public interface IClient
-    {
-        Task ReceiveMessage(MessageBody message);
-        Task ReceiveConnection(MessageBody message);
-        Task ReceiveDisConnection(MessageBody message);
-    }
-    public abstract class MessageBody
-    {
-        public MessageBody()
+
+        // <summary>
+        /// 这需要继承Hub来创建中心,并向中心添加方法,客户端可以调用标识符为public的方法
+        /// </summary>
+        /// <param name="user"></param>
+        /// <param name="message"></param>
+        /// <returns></returns>
+
+        public async Task SendMessage(string clientId, string grant_type, MessageContent content )
         {
-            time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+            SignalRClient  client = _memoryCache.Get<SignalRClient>($"{Constant._KeySignalRClientClients}:{clientId}");  
+            if (client != null)
+            {
+                switch (true)
+                {
+                    case bool when grant_type.Equals(Constant._Message_grant_type_check_file):
+                        {
+                            await Clients.Client(client.connid!).ReceiveMessage(new CheckFileMessageBody
+                            {
+                                content = content.content,
+                                status = content.status,
+                                clientid = clientId,
+                                connid = client.connid,
+                                grant_type = grant_type,
+                                time = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
+                                type = Constant._Message_grant_type_check_file,
+                            });
+                            break;
+                        }
+                    default:
+                        break;
+                }
+            }
         }
+
         /// <summary>
-        /// 连接id
-        /// </summary>
-        public virtual string? connid { get; set; }
-        /// <summary>
-        /// 客户端id
-        /// </summary>
-        public virtual string? clientid { get; set; }
-        /// <summary>
-        /// 状态  busy 忙碌,free 空闲,down 离线,error 错误
-        /// </summary>
-        public virtual string? status { get; set; }
-        /// <summary>
-        /// 消息内容
-        /// </summary>
-        public virtual string? content { get; set; }
-        /// <summary>
-        /// 消息创建时间
-        /// </summary>
-        public virtual long time { get; }
-        /// <summary>
-        /// 授权类型,bookjs_api 
-        /// </summary>
-        public virtual string? grant_type { get; set; }
-        /// <summary>
-        /// 消息类型
+        /// 客户连接成功时触发
         /// </summary>
-        public virtual MessageType message_type { get; set; }
-
+        /// <returns></returns>
+        public override async Task OnConnectedAsync() 
+        {
+            ServerDevice device = _memoryCache.Get<ServerDevice>(Constant._KeyServerDevice);
+            var connid = Context.ConnectionId;
+            var httpContext = Context.GetHttpContext();
+            if (httpContext != null) 
+            {
+                //wss://www.winteach.cn/signalr/notify?grant_type=wechat_qrcode&scene=0a75aca57536490ba00fe62e27bb8f6c&id=U2MNiCFNPPuVcw2gUI_gRA
+                //wss://www.winteach.cn/signalr/notify?grant_type=bookjs_api&clientid={clientid}&id=客户端自动生成的
+                httpContext.Request.Query.TryGetValue("grant_type", out StringValues grant_type);
+                httpContext.Request.Query.TryGetValue("clientid", out StringValues clientid);
+                await Groups.AddToGroupAsync(connid, grant_type!);
+                if (!clientid.Equals(StringValues.Empty) && !grant_type.Equals(StringValues.Empty)) 
+                {
+                    var client = new SignalRClient
+                    {
+                        connid = connid,
+                        grant_type = grant_type,
+                        clientid= clientid,//浏览器生成的客户端设备id
+                        serverid=device.deviceId,//服务器设备id
+                    };
+                   
+                    switch (true) 
+                    {
+                        // 检查文件
+                        case bool when grant_type.Equals(Constant._Message_grant_type_check_file):
+                            {
+                                _memoryCache.Set($"{Constant._KeySignalRClientClients}:{Constant._Message_grant_type_check_file}:{clientid}", JsonSerializer.Serialize(client));
+                                _memoryCache.Set($"{Constant._KeySignalRClientConnects}:{Constant._Message_grant_type_check_file}:{connid}", JsonSerializer.Serialize(client));
+                                await SendConnection(connid, new ConnectionMessageBody
+                                {
+                                    connid=connid,
+                                    clientid = clientid,
+                                    grant_type = grant_type,
+                                    content = $"连接成功",
+                                    type=Constant._Message_type_message,
+                                    status = Constant._Message_status_success,
+                                    time = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
+                                });
+                                break;
+                            }
+                    }
+                }
+            }
+        }
+        public async Task SendConnection(string connectionId, ConnectionMessageBody msg)
+        {
+            await Clients.Client(connectionId).ReceiveConnection(msg);
+        }
+        public async override Task OnDisconnectedAsync(Exception? exception)
+        {
+            var connid = Context.ConnectionId;
+            SignalRClient  signalRClient =   _memoryCache.Get<SignalRClient>($"{Constant._KeySignalRClientConnects}:{connid}");
+            if (signalRClient!=null)
+            {
+                _memoryCache.Remove($"{Constant._KeySignalRClientConnects}:{connid}");
+                _memoryCache.Remove($"{Constant._KeySignalRClientClients}:{signalRClient.clientid}");
+                await Groups.RemoveFromGroupAsync(connid, signalRClient.grant_type!);
+            }
+        }
     }
-    public enum MessageType
+    public interface IClient
     {
-        conn_success,//连接成功
-        conn_error,// 连接失败
-        task_send_success,// 任务发送成功
-        task_send_error,// 任务发送失败
-        task_execute_success,// 任务执行成功
-        task_execute_error,// 任务执行失败
+        Task ReceiveMessage(MessageBody message);
+        Task ReceiveConnection(MessageBody message);
+        Task ReceiveDisConnection(MessageBody message);
     }
+  
+    
 }

+ 16 - 3
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Helpers/Constant.cs

@@ -8,8 +8,21 @@ namespace IES.ExamServer.Helper
 {
     public static class Constant
     {
-        public static string _KeyServerCenter = "Server:Center:Data";
-        public static string _KeyServerDevice = "Server:Device:Info";
-        public static string _X_Auth_AuthToken = "X-Auth-AuthToken";
+        public static readonly string _KeyServerCenter = "Server:Center:Data";
+        public static readonly string _KeyServerDevice = "Server:Device:Info";
+        public static readonly string _KeySignalRClientClients = "SignalRClient:Clients";
+        public static readonly string _KeySignalRClientConnects = "SignalRClient:Connects";
+       
+        public static readonly string _X_Auth_AuthToken = "X-Auth-AuthToken";
+        public static readonly string _Message_grant_type_check_file = "check_file";
+        public static readonly string _Message_type_message = "message";
+        public static readonly string _Message_type_check = "check";
+        public static readonly string _Message_type_download = "download";
+        public static readonly string _Message_type_upload = "upload";
+
+        public static readonly int _Message_status_error = -1;
+        public static readonly int _Message_status_info = 0;
+        public static readonly int _Message_status_success = 1;
+        public static readonly int _Message_status_warning = 2;
     }
 }

+ 98 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Models/SignalRClient.cs

@@ -0,0 +1,98 @@
+namespace IES.ExamServer.Models
+{
+    public abstract class MessageBody
+    {
+        public MessageBody()
+        {
+            time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+        }
+        /// <summary>
+        /// 连接id
+        /// </summary>
+        public virtual string? connid { get; set; }
+        /// <summary>
+        /// 客户端id
+        /// </summary>
+        public virtual string? clientid { get; set; }
+        /// <summary>
+        ///-1 error(红),0 info(黑、白),1 success(绿),2 warning(黄)
+        /// </summary>
+        public int status { get; set; }
+        /// <summary>
+        /// 内容
+        /// </summary>
+        public string? content { get; set; }
+        /// <summary>
+        /// 消息创建时间
+        /// </summary>
+        public virtual long time { get; set; }
+        /// <summary>
+        /// 授权类型,bookjs_api 
+        /// </summary>
+        public virtual string? grant_type { get; set; }
+        /// <summary>
+        /// 类型message 消息,check检查,download下载,upload上传数据
+        /// </summary>
+        public string? type { get; set; }
+
+    }
+    public class ConnectionMessageBody : MessageBody
+    {
+
+    }
+    public class DisConnectionMessageBody : MessageBody
+    {
+
+    }
+    public class DownloadUplodaFileMessageBody : MessageBody
+    {
+
+        /// <summary>
+        /// 文件大小
+        /// </summary>
+        public long size { get; set; }
+        /// <summary>
+        /// 消耗时间
+        /// </summary>
+        public long cost { get; set; }
+    }
+
+    public class CheckFileMessageBody : MessageBody
+    {
+       
+       
+    }
+    public class MessageContent
+    {
+        /// <summary>
+        ///-1 error(红),0 info(黑、白),1 success(绿),2 warning(黄)
+        /// </summary>
+        public int status { get; set; }
+        /// <summary>
+        /// 内容
+        /// </summary>
+        public string? content { get; set; }
+        /// <summary>
+        /// 消耗时间
+        /// </summary>
+        public long cost { get; set; }
+
+    }
+ 
+    public class SignalRClient
+    {
+        /// <summary>
+        /// 授权类型,bookjs_api 
+        /// </summary>
+        public string? grant_type { get; set; }
+        /// <summary>
+        /// 客户端id
+        /// </summary>
+        public string? clientid { get; set; }
+        /// <summary>
+        /// SignalR的连接ID 不建议暴露。
+        /// </summary>
+        public string? connid { get; set; }
+        public string? serverid { get; set; }
+    }
+}

+ 1 - 1
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Program.cs

@@ -124,7 +124,7 @@ namespace IES.ExamServer
             
             app.UseEndpoints(endpoints =>
             {
-                endpoints.MapHub<SignalRExamServerHub>("/signalr/screen").RequireCors("any");
+                endpoints.MapHub<SignalRExamServerHub>("/signalr/exam").RequireCors("any");
                 endpoints.MapControllers();
 
                 // NOTE: VueCliProxy is meant for developement and hot module reload

+ 3 - 3
TEAMModelOS.Function/TEAMModelOS.Function.csproj

@@ -5,9 +5,9 @@
     <OutputType>Exe</OutputType>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
-	<Version>5.2501.1</Version>
-	<AssemblyVersion>5.2501.1.1</AssemblyVersion>
-	<FileVersion>5.2501.1.1</FileVersion>
+	<Version>5.2501.8</Version>
+	<AssemblyVersion>5.2501.8.1</AssemblyVersion>
+	<FileVersion>5.2501.8.1</FileVersion>
 	<PackageId>TEAMModelOS.FunctionV4</PackageId>
 	<Authors>teammodel</Authors>
 	<Company>醍摩豆(成都)信息技术有限公司</Company>

+ 3 - 3
TEAMModelOS.SDK/TEAMModelOS.SDK.csproj

@@ -1,9 +1,9 @@
 <Project Sdk="Microsoft.NET.Sdk">
 	<PropertyGroup>
 		<TargetFramework>net8.0</TargetFramework>
-		<Version>5.2501.1</Version>
-		<AssemblyVersion>5.2501.1.1</AssemblyVersion>
-		<FileVersion>5.2501.1.1</FileVersion>
+		<Version>5.2501.8</Version>
+		<AssemblyVersion>5.2501.8.1</AssemblyVersion>
+		<FileVersion>5.2501.8.1</FileVersion>
 		<PackageReleaseNotes>发版</PackageReleaseNotes>
 	</PropertyGroup>
 

+ 4 - 4
TEAMModelOS/TEAMModelOS.csproj

@@ -80,11 +80,11 @@
 		<SpaRoot>ClientApp\</SpaRoot>
 		<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
 		<UserSecretsId>078b5d89-7d90-4f6a-88fc-7d96025990a8</UserSecretsId>
-		<Version>5.2501.1</Version>
-		<AssemblyVersion>5.2501.1.1</AssemblyVersion>
-		<FileVersion>5.2501.1.1</FileVersion>
+		<Version>5.2501.8</Version>
+		<AssemblyVersion>5.2501.8.1</AssemblyVersion>
+		<FileVersion>5.2501.8.1</FileVersion>
 		<Description>TEAMModelOS(IES5)</Description>
-		<PackageReleaseNotes>IES版本说明版本切换标记5.2501.1.1</PackageReleaseNotes>
+		<PackageReleaseNotes>IES版本说明版本切换标记5.2501.8.1</PackageReleaseNotes>
 		<PackageId>TEAMModelOS</PackageId>
 		<Authors>teammodel</Authors>
 		<Company>醍摩豆(成都)信息技术有限公司</Company>

+ 1 - 1
TEAMModelOS/appsettings.Development.json

@@ -18,7 +18,7 @@
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4",
     "HttpTrigger": "https://teammodelosfunction-test.chinacloudsites.cn/api/",
     //"HttpTrigger": "http://localhost:7071/api/"
-    "Version": "5.2501.1.1"
+    "Version": "5.2501.8.1"
   },
   "Azure": {
     // 测试站数据库

+ 1 - 1
TEAMModelOS/appsettings.json

@@ -18,7 +18,7 @@
     "Exp": 86400,
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4",
     "HttpTrigger": "https://teammodelosfunction.chinacloudsites.cn/api/",
-    "Version": "5.2501.1.1"
+    "Version": "5.2501.8.1"
   },
   "Azure": {
     "Storage": {