我的连接无法启动。 此代码在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)
我想保存所有用户connectionIds有什么想法吗?
由于
答案 0 :(得分:1)
尝试将客户端方法订阅移至连接之前。如果在连接启动时没有注册,则无法从服务器调用它。
所以将其更改为以下内容:
$(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
意味着你实际上最终都没有。
e.g。
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/en-us/library/ee378675(v=vs.110).aspx
使用数据库:
另一种选择是存储在数据库中(使用实体框架),该数据库具有跨服务器回收跟踪用户数据的额外好处。
查看http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections,其中显示所有这些选项。
答案 1 :(得分:0)
长期存在同样的问题,所以在某个时候放弃了整个signalR,但是我们的项目不得不再次拿起它:
我写了一个答案,可能会引导你和其他人走上正轨(一步一步)......在答案中我使用PersistentConnection而不是Hub,但原则应该是相同的: