.NetCore项目SignalR获取客户端信息的测试

510 阅读2分钟

.NetCore项目SignalR获取客户端信息的测试

.Net7 新增了 SignalR 可以获取客户端数据的方法,即原方法 InvokeAsync 支持返回值,这里结合官网做了测试,作为记录

1. SignalR注入

2. 环境搭建

继续略

3. 升级本地SignalRJS

结合这两个地址

ASP.NET Core SignalR JavaScript 客户端

microsoft-signalr

注意js版本号7.0+,下到本地也行,从vs2022添加客户端也行,如果本地低在调用js方法后会显示版本不支持;

4. 服务端


/// <summary>

/// 得到客户端结果

/// </summary>

/// <param name="evname"></param>

/// <param name="msg"></param>

/// <param name="id"></param>

/// <returns></returns>

public static async Task<dynamic> GetHubMessage(string evname, string msg, string id = "")

{

    //尝试拿一个hubid

    if (string.IsNullOrEmpty(id)) { id = GetHubID(); }

    if (string.IsNullOrEmpty(id)) { return default; }

    var Hub = PageContext.GetServerByApp<IHubContext<SignalRHub>>();

    var msr = await Hub.Clients.Client(id).InvokeAsync<dynamic>(evname, msg, new CancellationToken());

    return msr ?? default;

}

  


/// <summary>

/// 尝试得到本次的hubid

/// </summary>

/// <returns></returns>

public static string GetHubID()

{

    var hubid = string.Empty;

    var head = PageContext.Current!.Request.Headers;

    if (head.ContainsKey("hubid"))

    {

        hubid = head["hubid"];

    }

    else if (PageContext.Current!.Request.Form.ContainsKey("hubid"))

    {

        hubid = PageContext.Current!.Request.Form["hubid"];

    }

    return hubid;

}

以上代码 核心方法就是 InvokeAsync ,其他都来自服务就可以了,注意接收值,前台的返回我测试了 数组 对象,后台的接到到的类型是 System.Text.Json , 而不是 Newtonsoft.Json,尽量返回字符串比较稳定;用的时候直接调用即可 GetHubMessage("getMessage","Grid1");

我这里触发的前端方法是 getMessage 如果前端没有注册 getMessage ,则会提示

Client didn't provide a result.(客户端没有返回结果)

5. 客户端


const connection = new signalR

    .HubConnectionBuilder()

    .withUrl("/HomeHub")

    .build();

  


window.hub.connection = connection;

...

window.hub.connection.on(`getMessage`,async (msg)=>{

    return JSON.stringify(F.ui[msg].fields);

});

这里注意了,我的HomeHub连接是在顶层框架页面,即只有一个实例,如果同一个实例注册多个方法即getMessage并返回结果,会报错,Client provided multiple results(客户端提供了多个结果);

6. 应用

这样就拿到数据了,那在什么情况下会用到呢,场景要有几个特点,数据回发提交的时候有的参数没带着,或者带不了;或者这是客户端还没有数据,等会才有;或者需要等待客户继续操作后才能拿到结果;

一个典型的场景就是确认Confirm,之前我已经将F.confirm 改为异步了,用Promise包一下就行;之前也改造过等待客户响应的方法,使用客户端响应后二次提交从缓存拿到任务再改变状态,绕了一大圈,存在超时和中断问题;升级之后,后台执行到需要客户选择的代码,可以直接由服务端发起,然后等着前台返回就行了,省去了不少代码;

其他应用场景还有待探索。