C#利用SignalR实现通信事例Demo

news2024/11/27 18:40:51

1.服务端安装SignalR的Nuget包

dotnet add package Microsoft.AspNet.SignalR --version 2.4.3

2.接下来,创建一个ChatHub类,它是SignalR通信的核心:

using Microsoft.AspNetCore.SignalR;

public class ChatHub : Hub
{
    public static Dictionary<string, string> user = new();
    
    public void Connect(string key)
    {
        if (user.ContainsKey(key)) { user.Remove(key); }
        user.Add(key,Context.ConnectionId);
        Console.WriteLine("("+ DateTime.Now +")客户端:"+ key + "上线成功!");
    }
    

    public async Task HandMsg(Chat chat)
    {
        chat.time = DateTime.Now;
        ChatHandlerService handler;
        switch ( (Command) chat.cmd)
        {
            case Command.PRIVATE:
                handler = new PrivateServiceImpl();
                await handler.execute(chat,user,Context,Clients);
                break; 
            case Command.LINERADIO:
                handler = new LineradioServiceImpl();
                await handler.execute(chat, user, Context, Clients);
                break;
        }
    }
}
  •  这个是信息处理的提取ChatHandlerService
public interface ChatHandlerService
{
    Task execute(Chat chat,Dictionary<string, string> user,HubCallerContext context, IHubCallerClients clients);
}
  •  这个是单聊的具体实现
public class PrivateServiceImpl : ChatHandlerService
{
    public Task execute(Chat chat, Dictionary<string, string> user, HubCallerContext context, IHubCallerClients clients)
    {
        if (user.ContainsKey(chat.target!))
        {
            string target = user[chat.target!];
            clients.Client(target).SendAsync("receive", chat);
            return Task.CompletedTask;
        }
        chat.message = "好友不在线";
        clients.Client(context.ConnectionId).SendAsync("receive", chat);
        return Task.CompletedTask;
    }
}
  • 这个是 通知全部在线的用户

public class LineradioServiceImpl : ChatHandlerService
{

    public async Task execute(Chat chat, Dictionary<string, string> user, HubCallerContext context, IHubCallerClients clients)
    {
        await clients.All.SendAsync("receive", chat); 
    }
}
  •  指令枚举
public enum Command
{
    PRIVATE = 300,
    GROUP = 400,
    LINERADIO = 500
}
  • 聊天模型 
public class Chat
{
    public string userKey { get; set; } = null!;
    
    public string? target { get; set; }
    
    public string? message { get; set; }
        
    public int type { get; set; }
    
    public int cmd { get; set; }
    
    public DateTime time { get; set; }
}

提示:Connect是连接的实例方法,当客户端成功后在回调使用此方法,HandMsg是我的信息处理方法,其中你可以不用我的service和实现层,直接在ChatHub类中使用你传入的数据就可以了。

3.在Program中使用

builder.Services.AddSignalR();

builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(
        builder =>
        {
            builder.WithOrigins("http://localhost")
                .AllowAnyHeader()
                .WithMethods("GET", "POST")
                .AllowCredentials();
        });
});


app.MapHub<ChatHub>("/chathub");

提示:注意需要配置跨域

4.编写客服端代码

<!DOCTYPE html>
<html lang="">
<head>
    <title>SignalR</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.0/signalr.min.js"></script>
    <meta charset="utf-8" />
</head>
<style>
    input {
        border-radius: 12px;
        padding: 5px 5px;
    }
    .sendButton {
        width:200px;
        border-radius: 12px;
        background: #3F95FF;
        padding: 6px 0;
        border: none;
        color: white;
    }
</style>
<body>

<h1>SignalR</h1>
<div style="display: flex;gap: 12px;flex-direction: column">
    <div>
        <label for="target">发送给:</label>
        <input type="text" id="target" />
    </div>
    <div>
        <label for="msg">信息:</label>
        <input type="text" id="msg" />
    </div>
    <div>
        <button type="button" id="sendButton" class="sendButton">发送</button>
    </div>
</div>
<div>
    <ul id="messagesList"></ul>
</div>

<script>

    /**
     * 获取URL中的查询参数值
     *
     * @param {string} name - 查询参数名
     * @returns {string|null} - 查询参数值,如果不存在则返回null
     */
    function getQueryParam(name) {
        const urlParams = new URLSearchParams(window.location.search);
        return urlParams.get(name);
    }

    /**
     * 初始化SignalR连接
     */
    const connection = new signalR.HubConnectionBuilder()
        .withUrl("https://localhost:7066/chathub")
        .configureLogging(signalR.LogLevel.Information)
        .build();

    /**
     * 监听服务器发送的消息
     *
     * @param {object} res - 接收到的消息对象
     */
    connection.on("receive", res => {
        const li = document.createElement("li");
        li.textContent = `${ res.userKey  }: ${res.message}`;
        document.getElementById("messagesList").appendChild(li);
    });

    /**
     * 启动SignalR连接,并调用Connect方法向服务器发送连接请求
     */
    connection.start()
        .then(() => {
            connection.invoke("Connect", getQueryParam("key"))
                .catch(err => console.error(err.toString()));
        })
        .catch(function (err) {
            return console.error(err.toString());
        });

    /**
     * 发送按钮点击事件处理函数
     *
     * @param {Event} event - 事件对象
     */
    document.getElementById("sendButton").addEventListener("click", event => {
        const target = document.getElementById("target").value;
        const message = document.getElementById("msg").value;
        let sendMessage = {
            userKey: getQueryParam("key"),
            target: target,
            cmd: 300,
            message: message
        };

        /**
         * 调用服务器HandMsg方法发送消息
         */
        connection.invoke("HandMsg", sendMessage)
            .then(res => {
                const li = document.createElement("li");
                li.textContent = `我: ${message}`;
                document.getElementById("messagesList").appendChild(li);
                document.getElementById("msg").value = "";
            })
            .catch(err => console.error(err.toString()));

        event.preventDefault();
    });
</script>
</body>
</html>

浏览器需要在后面跟上参数Key 

http://localhost/?key=10086

 

5.完整代码地址

https://gitee.com/byte1026/signal-r.git

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1851709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

苹果mac电脑救星CleanMyMac让我的电脑重获新生!

&#x1f389; 发现电脑的救星&#xff01;CleanMyMac让我的电脑重获新生&#xff01; CleanMyMac绿色免费版下载如下&#xff1a;记得保存哈&#xff0c;以防失效&#xff1a; https://pan.quark.cn/s/9b08114cf404 CleanMyMac X2024全新版下载如下: https://wm.makeding.…

awdawdad

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;C 创作时间 &#xff1a;2024年6月20日 最后&#xff1a; 十分感谢你可以耐着性子把它读完和我可以坚持写到这里&#xff0c;送几句话&#xff0c;对你&#xff0c;也对我&#xff1a; 1.一个冷知识&#xff1a; …

多路h265监控录放开发-(9)通过拖拽到窗口完成渲染

xcamera_widget.h class XCameraWidget :public QWidget {Q_OBJECTpublic:XCameraWidget(QWidget* p nullptr);//渲染视频void Draw();//123//清理资源,再一个窗口被覆盖后 清理之前窗口生成的资源1~XCameraWidget();//123 private:XDecodeTask* decode_ nullptr;//123XDemu…

高考填报志愿选专业,要善于发掘自身优势

每年的高考季&#xff0c;如何填报志愿又再成为困扰家长以及学生的难题&#xff0c;可能在面对大量的专业时&#xff0c;无论是考生还是家长都不知道应该如何选择&#xff0c;好的专业孩子不一定有优势&#xff0c;感兴趣的冷门专业又担心日后找工作难。 实际上&#xff0c;专业…

购买服务器,并安装宝塔

前言&#xff1a; 我们在开发项目时&#xff0c;总会遇到一个问题&#xff0c;就是将我们开发好的项目上传的公网中。对于中小型的项目&#xff0c;我们可以通过购买服务器进行项目的上线。 我们的项目一般是部署在Linux环境中。如果你不是专业的运维人员&#xff0c;可能对于…

『这世界上有无忧无虑的孩子,和永远焦虑的父母』

昨天&#xff0c;准确说是今天&#xff0c;凌晨两点多&#xff0c;被队友薅起来&#xff0c;严肃认真地讨论孩子的教育问题。 我们家的小神兽六岁&#xff0c;一年级了。从去年幼升小的阶段&#xff0c;我们就计划着好好培养孩子&#xff0c;在这一年间&#xff0c;给小朋友报过…

Linux下VSCode的安装和基本使用

应用场景&#xff1a;嵌入式开发。 基本只需要良好的编辑环境&#xff0c;能支持文件搜索和跳转&#xff0c;就挺OK的。 之所以要在Linux下安装&#xff0c;是因为在WIN11上安装后&#xff0c;搜索功能基本废了&#xff0c;咋弄都弄不好&#xff0c;又不方便重装win系统&#x…

HTTP网络协议

1.HTTP &#xff08;1&#xff09;概念&#xff1a; Hyper Text Transfer Protocol&#xff0c;超文本传输协议规定了浏览器和服务器之间数据传输的规则。 &#xff08;2&#xff09;特点 基于TCP协议:面向连接&#xff0c;安全基于请求-响应模型的:一次请求对应一次响应HTTP协…

2.APP测试-安卓adb抓取日志

1.打开手机的开发者模式&#xff0c;打开USB调试 &#xff08;1&#xff09;小米手机打开开发者模式&#xff1a; 【设置】-【我的设备】-【全部参数信息】-快速多次点击【OS版本】-进入开发者模式 &#xff08;2&#xff09;连接手机和电脑&#xff0c;手机打开USB调试 【设置…

“论软件系统建模方法”必过范文,软考高级,系统架构设计师论文

论文真题 软件系统建模(Software System Modeling)是软件开发中的重要环节,通过构建软件系统模型可以帮助系统开发人员理解系统、抽取业务过程和管理系统的复杂性,也可 以方便各类人员之间的交流。软件系统建模是在系统需求分析和系统实现之间架起的一 座桥梁,系统开发人…

Linux服务升级:Almalinux 升级 WebCatlog桌面程序

目录 一、实验 1.环境 2.Almalinux 升级 WebCatlog桌面程序 二、问题 1.Ubuntu如何升级 WebCatlog桌面程序 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统版本软件IP备注Almalinux9.4 WebCatlog 192.168.204.150 &#xff08;2&#xff09;Termi…

【物联网】NB-IoT

目录 一、什么是NBIOT 二、NB-IoT的特点 三、NBIOT的工作状态 四、移远NB-IoT模块及AT指令 一、什么是NBIOT NB-IoT&#xff08;Narrow Band Internet of Things&#xff09;窄带物联网&#xff0c;构建于蜂窝网络&#xff0c;所占用的带宽很窄&#xff0c;只需约180KHz&am…

mysql的安装和连接

一.数据库相关概 念 1.数据库 存储数据的仓库,数据是有组织的进行存储,简称DB。 2.数据库管理系统 操纵和管理数据库的大型软件,简称DBM。 3.SQL 操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准。简称SQL。 二.市面上流行的数据库 1.ORACLE 2.MySQL …

定个小目标之刷LeetCode热题(27)

这道题&#xff0c;我们可以使用动态规划&#xff0c;假设数组元素范围是>0,那么递推关系式表示为 imax MAX(imax * nums[i], nums[i])&#xff0c;由于本题数组元素范围是整数&#xff0c;即存在负数&#xff0c;最大可能变最小&#xff0c;最小可能变最大&#xff0c;所…

指纹浏览器与虚拟机的区别及在跨境电商中的应用

在如今数字化世界中&#xff0c;隐私和安全变得愈发重要。许多人在网络上进行敏感操作&#xff0c;如网上购物、在线银行、社交媒体管理等。为了保护自己的隐私&#xff0c;人们常常会寻求一些额外的工具&#xff0c;比如指纹浏览器和虚拟机。这两种工具在保护个人隐私方面都有…

【Qt】学习Day1

文章目录 Qt简介创建第一个Qt程序创建过程介绍main函数工程文件头文件控件源文件快捷键按钮控件常用API对象树坐标系 信号和槽自定义信号自定义槽函数触发自定义的信号案例-下课后&#xff0c;老师触发饿了信号&#xff0c;学生响应信号&#xff0c;请客吃饭重载信号连接信号La…

生成式AI和LLM的应用场景

简单说就是LLM能干啥&#xff1a; 1. 聊天机器人&#xff08;Chatbots&#xff09;&#xff1a; • 基于下一词预测的基本聊天功能。 2. 文本生成&#xff08;Text Generation&#xff09;&#xff1a; • 根据提示生成文章或作文。 • 总结对话内容&#xff0c;将对话作为…

github配置可拉取项目到本地

首先配置用户名和邮箱&#xff1a; git config --global user.name 自己的名字git config --global user.email 自己的邮箱配置完之后检查一下&#xff1a; git config --global user.namegit config --global user.email如果提示的是自己配置好的名字和邮箱就Ok 然后拉取githu…

汇聚荣做拼多多运营怎么样?

汇聚荣做拼多多运营怎么样?在电商行业竞争日益激烈的今天&#xff0c;拼多多作为一家迅速崛起的电商平台&#xff0c;吸引了众多商家入驻。对于汇聚荣这样的企业而言&#xff0c;选择在拼多多上进行商品销售和品牌推广&#xff0c;无疑需要一套高效的运营策略。那么&#xff0…

MSPM0G3507 ——GPIO例程讲解2——simultaneous_interrupts

主函数&#xff1a; #include "ti_msp_dl_config.h"int main(void) {SYSCFG_DL_init();/* Enable Interrupt for both GPIOA and GPIOB ports */NVIC_EnableIRQ(GPIO_SWITCHES_GPIOA_INT_IRQN); //启用SWITCHES——A的中断 NVIC_EnableIRQ(GPIO_S…