版本.Net6+Vue3+Element-Plus
问题
- Swagger加锁后不能访问接口 (看第三步)
- 跳过WebSocket验证 (看第四步里面)
- 添加自定义接受方法 (看第四步)
- 不能使用
第一步、下载包
后端:
前端:命令
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);//连接用户 这里可以存在Redisvar 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, //是否跳过协议 truetransport: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>
结果: