123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- 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
- {
- public static class SignalRExamServerHubExtension
- {
- public async static Task SendMessage(this IHubContext<SignalRExamServerHub> hubContext, IMemoryCache _memoryCache, ILogger logger, string clientId, string grant_type, MessageContent content,bool isLog=false)
- {
- try
- {
- //双向检测是否连接。
- SignalRClient signalRClient = _memoryCache.Get<SignalRClient>($"{Constant._KeySignalRClientClients}:{clientId}");
- if (signalRClient!=null)
- {
- signalRClient = _memoryCache.Get<SignalRClient>($"{Constant._KeySignalRClientConnects}:{signalRClient.connid}");
- }
- int code = 0;
- string msg = "";
- CheckFileMessageBody messageBody = new CheckFileMessageBody
- {
- content = content.content,
- status = content.status,
- clientid = clientId,
- connid = signalRClient?.connid,
- grant_type = grant_type,
- time = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
- type = Constant._Message_type_message,
- contents = content.contents,
- step=content.step,
- finish = content.finish
- };
- if (signalRClient != null)
- {
- try
- {
- switch (true)
- {
- case bool when grant_type.Equals(Constant._Message_grant_type_ies_qrcode_login):
- {
- await hubContext.Clients.Client(signalRClient.connid!).SendAsync("ReceiveMessage", messageBody);
- code=200;
- msg = $"发送成功";
- break;
- }
- case bool when grant_type.Equals(Constant._Message_grant_type_download_file):
- {
- await hubContext.Clients.Client(signalRClient.connid!).SendAsync("ReceiveMessage", messageBody);
- code=200;
- msg = $"发送成功";
- break;
- }
- case bool when grant_type.Equals(Constant._Message_grant_type_check_file):
- {
- await hubContext.Clients.Client(signalRClient.connid!).SendAsync("ReceiveMessage", messageBody);
- code=200;
- msg = $"发送成功";
- break;
- }
- default:
- break;
- }
- }
- catch (Exception ex)
- {
- code=500;
- msg = $"{ex.Message},{ex.StackTrace}";
- }
- }
- else
- {
- code= 400;
- msg="未连接客户端";
- }
- if (isLog)
- {
- logger.LogData<object>(new { code, msg, data = messageBody }, content.dataId!);
- }
- } catch (Exception ex) {
- logger.LogError(ex.Message, ex.StackTrace);
- }
- }
- }
- public class SignalRExamServerHub : Hub<IClient>
- {
- private readonly ILogger<SignalRExamServerHub> _logger;
- private readonly IMemoryCache _memoryCache;
-
- public SignalRExamServerHub(ILogger<SignalRExamServerHub> logger,IMemoryCache memoryCache)
- {
- _logger = logger;
- _memoryCache = memoryCache;
- }
- // <summary>
- /// 这需要继承Hub来创建中心,并向中心添加方法,客户端可以调用标识符为public的方法
- /// </summary>
- /// <param name="user"></param>
- /// <param name="message"></param>
- /// <returns></returns>
- public void ReceiveMessage(string clientId, string grant_type, string contentmsg )
- {
- _logger.LogInformation($"收到客户端的消息{contentmsg}");
- }
-
- /// <summary>
- /// 客户连接成功时触发
- /// </summary>
- /// <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}:{clientid}", client);
- _memoryCache.Set($"{Constant._KeySignalRClientConnects}:{connid}", 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;
- }
- // 扫码登录
- case bool when grant_type.Equals(Constant._Message_grant_type_ies_qrcode_login):
- {
- _memoryCache.Set($"{Constant._KeySignalRClientClients}:{clientid}", client);
- _memoryCache.Set($"{Constant._KeySignalRClientConnects}:{connid}", 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;
- }
- // 下载文件
- case bool when grant_type.Equals(Constant._Message_grant_type_download_file):
- {
- _memoryCache.Set($"{Constant._KeySignalRClientClients}:{clientid}", client);
- _memoryCache.Set($"{Constant._KeySignalRClientConnects}:{connid}", 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;
- }
- // 上传数据
- case bool when grant_type.Equals(Constant._Message_grant_type_upload_data):
- {
- _memoryCache.Set($"{Constant._KeySignalRClientClients}:{clientid}", client);
- _memoryCache.Set($"{Constant._KeySignalRClientConnects}:{connid}", 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 interface IClient
- {
- Task ReceiveMessage(MessageBody message);
- Task ReceiveConnection(MessageBody message);
- Task ReceiveDisConnection(MessageBody message);
- }
-
-
- }
|