[feat]增加WinForm客户端例程,主要为了测试同步调用异步方法等场景
大石头 authored at 2024-11-23 22:58:12
3.14 KiB
NewLife.Remoting
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebSockets;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NewLife.Caching;
using NewLife.Remoting.Extensions.ModelBinders;
using NewLife.Remoting.Extensions.Models;
using NewLife.Remoting.Extensions.Services;
using NewLife.Remoting.Models;
using NewLife.Security;

namespace NewLife.Remoting.Extensions;

/// <summary>远程通信框架扩展</summary>
public static class RemotingExtensions
{
    /// <summary>添加远程通信服务端,注册BaseDeviceController所需类型服务</summary>
    /// <remarks>
    /// 注册登录心跳等模型类,可再次扩展模型类,传输更多内容;
    /// 注册TokenService令牌服务,提供令牌颁发与验证服务;
    /// 注册密码提供者,用于通信过程中保护密钥,避免明文传输;
    /// 注册缓存提供者的默认实现;
    /// </remarks>
    /// <param name="services"></param>
    /// <param name="setting"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddRemoting(this IServiceCollection services, ITokenSetting? setting = null)
    {
        //if (setting == null) throw new ArgumentNullException(nameof(setting));

        services.TryAddTransient<ILoginRequest, LoginRequest>();
        services.TryAddTransient<ILoginResponse, LoginResponse>();
        services.TryAddTransient<ILogoutResponse, LogoutResponse>();
        services.TryAddTransient<IPingRequest, PingRequest>();
        services.TryAddTransient<IPingResponse, PingResponse>();

        // 注册Remoting所必须的服务
        if (setting != null)
        {
            services.TryAddSingleton<TokenService>();
            services.TryAddSingleton(setting);
        }

        // 注册密码提供者,用于通信过程中保护密钥,避免明文传输
        services.TryAddSingleton<IPasswordProvider>(new SaltPasswordProvider { Algorithm = "md5", SaltTime = 60 });

        // 注册缓存提供者,必须有默认实现
        services.TryAddSingleton<ICacheProvider, CacheProvider>();

        // 添加模型绑定器
        //var binderProvider = new ServiceModelBinderProvider();
        services.Configure<MvcOptions>(mvcOptions =>
        {
            //mvcOptions.ModelBinderProviders.Insert(0, binderProvider);
            mvcOptions.ModelBinderProviders.Insert(0, new InterfaceModelBinderProvider());
        });
        //services.AddSingleton<IModelMetadataProvider, ServicModelMetadataProvider>();

        return services;
    }

    /// <summary>使用远程通信服务端,注册WebSocket中间件</summary>
    /// <param name="app"></param>
    public static void UseRemoting(this IApplicationBuilder app)
    {
        // 判断是否已经添加了WebSocket中间件
        if (!app.Properties.TryGetValue("__MiddlewareDescriptions", out var value) ||
            value is not IList<String> result || !result.Contains(typeof(WebSocketMiddleware).FullName!))
        {
            app.UseWebSockets(new WebSocketOptions()
            {
                KeepAliveInterval = TimeSpan.FromSeconds(60),
            });
        }
    }
}