從ASP.NET Core 3.0版本開始,SignalR的Hub已經集成到了ASP.NET Core框架中。因此,在更高版本的ASP.NET Core中,不再需要單獨引用Microsoft.AspNetCore.SignalR包來使用Hub。 在項目創建一個類繼承Hub, 首先是寫一個Create ...
從ASP.NET Core 3.0版本開始,SignalR的Hub已經集成到了ASP.NET Core框架中。因此,在更高版本的ASP.NET Core中,不再需要單獨引用Microsoft.AspNetCore.SignalR包來使用Hub。
在項目創建一個類繼承Hub,
首先是寫一個CreateConnection方法
ConnectionId是SignalR中標識的客戶端連接的唯一標識符,
將userId和ConnectionId關聯起來,這樣就可以實現指定給某一個或一些用戶發送消息了。
SendMessageToUser方法用於向特定的用戶發送消息。它接受兩個參數:userId表示要用於接收消息的用戶標識,message表示要發送的消息內容。
該方法的主要作用是根據userId從記憶體緩存(IMemoryCache)中獲取與之關聯的ConnectionId,然後使用Clients.Client(connectionId.ToString())方法找到對應的客戶端連接,並通過SendAsync方法將消息發送給該用戶。這樣,用戶就能收到特定的消息。
public class MyHub : Hub
{
private readonly IMemoryCache memoryCache;
public MyHub(IMemoryCache memoryCache)
{
this.memoryCache = memoryCache;
}
public void CreateConnection(int userId)
{
// 將用戶標識與 ConnectionId 關聯起來
memoryCache.Set(userId, Context.ConnectionId);
}
public async Task SendMessageToUser(int userId, string message)
{
if (memoryCache.TryGetValue(userId, out var connectionId))
{
await Clients.Client(connectionId.ToString()).SendAsync("ReceiveMessage", message);
}
}
}
在program文件中註冊hub
//註冊signalr
builder.Services.AddSignalR();
//註冊hub 這裡的路徑是我的Hub類在項目中的路徑
app.MapHub<MyHub>("/SignalR/MyHub");
———————————————————————————————————————————————————————————————————————————
讓後前端這裡在vue項目中下載@microsoft/signalr包
npm i @microsoft/signalr --save
創建一個myHub.js文件
import * as signalr from '@microsoft/signalr';
const conn = new signalr.HubConnectionBuilder()
.withUrl('http://localhost:5124/SignalR/Myhub')
.withAutomaticReconnect()
.build();
export default conn;
.withUrl('http://localhost:5124/SignalR/Myhub')這裡的路徑一定要和在api項目中的Program配置的app.MapHub
withAutomaticReconnect()用於啟用自動重連功能。這意味著如果連接斷開,SignalR將自動嘗試重新建立連接,以確保保持實時通信。
.build()方法構建並返回一個SignalR連接對象。
conn.start();和SignarlR啟動建立連接。
———————————————————————————————————————————————————————————————————————————
讓後的話這裡簡單模擬了一下資料庫的登錄
Api部分
[Route("api/[controller]/[action]"), ApiController]
public class TestController : ControllerBase
{
List<SysUser> userList = new List<SysUser>()
{
new SysUser(1,"王鶴棣","123456"),
new SysUser(2,"吳磊","123456"),
new SysUser(3,"趙露思","123456")
};
[HttpPost]
public ActionResult Login(SysUser sysUser)
{
var user = userList.Where(s => s.userName == sysUser.userName && s.userPwd == sysUser.userPwd).FirstOrDefault();
if (user is not null)
{
return Ok(user.userId);
}
return Ok("失敗");
}
}
public record SysUser(int? userId,string userName,string userPwd);
Vue部分
<script setup>
import {ref,reactive,onMounted} from 'vue';
import axios from 'axios';
import myHub from './httpTools/myHub'; //導入hub
const loginUser=reactive({
userName:'王鶴棣',
userPwd:'123456',
});
const loginBtn= ()=>{
axios.post('http://localhost:5159/api/test/login',loginUser)
.then(async res => {
console.log(res);
alert('成功');
//這裡在登錄成功之後調用服務端在MyHub類的CreateConnection方法,
//把登錄成功之後返回的userId傳過去
//使客戶端與服務端建立連接
if(myHub.state.toString()!="Connected"){
await myHub.start();
}
myHub.invoke("CreateConnection",res.data);
})
}
//這裡的ReceiveMessage用於接受伺服器發送的消息
//這個ReceiveMessage名字是自己定義的
onMounted(() => {
myHub.on('ReceiveMessage', (message) => {
console.log("MyHub接受到的消息:"+message);
alert(message);
})
})
const message=ref();
const sendUserId=ref();
const sendMessage=()=>{
myHub.invoke("SendMessageToUser",Number(sendUserId.value),message.value)
}
</script>
<template>
<input type="text" v-model.trim="loginUser.userName" placeholder="用戶名">
<input type="text" v-model.trim="loginUser.userPwd" placeholder="密碼">
<button @click="loginBtn">確定</button>
<input type="text" v-model="message">
<select v-model="sendUserId">
<option value="1">王鶴棣</option>
<option value="2">吳磊</option>
<option value="3">趙露思</option>
</select >
<button @click="sendMessage">發送消息</button>
</template>