前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ASP.NET Core + Vue3 实现 SignalR 通讯

ASP.NET Core + Vue3 实现 SignalR 通讯

作者头像
郑子铭
发布2023-12-15 12:54:29
5990
发布2023-12-15 12:54:29
举报
文章被收录于专栏:DotNet NB && CloudNative

SignalR

从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方法将消息发送给该用户。这样,用户就能收到特定的消息。

代码实现

代码语言:javascript
复制
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

代码语言:javascript
复制
//注册signalr
builder.Services.AddSignalR();
//注册hub  这里的路径是我的Hub类在项目中的路径
app.MapHub<MyHub>("/SignalR/MyHub");

让后前端这里在vue项目中下载@microsoft/signalr包

代码语言:javascript
复制
npm i @microsoft/signalr --save

创建一个myHub.js文件

代码语言:javascript
复制
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("/Signalr/Myhub");相同。

withAutomaticReconnect()用于启用自动重连功能。这意味着如果连接断开,SignalR将自动尝试重新建立连接,以确保保持实时通信。.build()方法构建并返回一个SignalR连接对象。conn.start();和SignarlR启动建立连接。

让后的话这里简单模拟了一下数据库的登录

Api部分

代码语言:javascript
复制
[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部分

代码语言:javascript
复制
<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>

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SignalR
  • 代码实现
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档