SignalR 服务端/SignalR C#客户端/SignalR js客户端

服务端

Program.cs

SignalRHub 是自定义的操作类,/chathub 是客户端访问的路由

builder.Services.AddSignalR();
builder.Services.AddSingleton<SignalRUsers>();


app.MapHub<SignalRHub>("/chathub");

SignalRUsers 客户端列表

public class SignalRUsers
{
	// 保存客户端的列表
    public ConcurrentDictionary<string, string> list { get; set; } 
    public SignalRUsers()
    {
        list = new System.Collections.Concurrent.ConcurrentDictionary<string, string>();
    }
}

SignalRHub

public class SignalRHub : Hub
{
    readonly SignalRUsers users;

    public SignalRHub(SignalRUsers _users) {
        users = _users;
    }



    /// <summary>
    /// 连接事件
    /// </summary>
    /// <returns></returns>
    public override Task OnConnectedAsync()
    {
        // 获取客户端自定义id
        var userid = Context.GetHttpContext().Request.QueryString.Get("userid");

        //客户端连接id
        var id = Context.ConnectionId;

        //将客户端添加到列表
        if(!users.list.ContainsKey(userid))
        {
            users.list.TryAdd(userid, id);
        }
        else
        {
            //每次重新连接,客户端连接的id都不一样,这里更新客户端连接id
            users.list[userid] = id;
        }

        return base.OnConnectedAsync();
    }

    /// <summary>
    /// 客户端断连事件
    /// </summary>
    /// <param name="exception"></param>
    /// <returns></returns>
    public override Task OnDisconnectedAsync(Exception? exception)
    {
        return base.OnDisconnectedAsync(exception);
    }

    /// <summary>
    /// 发送消息
    /// 也可以由客户端调用
	/// 可以创建多个类似方法实现复杂功能
    /// </summary>
    /// <param name="user"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task SendMessage(string user, string message)
    {
		//取得客户端连接id
		var id = users.list[user];

		//触发所有客户端定义的"ReceiveMessage"方法
		await Clients.All.SendAsync("ReceiveMessage", user, message);

		//触发指定客户端定义的"ReceiveMessage"方法
		await Clients.Clients(id).SendAsync("ReceiveMessage", user, message);
    }

}

QueryString取值的方法
public static string Get(this QueryString query, string name)
{
    var str = query.ToString().Trim('?');

    if (string.IsNullOrEmpty(str)) return null;

    var arr = str.Split('&');
    var dic = new Dictionary<string, string?>();
    foreach (var i in arr)
    {
        var item = i.Split('=');
        dic.Add(item[0], item.Length > 1 ? item[1] : null);
    }

    var q = dic.Any(x => x.Key == name);//[name];//.FirstOrDefault(x => x.Key == name);
    if (!q) return null;
    return System.Web.HttpUtility.UrlDecode(dic[name]);
    return "";
}

服务端在其它业务类中调用SignalRHub中的方法,实现操控客户端

 //注入 Hub类
 private readonly IHubContext<SignalRHub> _hubContext;

 public NotificationService(IHubContext<SignalRHub> hubContext)
 {
     _hubContext = hubContext;
	 
	 //向所有客户端发送消息
	 _hubContext.Clients.All.SendAsync("ReceiveMessage", "123456", "66666");
 }

C#客户端

NuGet 添加包 Microsoft.AspNetCore.SignalR.Client

Program.cs


//注册客户端
builder.Services.AddSingleton<Client>();

//注册一个后台任务,定时检查连接状态,重连
builder.Services.AddHostedService<SClient>();

Client

using Microsoft.AspNetCore.SignalR.Client;

public class Client
{
    HubConnection _connection;

    public Client() {
        _connection = new HubConnectionBuilder()
            .WithUrl("http://localhost:5047/chatHub?userid=654321") // 替换为你的 SignalR Hub 的 URL  
            .Build();

        // 订阅 Hub 发送的消息  
        _connection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            Console.WriteLine($"Received: {message}");
        });
    }

    
    public void Send()
    {
        // 调用服务端指定方法
        _connection.SendAsync("SendMessage", "654321","123456789");
    }

    /// <summary>
    /// 连接或者重连服务器
    /// </summary>
    public void ReConnected()
    {
        //判断连接状态
        if (_connection != null && _connection.State == HubConnectionState.Disconnected)
        {
            Console.WriteLine("连接服务器");
            // 开始连接  
            _connection.StartAsync();
            
            //是否连接成功
            if(_connection.State == HubConnectionState.Connecting)
            {
                Console.WriteLine("连接成功");
            }
            else
            {
                Console.WriteLine("连接失败");
            }
        }
    }

}

SClient

public class SClient : BackgroundService
{
    //引入客户端类
    Client _sc;
    public SClient(Client sc) {
        _sc = sc;
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        Task.Run(() =>
        {
            while (true)
            {
                _sc.Send();//发送消息到服务端
                _sc.ReConnected();//重连
                Task.Delay(5000).Wait();//每5秒检查一次状态
            }
        });

        return Task.CompletedTask;
    }

}

js客户端

右键项目-添加-客户端库
提供程序选择 unpkg ,搜索 signalr ,选择microsoft/signalr
选择特定文件
dist-browser-signalr.jssignalr.min.js
引入signalr.jssignalr.min.js


//创建连接对象 userid 是自定义的客户端id
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub?userid=123456").build();



//客户端方法,由服务端触发
connection.on("ReceiveMessage", function (user, message) {
    
    console.log(`${user} says ${message}`);
});

//是否连接成功
var _isConn = false;
connection.start().then(function () {
    //连接成功
    _isConn = true;

    var user = "123456";//客户端id,经过服务端可以将消息发送到指定的客户端
    var message = "666";//消息内容

    //调用服务端方法
    connection.invoke("SendMessage", user, message).catch(function (err) {
        return console.error(err.toString());
    });

}).catch(function (err) {
    //连接失败
    return console.error(err.toString(),666);
});
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_42199478

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值