[英]SignalR Javascript Client: Cannot Start Connection
我的连接无法启动。 此代码在1.x中有效,但在版本2中不起作用。
SignalR似乎正在尝试连接,但没有成功。 永远不会调用hub方法。
附带使用SignalR调试发送图像。
使用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>
毂:
[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();
}
}
调试:
编辑:
我发现了问题! 我的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];
}
该方法总是在这里停止:lock(_lockAdd)
我想保存所有用户连接Ids有什么想法吗?
谢谢
尝试在连接之前将客户端方法预订移到。 如果在启动连接时尚未注册,则无法从服务器调用它。
因此,将其更改为以下内容:
$(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);
});
});
编辑
根据您对OnConnected
方法中的服务器错误的评论,看来您可能有两个问题。 隔离掉连接跟踪部分(只需将其注释掉)即可获得客户端和服务器之间的完整往返。 然后添加可能是数据库连接错误的连接跟踪-检查服务器日志。
编辑
在存储用户连接方面,您有几种选择。
使用ConcurrentDictionary
:
最简单的方法之一是将其存储在静态ConcurrentDictionary
,类似于您所拥有的。 尽量避免使用太多的锁-使用ConcurrentDictionary
意味着您实际上将一无所有。
例如
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;
});
}
}
有关更多信息,请参见MSDN: http : //msdn.microsoft.com/zh-cn/library/ee378675(v=vs.110).aspx
使用数据库:
另一个选择是存储在数据库中(使用Entity Framework),该数据库具有在跨服务器回收跟踪用户数据方面的额外好处。
看看http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections ,其中显示了所有其他选项。
长期存在相同的问题,因此在某个时候放弃了整个signalR,但不得不为我们的项目再次选择它:
我写了一个答案,可能会引导您和其他人走上正确的道路……在答案中,我使用的是PersistentConnection而不是Hub,但原理应相同:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.