ASP.NET Core SignalR向部分客户端发消息

筛选客户端

  1. 客户端筛选的3个参数:ConnectionId、组和用户Id(它对应ClaimTypes.NameIdentifier的Claim)。
  2. Hub的Groups属性为IGroupManager属性,可以对组成员进行管理。查看类型的成员。
  3. Hub的Clients属性为IHubCallerClients类型,可以对连接到当前集线器的客户端进行筛选。查看类型的成员。
  4. IClientProxy类型。无法知道具体有哪些客户端调用SendAsync()方法向筛选的客户端发送消息。
  5. 实现聊天室私聊。

IGroupManager 接口 (Microsoft.AspNetCore.SignalR) | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.signalr.igroupmanager?view=aspnetcore-9.0

IHubCallerClients 接口 (Microsoft.AspNetCore.SignalR) | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.signalr.ihubcallerclients?view=aspnetcore-9.0

cs 复制代码
public async Task SendPrivateMsg(string UserName, string message)
{
    var user = await userManager.FindByNameAsync(UserName);
    long userId = user.Id;
    string currentUserName = this.Context.UserIdentifier;
    await this.Clients.User(userId.ToString()).SendAsync("ReceivePrivateMsg", currentUserName, message );
}
javascript 复制代码
<template>
  <div>公屏:
    <input type="text" v-model="state.userMessage" v-on:keypress="txtMsgOnkeypress" />
  </div>
  <div>私聊:
    目标用户名:<input type="text" v-model="state.privateMsg.toUserName" />
    <input type="text" v-model="state.privateMsg.msg" v-on:keypress="txtPrivateMsgOnkeypress" />
  </div>
  <div>
    用户名<input type="text" v-model="state.loginData.username" />
    密码<input type="password" v-model="state.loginData.password" />
    <button v-on:click="loginClick">登录</button>
  </div>
  <div>
    <ul>
      <li v-for="(msg, index) in state.messages" :key="index">{
  
  { msg }}</li>
    </ul>
  </div>
</template>

<script>
import { reactive } from 'vue';
import * as signalR from '@microsoft/signalr';
import axios from 'axios';

let connection;
export default {
  name: 'Login',
  setup() {
    //创建响应式对象
    const state = reactive({
      accessToken: "", userMessage: "", messages: [],
      loginData: { userName: "", password: "" },
      privateMsg: { toUserName: "", msg: "" }
    });

    //SignalR连接
    const startConn = async function () {
      const transport = signalR.HttpTransportType.WebSockets;
      const options = { skipNegotiation: true, transport: transport };
      options.accessTokenFactory = () => state.accessToken;
      connection = new signalR.HubConnectionBuilder()
        .withUrl('https://localhost:7181/MyHub', options)
        .withAutomaticReconnect().build();
      try {
        await connection.start();
      } catch (err) {
        alert(err);
        return;
      }

      //注册ReceivePublicMessage事件,接收消息,添加到messages数组
      connection.on('ReceivePublicMessage', msg => {//监听服务器端发送过来的信息
        state.messages.push(msg);
      });
      //注册SendPrivateMessage事件,接收消息,添加到messages数组
      connection.on('ReceivePrivateMsg',(fromUserName,msg) => {//监听服务器端发送过来的信息
        state.messages.push(fromUserName+"私聊说:"+msg);
      });
    }

    //点击登录
    const loginClick = async function () {
      const resp = await axios.post('https://localhost:7181/api/Demo/Login', state.loginData)
        .then((response) => {
          state.accessToken = response.data;
          startConn()
        })
    };

    //按下回车键发送消息,调用SendPublicMessage方法,发送消息,清空输入框
    const txtMsgOnkeypress = async function (e) {
      if (e.keyCode != 13) return;
      await connection.invoke("SendPublicMessage", state.userMessage);
      state.userMessage = "";
    };

    //按下回车键发送私聊消息,调用SendPrivateMessage方法,发送消息,清空输入框
    const txtPrivateMsgOnkeypress = async function (e) {
      if (e.keyCode != 13) return;
      await connection.invoke("SendPrivateMsg", state.privateMsg.toUserName,state.privateMsg.msg);
      state.privateMsg.msg = "";
    };

    //返回响应式对象和方法
    return { state, txtMsgOnkeypress,txtPrivateMsgOnkeypress, loginClick };
  },
}
</script>
相关推荐
北极糊的狐2 分钟前
父组件向子组件传参时,传递数组和对象类型的参数的方法
前端·javascript·vue.js
一颗不甘坠落的流星36 分钟前
【HTML】iframe 标签 allow 权限汇总(例如添加复制粘贴权限)
前端·javascript·html
forestsea43 分钟前
现代 JavaScript 加密技术详解:Web Crypto API 与常见算法实践
前端·javascript·算法
骑自行车的码农2 小时前
🍂 React DOM树的构建原理和算法
javascript·算法·react.js
北极糊的狐2 小时前
Vue3 中父子组件传参是组件通信的核心场景,需遵循「父传子靠 Props,子传父靠自定义事件」的原则,以下是资料总结
前端·javascript·vue.js
看到我请叫我铁锤3 小时前
vue3中THINGJS初始化步骤
前端·javascript·vue.js·3d
q***25213 小时前
SpringMVC 请求参数接收
前端·javascript·算法
谢尔登3 小时前
defineProperty如何弥补数组响应式不足的缺陷
前端·javascript·vue.js
T***u3335 小时前
前端框架在性能优化中的实践
javascript·vue.js·前端框架
jingling5556 小时前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js