前面的项目创建与SignalR的引用在微软官方文档都有,我们就不做概述,今天我们主要看一下客户端的连接与断线以及单对单很群发消息。
首先是登陆和断开的过程登陆时我们可以将一些信息从JavaScript传过来,在服务器的Context中存有这些数据,然后根据用户名的情况保存到Dictionary中去。
//JavaScript代码实现客户端与服务器连接
var connection;
$(function () {
var userName"***";
//连接客户端实现登陆
connection = new signalR.HubConnectionBuilder().withUrl("/chatHub?userName="+ userName ).build();
//连接情况返回结果
connection.on("ReceiveMessage", function (result) {alert(result); });
//启动SignalR连接客户端
connection.start().catch(function(err){alert(err.toString());}).then(function () {});
});
public class ChatHub : Hub
{
// 用户与ID对应
private static Dictionary<string,string>_connections=new Dictionary<string,string>();
//连接客户端
public override Task OnConnectedAsync()
{
string userName = Context.GetHttpContext().Request.Query["userName"];
string pwd = Context.GetHttpContext().Request.Query["pwd"];
if (_connections.ContainsKey(userName)) {
if (UserInfo.userPwd.ContainsKey(userName))
{
Clients.Caller.SendAsync("ReceiveMessage", "登陆成功!");
//用户名添加(不存在的Add到字典表,存在的进行修改)
SendLogin(userName, comip);
}
else
{
Clients.Caller.SendAsync("ReceiveMessage", "重新登陆成功!");
//用户名添加(不存在的Add到字典表,存在的进行修改)
SendLogin(userName, comip);
}
}
return base.OnConnectedAsync();
}
//客户端连接成功保存用户名和客户都安Id
public void SendLogin(string username)
{
//判断用户有没有登陆过(没登陆过插入用户名和Id,登陆过修改用户名和Id)
if (!_connections.ContainsKey(username))
{
_connections(username, Context.ConnectionId);
}
else
{
_connections[username]= Context.ConnectionId;
}
}
//客户端关闭
public override Task OnDisconnectedAsync(Exception exception)
{
//这个会和连接相反,说明有客户端断线了
var a = Context.ConnectionId;//客户端Id
List<string> dik = valeToKey(_connections, a);//根据Id查出客户端名称
if (dik.Count == 1)
{
_connections.Remove(dik[0]);//删除掉字典表中这个人
}
return base.OnDisconnectedAsync(exception);
}
//根据value找到key
public List<string> valeToKey(Dictionary<string,string>dkv,string vle)
{
List<string> resultKey = new List<string>();
foreach (var key in dkv.Keys)
{
if (dkv[key] == vle)
{
resultKey.Add(key);
}
}
return resultKey;
}
}
发送消息有很多种,可以进行群发(Clients()-传参是所有要发送的客户端Id)、单发(Client()-传参是要发送的Id)和全部发送(All)都可以用。
/**此方法调用服务器方法
**单人发送消息
**调用SendByNumber方法
*/
var user="********";//要发送给谁
var information="xxxxxxxx";//要发送的消息
connection.invoke("SendByNumber", user, information).catch(function (err) {
return console.error(err.toString());
});
/**服务器调用此方法进行消息发送**/
connection.on("Seddgfsx", function (fhx) {
alert(fhx);
});
public async Task SendByNumber(string user,string information)
{
string userId = sctConnections(user);
await Clients.Client(_connections[user]).SendAsync("Seddgfsx", information);
}
发消息的原理其实也是很简单,在JavaScript方法中调用服务器方法,然后服务器通过user找到要发送是Id,再运用这个Id去调用这个客户端的方法将消息传给他。
感谢大家的阅读,也真心希望大家能有所收获,同样也感谢大家能提出宝贵的意见或者是建议,让更多的人在技术这条路上走得更加坦荡。