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>
相关推荐
超人不会飛15 分钟前
就着HTTP聊聊SSE的前世今生
前端·javascript·http
数通Dinner16 分钟前
异步Websocket构建聊天室
运维·网络·websocket·网络协议·信息与通信
蓝胖子的多啦A梦18 分钟前
Vue+element 日期时间组件选择器精确到分钟,禁止选秒的配置
前端·javascript·vue.js·elementui·时间选选择器·样式修改
夏天想21 分钟前
vue2+elementui使用compressorjs压缩上传的图片
前端·javascript·elementui
The_cute_cat22 分钟前
JavaScript的初步学习
开发语言·javascript·学习
海天胜景25 分钟前
vue3 el-table 列增加 自定义排序逻辑
javascript·vue.js·elementui
烛阴40 分钟前
XPath 进阶:掌握高级选择器与路径表达式
前端·javascript
独立开阀者_FwtCoder1 小时前
URL地址末尾加不加 "/" 有什么区别
前端·javascript·github
独立开阀者_FwtCoder1 小时前
Vue3 新特性:原来watch 也能“暂停”和“恢复”了!
前端·javascript·github
前端小巷子1 小时前
跨域问题解决方案:开发代理
前端·javascript·面试