.net5 signalR

1. 创建对应通信的Hub类

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace SignalRChat.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

### 2. 注入相关的服务
//Startup.cs文件中添加
using SignalRChat.Hubs;


//在ConfigureServices方法中添加
services.AddSignalR();

//设置跨域访问
            services.AddCors(options =>
            {
                //登录用户使用
                options.AddPolicy("any", builder =>
                {
                    builder.WithOrigins(
                        "http://127.0.0.1",
                        "http://localhost",
                        "http://192.168.2.171")
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();
                });
                ////公开使用
                //options.AddPolicy("all", builder =>
                //{
                //    builder.WithOrigins("*")
                //    .AllowAnyMethod()
                //    .AllowAnyHeader();
                //});
            });



//在Configure方法中添加
app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapHub<ChatHub>("/chatHub").RequireCors("any"); 
});


3. 跨域

Startup.cs文件中Configure方法中添加


            app.UseCors("any");

4. 获取客户端依赖的库

客户端需要用到的js文件可以通过如下方法获取(不要直接使用其他文档中给定的cdn地址,会有404的问题)

在“解决方案资源管理器”>中,右键单击项目,然后选择“添加”“客户端库”。
在“添加客户端库”对话框中,对于“提供程序”,选择“unpkg”。
对于“库”,输入 @microsoft/signalr@latest。
选择“选择特定文件”,展开“dist/browser”文件夹,然后选择 signalr.js 和 signalr.js。
将“目标位置”设置为 wwwroot/js/signalr/
选择“安装”

5. 客户端测试代码

记得调整.withUrl中对应的url和端口


<!DOCTYPE html>
<html>
<head>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script> -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/5.0.0/signalr.js"></script> -->
<script src="signalr.js"></script>

</head>
<body>
 <div class="container">
        <div class="row">
            <div class="col-2">User</div>
            <div class="col-4"><input type="text" id="userInput" /></div>
        </div>
        <div class="row">
            <div class="col-2">Message</div>
            <div class="col-4"><input type="text" id="messageInput" /></div>
        </div>
        <div class="row">&nbsp;</div>
        <div class="row">
            <div class="col-6">
                <input type="button" id="sendButton" value="Send Message" />
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-12">
            <hr />
        </div>
    </div>
    <div class="row">
        <div class="col-6">
            <ul id="messagesList"></ul>
        </div>
    </div>
<script>
const connection = new signalR.HubConnectionBuilder()
    //.withUrl("/chathub")
    .withUrl("http://127.0.0.1:5000/chatHub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

async function start() {
    try {
        await connection.start();
        console.log("SignalR Connected.");
    } catch (err) {
        console.log(err);
        setTimeout(start, 5000);
    }
};

connection.onclose(async () => {
    await start();
});


connection.on("ReceiveMessage", function (user, message) {
    var li = document.createElement("li");
    document.getElementById("messagesList").appendChild(li);
    // We can assign user-supplied strings to an element's textContent because it
    // is not interpreted as markup. If you're assigning in any other way, you 
    // should be aware of possible script injection concerns.
    li.textContent = `${user} says ${message}`;
});

document.getElementById("sendButton").addEventListener("click", function (event) {
   
    connection.invoke("SendMessage", "t", "hh").catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});

// Start the connection.
start();
</script>
</body>
</html>

6. 注意

因为涉及到跨域,所以web的测试页面需要发布才能使用

同时要保证跨域的配置正确

测试时可以临时配置跨域策略为下面的配置,但是不建议用在生产环境中

 app.UseCors(option => option
            .SetIsOriginAllowed(f => true)
            //.AllowAnyOrigin()
            //.WithOrigins("http://localhost")
            .AllowCredentials()
            .AllowAnyMethod().AllowAnyHeader());  //配置跨域
  1. 在接口中获取到hub对象
[ApiController]
    [Route("[controller]/[action]")]
    public class TestController : ControllerBase
    {

        private readonly IHubContext<TestHub> _hubContext;
        private readonly ILogger<TestController> _logger;


        public TestController(IHubContext<TestHub> hubContext)
        {
            _hubContext = hubContext;
        }



        [HttpPost]
        public void Send()
        {
            var urlList = new List<string> {
                "http://192.168.2.179:9700", "http://192.168.2.179:9600", "http://192.168.2.179:9500", "http://192.168.2.179:96", "http://192.168.2.179:9120"
                };

            var random = new Random();

            var urlIndex = random.Next(0, urlList.Count);

            //$@"{{""URL"":""{urlList[urlIndex]}""}}"
            _hubContext.Clients.All.SendAsync("UpdateView", "UpdateURL", new
            {
                URL = urlList[urlIndex]
            });
        }
    }

如果需要走ocelot转发,可以参考
ocelot转发signalr/socket

在接口中调用signalR

[ApiController]
[Route("[controller]/[action]")]
public class TestController : ControllerBase
{

    private readonly IHubContext<TestHub> _hubContext;
    private readonly ILogger<TestController> _logger;


    public TestController(IHubContext<TestHub> hubContext)
    {
        _hubContext = hubContext;
    }


    [HttpPost]
    public void Send()
    {
        _hubContext.Clients.All.SendAsync("UpdateView", "UpdateURL", new
        {
            URL = "test"
        });


    }
}

获取客户端ip、端口

//在Hub中使用

//获取经过代理的真实ip
//this.Context.GetHttpContext().Request.Headers["X-Real-IP"]

//获取ip
//this.Context.GetHttpContext().Connection.RemoteIpAddress

//获取端口
//this.Context.GetHttpContext().Connection.RemotePort

[参考]
教程:ASP.NET Core SignalR 入门

posted @   Hey,Coder!  阅读(153)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示