SignalR实现简单的Web端实时通讯,跳过WebSocket验证,Swagger加锁后不能访问接口,Script setup不支持动态绑定

版本.Net6+Vue3+Element-Plus

问题

  1. Swagger加锁后不能访问接口 (看第三步)
  2. 跳过WebSocket验证 (看第四步里面)
  3. 添加自定义接受方法 (看第四步)
  4. 不能使用

第一步、下载包

后端:
在这里插入图片描述
前端:命令

npm install @microsoft/signalr

第二步、加后端触发方法

后端:

public class ServerHub : Hub
    {
        /// <summary>
        /// 已连接的用户信息
        /// </summary>
        public static List<UserModel> OnlineUser { get; set; } = new List<UserModel>();

        private readonly ILogger<ServerHub> _logger;
        private readonly IHttpContextAccessor _accessor;

        public ServerHub(ILogger<ServerHub> logger, IHttpContextAccessor accessor)
        {
            _logger = logger;
            _accessor = accessor;
        }

        /// <summary>
        /// 当连接成功时执行
        /// </summary>
        public override Task OnConnectedAsync()
        {
            string connId = Context.ConnectionId;
            _logger.LogWarning("SignalR已连接");
            //验证Token    "access_token"这个值是默认的不要改
            var token= _accessor.HttpContext.Request.Query["access_token"];
            var user = JwtHelper.SerializeJwt(token);
            _logger.LogWarning("SignalR已连接,用户名:" + user.UserName);
            //连接用户 这里可以存在Redis
            var model= new UserModel
            {
                ConnectionId = connId,
                Token = token,
                UserName = user.UserName
            };
            OnlineUser.Add(model);
            
            //给当前连接返回消息 .Clients可以发多个连接ID
            // "ConnectResponse"这个是前端接收的方法名字
            Clients.Client(connId).SendAsync("ConnectResponse", 
                new ApiResult<UserModel>() 
                {
                    state=200,
                    data = model,
                    msg= user.UserName+"连接成功" 
                });
            return base.OnConnectedAsync();
        }
        
        /// <summary>
        /// 当连接断开时的处理
        /// </summary>
        public override Task OnDisconnectedAsync(Exception exception)
        {
            string connId = Context.ConnectionId;
            var model = OnlineUser.Find(u => u.ConnectionId == connId);
            int count = OnlineUser.RemoveAll(u => u.ConnectionId == connId);
            if (model != null)
            {
                //给当前连接返回消息 .Clients可以发多个连接ID
                // "DisconnectResponse"这个是前端接收的方法名字
                Clients.Client(connId).SendAsync("DisconnectResponse",
                new ApiResult<bool>()
                {
                    state = 1000,
                    data = true,
                    msg = "断开连接"
                });
            }
            return base.OnDisconnectedAsync(exception);
        }

        /// <summary>
        /// 自定义方法:接受用户的数进行推送
        /// </summary>
        /// <returns></returns>
        public async Task SendMessage(string user,string msg)
        {
            ApiResult<UserModel> result = new ApiResult<UserModel>();
            result.data = new UserModel
            {
                ConnectionId = Context.ConnectionId,
                Token = "",
                UserName = user
            };
            result.state = 200;
            result.msg = msg;

            //推送给所有连接ID的第一条数据
            await Clients.Clients(OnlineUser.Select(q=>q.ConnectionId).ToList()).SendAsync("SendMessage", result);
        }

        
    }

第三步、在Program.cs中添加配置

builder.Services.AddSignalR();

再向中间管道添加终结点

app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapHub<ServerHub>("/ServerHub");
    endpoints.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
});

Swagger加锁后不能访问接口
在这里插入图片描述
加锁后的配置方式稍微有点差别(我当时找了半天问题)
等于说把他拆出来了

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.UseAuthentication();
app.UseAuthorization();
app.MapHub<ServerHub>("/ServerHub");

第四步、加前端接收方法

前端: 重点注意没有

<template>
  <div>
    <input type="text" placeholder="请输入用户名" v-model="user" />
    <input type="text"  placeholder="请输入内容" v-model="msg">
    <button  @click="Submit">发送消息</button><br/>
    <textarea type="text"  v-model="txt" ></textarea>
  </div>
</template>

 <script>
    import store from '@/store/index' //这个可以不加,这个是我localStorage缓存的东西
    import * as signalR from "@microsoft/signalr"; 
  
   
   let hubUrl ="http://localhost:5193/serverHub";
 //实例化
const connection = new signalR.HubConnectionBuilder()
.withAutomaticReconnect()
.withUrl(hubUrl,
         {accessTokenFactory:()=>store.state.user.refreshToken,//添加Token验证
          skipNegotiation:true, //是否跳过协议 true
          transport:signalR.HttpTransportType.WebSockets //跳过Websocket协议
        })
.build();
//启动
connection.start().catch(err=>{connsole.log(err)});
export default({
  data(){return {
    txt:"",
      user: "",
     msg: ""
  }},
  
  methods: {
    Submit: function() {
      if(this.msg.trim()==""){
        alert("不能发送空白消息");
        return;
      }
      //访问自定义后端方法"SendMessage"
      connection.invoke("SendMessage", this.user, this.msg);
      this.msg = "";
    }
  },
created(){
var _this = this;
//"ConnectResponse" 与后端里面的名字对应,根据名字返回到这个方法里面
connection.on("ConnectResponse", function(data) {
      if(data.code==1)
          _this.txt = data.message;
 })
    //接收
connection.on("SendMessage", function(data) {
  if(data.code==1)
          _this.txt = data.message;
    
  })
}
})

</script>

结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/671b432330194b6db9375d5e830a3e6c.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值