【问题标题】:Adding a user to Hub group in SignalR在 SignalR 中将用户添加到 Hub 组
【发布时间】:2019-12-02 12:17:48
【问题描述】:

我有一个基集线器 (HubBase) 类和两个从基类继承的不同集线器类(我们称之为 HubA 和 HubB)。我将所有共享连接方法保留到 HubBase。我只想向连接到相关集线器的相应客户端发送消息。出于这个原因,我会将相关用户添加到已连接的相应组中。例如,如果用户连接到 HubA,则应将此用户添加到 GroupA,如果连接到 HubB,则应添加 GroupB。下面是相关类中的方法:

HubBase:

public class HubBase : Hub
{
    public readonly static ConnectionMapping<string> _connections =
        new ConnectionMapping<string>();

    public override async Task OnConnected()
    {
        /* !!! Here I need the user to the given group name. But I cannot define groupName 
        parameter in this method due to "no suitable method found to override" error */
        await Groups.Add(Context.ConnectionId, "groupA");

        string name = Context.User.Identity.Name;
        _connections.Add(name, Context.ConnectionId);
        await base.OnConnected();
    }

    public override async Task OnDisconnected(bool stopCalled)
    {
        await Groups.Remove(Context.ConnectionId, "groupA");

        string name = Context.User.Identity.Name;
        _connections.Remove(name, Context.ConnectionId);
        await base.OnDisconnected(stopCalled);
    }
}


HubA:

public class HubA : HubBase
{
    private static IHubContext context = GlobalHost.ConnectionManager.GetHubContext<HubA>();

    public async Task SendMessage(string message)
    {
        await context.Clients.Group("groupA", message).sendMessage;
    }
}


HubB:

public class HubB : HubBase
{
    private static IHubContext context = GlobalHost.ConnectionManager.GetHubContext<HubB>();

    public async Task SendMessage(string message)
    {
        await context.Clients.Group("groupB", message).sendMessage;
    }
}

问题是:我需要将组名传递给基类中的 OnConnected() 方法,并在连接时将用户添加到这个给定的组。但是由于“找不到合适的方法来覆盖”错误,我无法在此方法中定义 groupName 参数。我应该将此参数从继承的类传递给基类的构造函数吗?还是有更聪明的方法?

更新:这是我试图从客户端传递的内容:

HubService.ts:

export class HubService {
    private baseUrl: string;
    private proxy: any;
    private proxyName: string = 'myHub';
    private connection: any;         

    constructor(public app: AppService) {
        this.baseUrl = app.getBaseUrl();
        this.createConnection();
        this.registerOnServerEvents();
        this.startConnection();
    }

    private createConnection() {
        // create hub connection
        this.connection = $.hubConnection(this.baseUrl);

        // create new proxy as name already given in top  
        this.proxy = this.connection.createHubProxy(this.proxyName);
    }

    private startConnection(): any {
        this.connection
            .start()
            .done((data: any) => {
                this.connection.qs = { 'group': 'GroupA' };
            })
    }
}

HubBase.cs:

public override async Task OnConnected()
{
    var group = Context.QueryString["group"]; // ! this returns null
    await Groups.Add(Context.ConnectionId, group);

    string name = Context.User.Identity.Name;
    _connections.Add(name, Context.ConnectionId);
    await base.OnConnected();
}

【问题讨论】:

  • 复制粘贴完整异常信息
  • “'HubBase.OnConnected(string)': 找不到合适的方法来覆盖 Xxx\HubBase.cs。”。但我不是错误消息,而是想知道如何通过提供组名从 HubA、HubB 添加用户。另一方面,在客户端可能有另一种解决方案,方法是给出组名并传递给 HubA,HubB。
  • 您可以设置GroupqueryString 开始连接。

标签: c# asp.net asp.net-mvc asp.net-core signalr


【解决方案1】:

我通过以下方法解决了这个问题:

service.ts:

private startConnection(): any {

    //pass parameter viw query string
    this.connection.qs = { 'group': 'myGroup' }; 

    this.connection
        .start()
        .done((data: any) => {
            //
        })
}

HubBase.cs:

public class HubBase : Hub
{
    public readonly static ConnectionMapping<string> _connections =
        new ConnectionMapping<string>();

    public override async Task OnConnected()
    {
        var group = Context.QueryString["group"];

        //I tried to add the user to the given group using one of the following method
        await Groups.Add(Context.ConnectionId, group); 
        await AddToGroup(Context.ConnectionId, group);

        //other stuff
    }
}

https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client#how-to-configure-the-connection

但我无法从继承的集线器类中获取组,如 Cannot retrieve group in SignalR Hub 中所述。有什么帮助吗?

【讨论】:

    【解决方案2】:

    您可以在与 queryString 开始连接时将 Group 名称设置为 parameter

    在服务器端从Request获取。

    更多信息:

    SignalR Client How to Set user when start connection?

    请在 ts:

    中尝试此代码
    export class HubService 
    {
        hubConnection: HubConnection;
        constructor(public app: AppService) { this.startConnection();}
    
        private startConnection(): any 
        {
            let builder = new HubConnectionBuilder();
            this.hubConnection = builder.withUrl('http://localhost:12345/HubBase?group=GroupA').build();
            this.hubConnection.start().catch(() => console.log('error'););
        }
    }
    

    【讨论】:

    • @ARF 非常感谢您的回复。但不幸的是,我在服务器端得到了 null 。您能否请我在上面的问题中更新?
    • 谢谢。我认为 Javascript 和 Angular 方面没有太多区别。那么,我怎样才能在你说的例子中传递参数 // 在这里做一些事情......
    • 不幸的是,该文章中没有与组相关的部分:(
    • 非常感谢您的帮助,我用另一种方法解决了这个问题。尽管如此,还是投了赞成票;)
    • 但是我的回答中提到了一个小问题,请您看看好吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多