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>
相关推荐
旷世奇才李先生5 分钟前
Next.js 安装使用教程
开发语言·javascript·ecmascript
Mintopia2 小时前
四叉树:二维空间的 “智能分区管理员”
前端·javascript·计算机图形学
慌糖2 小时前
RabbitMQ:消息队列的轻量级王者
开发语言·javascript·ecmascript
Mintopia2 小时前
Three.js 深度冲突:当像素在 Z 轴上玩起 "挤地铁" 游戏
前端·javascript·three.js
MrSkye2 小时前
🔥JavaScript 入门必知:代码如何运行、变量提升与 let/const🔥
前端·javascript·面试
爱学习的茄子2 小时前
深入理解JavaScript闭包:从入门到精通的实战指南
前端·javascript·面试
zhanshuo3 小时前
不依赖框架,如何用 JS 实现一个完整的前端路由系统
前端·javascript·html
讨厌吃蛋黄酥3 小时前
智能前端新纪元:语音交互技术与安全实践全解析
javascript
1234Wu3 小时前
React Native 接入 eCharts
javascript·react native·react.js
脑袋大大的11 小时前
JavaScript 性能优化实战:减少 DOM 操作引发的重排与重绘
开发语言·javascript·性能优化