我正在尝试使用MVC5
在SignalR
中构建一个非常简单的聊天应用程序。
我在我的集线器类中创建了一个字符串列表,并添加了两个简单的方法来添加和删除元素,调用客户端以通过Jquery
显示用户列表。
添加用户可以正常工作,但不会从列表中删除它们。知道为什么吗?
static List<string> users = new List<string>();
public void AddUser(string name)
{
if (!users.Contains(name))
{
users.Add(name);
Clients.All.updateUserList(users);
}
Clients.All.updateUserList(users);
}
public void RemoveUser(string name)
{
if (users.Contains(name))
{
users.Remove(name);
Clients.All.updateUserList(users);
}
Clients.All.updateUserList(users);
}
public override System.Threading.Tasks.Task OnConnected()
{
Clients.Caller.connected();
return base.OnConnected();
}
public override System.Threading.Tasks.Task OnReconnected()
{
Clients.Caller.connected();
return base.OnReconnected();
}
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
Clients.Caller.disconnected();
return base.OnDisconnected(stopCalled);
}
在视图中
<script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script>
<script src="~/signalr/hubs"></script>
<script>
$(function () {
var chat = $.connection.ChatHub;
chat.client.updateUserList = function (users) {
var userList = $("#nameUsers");
userList.empty();
$.each(users, function (i) {
var li = $('<li/>')
.text(users[i])
.appendTo(userList);
});
};
chat.client.connected = function () {
chat.server.addUser("@ViewBag.Username");
};
chat.client.disconnected = function () {
chat.server.removeUser("@ViewBag.Username");
}; ....
我从MVC
中的ViewBag
控制器获取用户名。
答案 0 :(得分:1)
删除逻辑应该在OnDisconnected
方法上进行。
Read this article from the SignalR documentation that explains lifetime events.
我们的想法是,您的客户端无法调用removeUser
方法,因为它已经与服务器断开连接。
因此SignalR实现了OnDisconnected
方法(您覆盖它,添加逻辑然后返回base.OnDisconnected
),然后让服务器确定断开连接时间。
祝你好运!
答案 1 :(得分:0)
正如其他答案中所提到的 - 一旦客户端断开连接 - 它就无法调用服务器上的删除用户。更好的解决方案是:
static Dictionary<string, string> users = new List<string, string>();
private void AddUser(string connectionId, string name)
{
lock (users)
{
users[connectionId] = name;
Clients.All.updateUserList(users.Values.Distinct());
}
}
private void RemoveUser(string connectionId)
{
lock (users)
{
users.Remove(connectionId);
Clients.All.updateUserList(users.Values.Distinct());
}
}
public override System.Threading.Tasks.Task OnConnected()
{
AddUser(Context.ConnectionId, User.Identity.Name);
return base.OnConnected();
}
public override System.Threading.Tasks.Task OnReconnected()
{
AddUser(Context.ConnectionId, User.Identity.Name);
return base.OnReconnected();
}
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
RemoveUser(Context.ConnectionId);
return base.OnDisconnected(stopCalled);
}
主要差异:
你的下一个问题是静态用户(这有点像黑客攻击),但相比之下,这是一个小问题。
答案 2 :(得分:0)
Connection is lost while removing user.You have to establish connection.
$.connection.hub.disconnected(function () {
console.log("Disconnected. Reason: " + $.connection.hub.lastError.message);
setTimeout(function () {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
It will reestablish your connection.