SignalR 配置

发布于 11 天前  138 次阅读


1.客户端配置(web或者其他)

 const token = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoic3RyaW5nIiwianRpIjoiYjRkZmRlNDctYTg0MS00Y2YwLTg3MjYtNDYzNTk5ZmY0ZjFkIiwibmJmIjoxNzU1ODMyMjkzLCJleHAiOjE3NTU4NzU0OTMsImlzcyI6Im1pbmdzaGVueWkueHl6IiwiYXVkIjoibWluZ3NoZW55aS54eXoifQ.39dwX4qI6oH5i11TByPdw_P60zPSNJ4IEmJoDrTnGbI'
      const connection = new signalR.HubConnectionBuilder()
        .withUrl("http://localhost:5275/chatHub", {
          accessTokenFactory: () => token,
          skipNegotiation: true, // 跳过协商
          transport: signalR.HttpTransportType.WebSockets, // 强制 WebSocket,这一步一定要,否则会一直卡在协商状态
        })
        .configureLogging(signalR.LogLevel.Information)
        .build();
      // 修改此 URL 以匹配你的 Hub 地址

      // 3. 连接建立后的处理
      connection.on("ReceiveMessage", function (user, message) {
        // 当服务器调用 'ReceiveMessage' 方法时,此函数接收到服务端回调,并触发逻辑
        const msg = document.createElement("li");
        msg.textContent = `${user}: ${message}`;
        document.getElementById("messagesList").appendChild(msg);
        // 滚动到底部
        const list = document.getElementById("messagesList");
        list.scrollTop = list.scrollHeight;
      });

      // 4. 启动连接
      async function startConnection() {
        try {
          await connection.start();
          console.log("SignalR 已连接");
          document.getElementById("status").textContent =
            "连接状态: Connected";
          document.getElementById("status").style.color = "green";
        } catch (err) {
          console.error(err);
          document.getElementById(
            "status"
          ).textContent = `连接失败: ${err.toString()}`;
          document.getElementById("status").style.color = "red";
          // 可选:尝试重新连接
          setTimeout(startConnection, 5000);
        }
      }

      // 5. 启动连接
      startConnection();

      // 6. 处理发送按钮点击(这里为HTML+js实现)
      document
        .getElementById("sendButton")
        .addEventListener("click", async function (event) {
          event.preventDefault();
          const user = document.getElementById("userInput").value;
          const message = document.getElementById("messageInput").value;
          if (user && message) {
            try {
              // 调用服务器端的 'SendMessage' 方法
              await connection.invoke("SendMessage", user, message);
              // 清空输入框
              document.getElementById("messageInput").value = "";
            } catch (err) {
              console.error(err);
              alert(err.toString());
            }
          } else {
            alert("请输入你的名字.");
          }
        });

      // 7. 处理连接关闭 (可选)
      connection.onclose(async (error) => {
        console.log("连接错误: ", error);
        // 可以在这里实现自动重连逻辑
        // await startConnection();
      });
    

2.服务端配置(C#)

//在JWT配置中
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];

    // 如果是来自hub的请求,提取accessToken...
    var path = context.HttpContext.Request.Path;
    if (!string.IsNullOrEmpty(accessToken) &&
        (path.StartsWithSegments("/chatHub")))
    {
       //我这里是自动配置的JWT,如果是自己中间件验证token可以换成其他的请求头或者其他字段
        context.Request.Headers["Authorization"] = accessToken;
    }
    return Task.CompletedTask;
},

};
一个练习时长还差一年半的切图仔,有需求可联系 QQ:963827384
最后更新于 2025-08-22