简体   繁体   English

SignalR Javascript客户端:无法启动连接

[英]SignalR Javascript Client: Cannot Start Connection

My connection does not start. 我的连接无法启动。 This code worked in 1.x but in version 2 is not working. 此代码在1.x中有效,但在版本2中不起作用。

SignalR seems to be trying to connect but without success. SignalR似乎正在尝试连接,但没有成功。 The hub method is never called. 永远不会调用hub方法。

Attached sending an image with SignalR debug. 附带使用SignalR调试发送图像。

Javascript: 使用Javascript:

<script type="text/javascript">

    $.connection.hub.logging = true;
    var options = { transport: ['webSockets', 'longPolling'] };

    $(function() {
        var userHub = $.connection.userHub;

        //Iniciar connecção
        window.hubReady = $.connection.hub.start(options);

        window.hubReady.done(function () {
            userHub.server.ini();
        });

        userHub.client.iniDone = function (connectionId) {
            console.log(connectionId);
        };

        $.connection.hub.connectionSlow(function() {
            console.log('slow connection...');
        });

        window.hubReady.fail(function(error) {
            console.log(error);
        });

        $.connection.hub.disconnected(function() {
            setTimeout(function() {
                $.connection.hub.start();
            }, 2000);
        });

    });

</script>

Hub: 毂:

[HubName("userHub")]
public class UserHub : Hub
{
    public void Ini()
    {
        Clients.Client(Context.ConnectionId).iniDone(string.Format("Conectado com o id: {0}", Context.ConnectionId));
    }

    public override Task OnConnected()
    {

        var connectionId = Context.ConnectionId;
        var email = string.IsNullOrWhiteSpace(Context.User.Identity.Name) ? Context.Headers["email"] : Context.User.Identity.Name;


        if (email != null && connectionId != null)
            UserData.GetInstance(email).ConnectionsIds.Add(connectionId);

        return base.OnConnected();
    }

    public override Task OnDisconnected()
    {

        var connectionId = Context.ConnectionId;
        var email = string.IsNullOrWhiteSpace(Context.User.Identity.Name) ? Context.Headers["email"] : Context.User.Identity.Name;


        if (email != null && connectionId != null)
            UserData.GetInstance(email).ConnectionsIds.Remove(connectionId);

        return base.OnDisconnected();
    }
}

Debug: 调试:

SignalR Debug Image SignalR调试映像

EDIT: 编辑:

I found the problem! 我发现了问题! The GetInstance method of my Singleton has problems. 我的Singleton的GetInstance方法有问题。

public static UserData GetInstance(string username)
{
    if (_sharedUsers == null) 
        lock (_lockCreate) 
                _sharedUsers = new Dictionary<string, UserData>(); 

    if (!_sharedUsers.ContainsKey(username)) 
        lock (_lockAdd) 
            _sharedUsers.Add(username, new UserData(username)); 

    return _sharedUsers[username];
}

the method stops always here: lock (_lockAdd) 该方法总是在这里停止:lock(_lockAdd)

I want to save all user connectionsIds Any ideas? 我想保存所有用户连接Ids有什么想法吗?

Thanks 谢谢

Try moving the client method subscription to be before you connect. 尝试在连接之前将客户端方法预订移到。 If it's not registered by the time the connection is started, then it will not be callable from the server. 如果在启动连接时尚未注册,则无法从服务器调用它。

So change it to the following: 因此,将其更改为以下内容:

$(function() {
    var userHub = $.connection.userHub;

    //Register Client handlers first
    userHub.client.iniDone = function (connectionId) {
        console.log(connectionId);
    };

    //Now you can connect.
    window.hubReady = $.connection.hub.start(options);

    window.hubReady.done(function () {
        userHub.server.ini();
    });

    $.connection.hub.connectionSlow(function() {
        console.log('slow connection...');
    });

    window.hubReady.fail(function(error) {
        console.log(error);
    });

    $.connection.hub.disconnected(function() {
        setTimeout(function() {
            $.connection.hub.start();
        }, 2000);
    });

});

Edit 编辑

Based on your comment around a server error in the OnConnected method, it seems like you may have a two problems then. 根据您对OnConnected方法中的服务器错误的评论,看来您可能有两个问题。 Isolate the connection tracking part out (just comment it out) to get the full round-trip going between client and server. 隔离掉连接跟踪部分(只需将其注释掉)即可获得客户端和服务器之间的完整往返。 Then add back the connection tracking which is possibly a DB connection error - check the server logs. 然后添加可能是数据库连接错误的连接跟踪-检查服务器日志。

Edit 编辑

In terms of storing the user connections, you've a few options. 在存储用户连接方面,您有几种选择。

Use ConcurrentDictionary : 使用ConcurrentDictionary

One of the simplest is storing in a static ConcurrentDictionary , similar to what you have. 最简单的方法之一是将其存储在静态ConcurrentDictionary ,类似于您所拥有的。 Try to avoid the use of so many locks - using a ConcurrentDictionary means you'll actually end up with none. 尽量避免使用太多的锁-使用ConcurrentDictionary意味着您实际上将一无所有。

eg 例如

    public class UserData
    {
        public UserData(string username)
        {
            UserName = username;
            ConnectionIds = new HashSet<string>();
        }

        public string UserName { get; private set; }
        public HashSet<string> ConnectionIds { get; private set; } 
    }

    public static class ConnectionStore
    {
        private static readonly ConcurrentDictionary<string, UserData> _userData = new ConcurrentDictionary<string, UserData>();

        public static void Join(string username, string connectionId)
        {
            _userData.AddOrUpdate(username, 
                u => new UserData(u),                   /* Lambda to call when it's an Add */
                (u, ud) => {                            /* Lambda to call when it's an Update */
                    ud.ConnectionIds.Add(connectionId);
                    return ud;
            });
        }
    }

See MSDN for more info: http://msdn.microsoft.com/en-us/library/ee378675(v=vs.110).aspx 有关更多信息,请参见MSDN: http : //msdn.microsoft.com/zh-cn/library/ee378675(v=vs.110).aspx

Use a database: 使用数据库:

The other option is to store in a database (using Entity Framework) which has the added benefit of tracking user data across server recycles. 另一个选择是存储在数据库中(使用Entity Framework),该数据库具有在跨服务器回收跟踪用户数据方面的额外好处。

Have a look at http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections which shows all these options a couple of others. 看看http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections ,其中显示了所有其他选项。

Had the same problem for so long, so gave up the whole signalR at some point, but had to pick it up again for our project: 长期存在相同的问题,因此在某个时候放弃了整个signalR,但不得不为我们的项目再次选择它:

I have written an answer which might lead you and others on the right track (step by step)...In the answer I am using PersistentConnection rather than Hub, but the principle should be the same: 我写了一个答案,可能会引导您和其他人走上正确的道路……在答案中,我使用的是PersistentConnection而不是Hub,但原理应相同:

https://stackoverflow.com/a/25304790/3940626 https://stackoverflow.com/a/25304790/3940626

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM