如何持久化SignalR连接ID

时间:2015-01-01 19:31:35

标签: asp.net signalr

我正在尝试构建一个聊天应用,用户ID由其自动生成的signalR连接ID表示。在页面刷新时,实例化新连接时连接ID会更改。有没有办法保持用户的连接ID状态,直到浏览器会话结束(即直到他在客户端结束他的会话)。

任何指南或文档?这真的很有用。

我是信号员的新手。所以试图了解搜索谷歌的很多东西。从这个网址我得到了一个类似的片段http://kevgriffin.com/maintaining-signalr-connectionids-across-page-instances/

他们说这是可能的。问题是如果我们引用页面,信号器通常会创建一个新的连接ID。我想阻止这个但是如何.......

此代码段。

public class MyConnectionFactory : IConnectionIdFactory
    {
        public string CreateConnectionId(IRequest request)
        {
            if (request.Cookies["srconnectionid"] != null)
            {
                return request.Cookies["srconnectionid"];
            }

            return Guid.NewGuid().ToString();
        }
    }

$.connection.hub.start().done(function () {
        alert("Connected!");
        var myClientId = $.connection.hub.id;
        setCookie("srconnectionid", myClientId);
    });

    function setCookie(cName, value, exdays) {
        var exdate = new Date();
        exdate.setDate(exdate.getDate() + exdays);
        var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString());
        document.cookie = cName + "=" + c_value;
    }

我怀疑它是否适用于所有信号灯版本?如果不是那么如何在新版本中处理它,特别是如果页面被刷新则不生成新的连接ID。寻找建议。

如果我们使用Persistent连接类而不是hub,那么会发生什么.....在这种情况下,如果我们在客户端刷新页面,连接ID将会持续存在?请指导。 感谢

2 个答案:

答案 0 :(得分:4)

SignalR允许您通过IPrincipal.Identity.Name向用户发送消息。只需使用Clients.User(userName)代替Clients.Client(connectionId)

如果由于某种原因无法使用IPrincipal.Identity.Name来解决用户问题,您可以创建自己的IUserIdProvider。这是SignalR> = 1.0.0中不再存在的IConnectionIdFactory的替代。

等效IUserIdProvider将如下所示:

public class MyConnectionFactory : IUserIdProvider
{
    public string GetUserId(IRequest request)
    {
        if (request.Cookies["srconnectionid"] != null)
        {
            return request.Cookies["srconnectionid"];
        }

        return Guid.NewGuid().ToString();
    }
}

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var idProvider = new MyConnectionFactory();
        GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => idProvider);

        app.MapSignalR();
    }
}

public class MyHub : Hub
{
    public Task Send(string userName, string message)
    {
        return Clients.User(userName).receive(message);
    }
}

在给定MyConnectionFactory的情况下欺骗用户真的很微不足道。您可以使用HMAC

使其更安全

理想情况下,您只需使用从IRequest.User.Identity.Name检索用户ID的default IUserIdProvider

答案 1 :(得分:0)

用户ID提供程序不起作用,因为连接ID不是来自它。我实现了一个解决方案(https://weblogs.asp.net/ricardoperes/persisting-signalr-connections-across-page-reloads),它使用存储在会话存储中的伪会话ID。然后,每个SignalR连接ID都映射到此伪会话ID。