使用JS和SignalR完成双向通信

发布时间 2023-12-16 23:47:16作者: 万金流

如题,比NodeJS下直接websocket来的复杂。

web端

html:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>SignalR Example</title>
 5     <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>
 6 </head>
 7 <body>
 8     <h1>SignalR Example</h1>
 9 
10     <script>
11         // 创建 SignalR 连接
12         var connection = new signalR.HubConnectionBuilder()
13             .withUrl("http://localhost:5267/chathub")
14             .build();
15 
16         // 注册事件处理程序
17         connection.on("messageReceived", function (message) {
18             console.log(message);
19         });
20 
21         // 启动连接
22         connection.start()
23             .then(function () {
24                 console.log("SignalR connection started.");
25             })
26             .catch(function (err) {
27                 console.error(err.toString());
28             });
29 
30         // 发送消息
31         function sendMessage() {
32             var message = document.getElementById("messageInput").value;
33             connection.invoke("sendMessage", message)
34                 .catch(function (err) {
35                     console.error(err.toString());
36                 });
37         }
38     </script>
39 
40     <input type="text" id="messageInput" />
41     <button onclick="sendMessage()">Send Message</button>
42 </body>
43 </html>

说明:

1、第5行引用官方SignalR的js库。官方位置(版本升级,链接可能会变。这里给官方文档位置图)

 2、17行的事件是给服务端回调用的。

3、33行调用服务器方法,发送数据。

 

服务端:

新建的是asp.net的空项目,一点点添加内容。

思想:

1、SignalR的类,继承自Hub。

2、在管道里配置它,书写路径映射即可。

3、默认禁止跨域(这一点和websocket不同),前后端分离调试需要注意。

代码(路径略):

ChatHub.cs:

 1 using Microsoft.AspNetCore.SignalR;
 2 
 3 namespace SignalRChat.Hubs
 4 {
 5     public class ChatHub : Hub
 6     {
 7         public async Task SendMessage(string message)
 8         {
 9             await Clients.All.SendAsync("messageReceived", "server:"+message);
10         }
11     }
12 }

第7行的方法名称,通常由客户端调用。(见前面html的第33行)

第9行向客户端发送事件和参数。(对应html的第17行)

Program.cs:

 1 using SignalRChat.Hubs;
 2 
 3 namespace WebApplication1
 4 {
 5     public class Program
 6     {
 7         public static void Main(string[] args)
 8         {
 9             var builder = WebApplication.CreateBuilder(args);
10 
11             builder.Services.AddSignalR();
12 
13             builder.Services.AddCors(options =>
14             {
15                 options.AddDefaultPolicy(
16                     builder =>
17                     {
18                         builder.WithOrigins("http://127.0.0.1:5500")
19                             .AllowAnyHeader()
20                             .WithMethods("GET", "POST")
21                             .AllowCredentials();
22                     });
23             });
24 
25             var app = builder.Build();
26 
27             app.UseCors();
28 
29             app.MapHub<ChatHub>("/chatHub");
30 
31             app.MapGet("/", () => "Hello World!");
32 
33             app.Run();
34         }
35     }
36 }

说明:11-23、27-29行为添加。


 

至此,可以运行。

 感受:看官网介绍,听开发者朋友的感受,SignalR对websocket等多个长连接协议进行了封装,提供了多种方法,能够适应很多场合和复杂情况。单纯论简单的web长连接,它确实没有js/nodejs版的websocket直观、简单。微软的风格,一来就高大上,不知道又会劝退多少人,会不会把自己玩死。