using Serein.Library;
using Serein.Library.Api;
using Serein.Library.Utils;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
namespace Serein.Proto.WebSocket.Handle
{
///
/// Json消息处理模块
///
public class WebSocketHandleModule
{
///
/// Json消息处理模块
///
public WebSocketHandleModule(WebSocketModuleConfig config)
{
_moduleConfig = config;
_methodInvokeConfigs = new ConcurrentDictionary();
_myMsgIdHash = new HashSet();
}
///
/// 模块的处理配置
///
private readonly WebSocketModuleConfig _moduleConfig;
///
/// 用来判断消息是否重复
///
private readonly HashSet _myMsgIdHash;
///
/// 存储处理数据的配置
///
private readonly ConcurrentDictionary _methodInvokeConfigs ;
///
/// 添加处理配置
///
/// 处理模块
internal bool AddHandleConfigs(WebSocketMethodConfig config)
{
if (!_methodInvokeConfigs.ContainsKey(config.ThemeValue))
{
_methodInvokeConfigs[config.ThemeValue] = config;
return true;
}
else
{
return false;
}
}
///
/// 移除某个处理模块
///
///
///
public bool RemoveConfig(ISocketHandleModule socketControlBase)
{
foreach (var kv in _methodInvokeConfigs.ToArray())
{
var config = kv.Value;
_methodInvokeConfigs.TryRemove(kv.Key, out _);
}
return _methodInvokeConfigs.Count == 0;
}
///
/// 卸载当前模块的所有配置
///
public void UnloadConfig()
{
var temp = _methodInvokeConfigs.Values;
_methodInvokeConfigs.Clear();
}
///
/// 处理JSON数据
///
public async Task HandleAsync(WebSocketHandleContext context)
{
var jsonObject = context.MsgRequest; // 获取到消息
context.Model = new ModuleConfig(); // 设置当前模块配置
context.Model.IsResponseUseReturn = _moduleConfig.IsResponseUseReturn;
if (jsonObject is null)
{
context.TriggerExceptionTracking($"请求没有获取到消息");
return; // 没有获取到消息
}
if (!jsonObject.TryGetValue(_moduleConfig.MsgIdJsonKey, out var msgIdToken) || msgIdToken.IsNull)
{
context.TriggerExceptionTracking($"消息Id从JSON键[{_moduleConfig.MsgIdJsonKey}]提取失败");
return; // 没有获取到消息
}
if (msgIdToken.Type != IJsonToken.TokenType.Value)
{
context.TriggerExceptionTracking($"请求消息Id[{_moduleConfig.ThemeJsonKey}]需要值类型,当前类型为[{msgIdToken.Type}]");
return; // 没有获取到消息
}
var msgId = msgIdToken.ToString(); // 获取Id
context.Model.MsgId = msgId;
// 验证消息ID是否重复
if (!_myMsgIdHash.Add(msgId))
{
context.TriggerExceptionTracking($"消息Id[{msgId}]重复发送");
return; // 消息重复
}
if(!jsonObject.TryGetValue(_moduleConfig.ThemeJsonKey, out var themeToken) || themeToken.IsNull)
{
context.TriggerExceptionTracking($"主题从JSON键[{_moduleConfig.ThemeJsonKey}]提取失败");
return; // 没有获取到消息
}
if(themeToken.Type != IJsonToken.TokenType.Value)
{
context.TriggerExceptionTracking($"请求主题[{_moduleConfig.ThemeJsonKey}]需要值类型,当前类型为[{themeToken.Type}]");
return; // 没有获取到消息
}
var theme = themeToken.ToString(); // 获取主题
context.Model.Theme = theme;
// 验证主题
if (!_methodInvokeConfigs.TryGetValue(theme, out var handldConfig))
{
context.TriggerExceptionTracking($"不存在这样的主题");
return;
}
// 验证数据
if (!jsonObject.TryGetValue(_moduleConfig.DataJsonKey, out var dataToken))
{
context.TriggerExceptionTracking($"数据从JSON键[{_moduleConfig.DataJsonKey}]提取失败");
return; // 没有主题
}
if(dataToken.Type != IJsonToken.TokenType.Object)
{
context.TriggerExceptionTracking($"数据需要 JSON Object,当前类型为[{dataToken.Type}]");
return;
}
context.MsgData = dataToken; // 添加消息
context.MsgRequest = jsonObject; // 添加原始消息
try
{
if (TryGetParameters(handldConfig, context, out var args))
{
var result = await InvokeAsync(handldConfig, args);
if (handldConfig.IsReturnValue)
{
await RepliedAsync(_moduleConfig, context, result);
}
}
}
catch (Exception ex)
{
context.TriggerExceptionTracking(ex);
}
finally
{
context.Handle = true;
}
}
///
/// 调用
///
///
///
///
public static async Task