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;
},
};
Comments NOTHING