利用signalR实现简单通信(Vue2+C#)

本次编辑器采用Visual Studio Code

官方文档链接

https://learn.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-10.0\&tabs=visual-studio-code

dotnet 命令安装

  1. 下载地址:https://dotnet.microsoft.com/zh-cn/download
  2. 安装完成之后打开vscode,打开终端
  3. 终端输入命令dotnet new webapp -o SignalRChat
  4. cdSignalRChat 目录下

添加 SignalR 客户端库

  1. 在集成终端中,在卸载任何早期版本(如果存在)后,运行以下命令,安装 LibMan。
bash 复制代码
dotnet tool uninstall -g Microsoft.Web.LibraryManager.Cli
dotnet tool install -g Microsoft.Web.LibraryManager.Cli

注意!!!一定要用cmd终端 别使用Git bash

接下来在SignalRChat 文件夹中打开终端输入命令

bash 复制代码
libman install @microsoft/signalr@latest -p unpkg -d wwwroot/js/signalr --files dist/browser/signalr.js

创建 SignalR 中心

在 SignalRChat 项目文件夹中,创建 Hubs 文件夹。

在 Hubs 文件夹中,使用以下代码创建 ChatHub 类:

c 复制代码
using Microsoft.AspNetCore.SignalR;

namespace SignalRChat.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

配置 SignalR

必须将 SignalR 服务器配置为将 SignalR 请求传递给 SignalR。 将以下突出显示的代码添加到 Program.cs 文件。(实则文档都有,本次只做搬运)

添加 SignalR 客户端代码

使用以下代码替换 Pages/Index.cshtml 中的内容:

html 复制代码
@page
<div class="container">
    <div class="row p-1">
        <div class="col-1">User</div>
        <div class="col-5"><input type="text" id="userInput" /></div>
    </div>
    <div class="row p-1">
        <div class="col-1">Message</div>
        <div class="col-5"><input type="text" class="w-100" id="messageInput" /></div>
    </div>
    <div class="row p-1">
        <div class="col-6 text-end">
            <input type="button" id="sendButton" value="Send Message" />
        </div>
    </div>
    <div class="row p-1">
        <div class="col-6">
            <hr />
        </div>
    </div>
    <div class="row p-1">
        <div class="col-6">
            <ul id="messagesList"></ul>
        </div>
    </div>
</div>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

在 wwwroot/js 文件夹中,使用以下代码创建 chat.js 文件:

js 复制代码
"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

//Disable the send button until connection is established.
document.getElementById("sendButton").disabled = true;

connection.on("ReceiveMessage", function (user, message) {
    var li = document.createElement("li");
    document.getElementById("messagesList").appendChild(li);
    // We can assign user-supplied strings to an element's textContent because it
    // is not interpreted as markup. If you're assigning in any other way, you 
    // should be aware of possible script injection concerns.
    li.textContent = `${user} says ${message}`;
});

connection.start().then(function () {
    document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
    return console.error(err.toString());
});

document.getElementById("sendButton").addEventListener("click", function (event) {
    var user = document.getElementById("userInput").value;
    var message = document.getElementById("messageInput").value;
    connection.invoke("SendMessage", user, message).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});

之后在SignalRChat 文件夹下输入dotnet run就可以启动了

如果看见上述执行结果,就代表成功了。此时打开localhost:5113 就可以访问了

当然上面的都是C#里的代码,由于作者是前端开发的,C#虽说里面有CSHTML的代码,但是由于项目使用的是Vue2,并且自己为了学习测试,必须要前后端分离

改造前后端分离

在之前的Program.cs 文件中,改写以下代码支持前端跨域访问

cs 复制代码
using SignalRChat.Hubs;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
builder.Services.AddCors();
var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseCors(options =>
{
    options.WithOrigins(["http://localhost:8080", "http://localhost:3000"]) // 前端应用的地址
           .AllowAnyHeader()
           .AllowAnyMethod()
           .AllowCredentials(); // 如果前端需要带 cookie 或认证,才加这个
});
app.UseRouting();

app.UseAuthorization();

app.MapStaticAssets();
app.MapRazorPages()
   .WithStaticAssets();

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

app.Run();

改完之后重新dotnet run命令执行

前端代码

首先
npm install @microsoft/signalr这个命令在vue2和vue3都通用的

signalr.js文件

js 复制代码
import * as signalR from "@microsoft/signalr";

class SignalRService {
  constructor() {
    this.connection = null;
  }

  // 连接到 SignalR hub
  connect() {
    this.connection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:5113/chathub") // .NET Core 服务中 hub 的地址
      .configureLogging(signalR.LogLevel.Information)
      .build();

    // 启动连接
    this.connection
      .start()
      .then(() => console.log("SignalR 连接成功"))
      .catch((err) => console.error("SignalR 连接失败:", err));

    // 监听服务器发送的消息
    this.connection.on("ReceiveMessage", (user, message) => {
      // 这里可以将消息传递给组件,例如通过事件总线或状态管理库
      console.log(`收到来自 ${user} 的消息:${message}`);
      // 假设使用 Vue 的事件总线
      this.$bus.$emit("receiveMessage", { user, message });
    });
  }

  // 发送消息到服务器
  sendMessage(user, message) {
    if (
      this.connection &&
      this.connection.state === signalR.HubConnectionState.Connected
    ) {
      this.connection
        .invoke("SendMessage", user, message)
        .catch((err) => console.error("发送消息失败:", err));
    } else {
      console.error("SignalR 未连接,无法发送消息");
    }
  }

  // 断开连接
  disconnect() {
    if (this.connection) {
      this.connection
        .stop()
        .then(() => console.log("SignalR 断开连接"))
        .catch((err) => console.error("SignalR 断开连接失败:", err));
      this.connection = null;
    }
  }
}

export default new SignalRService();

main.js文件

js 复制代码
import Vue from "vue";
import App from "./App.vue";
// 创建事件总线
Vue.prototype.$bus = new Vue();
Vue.config.productionTip = false;
new Vue({
  render: (h) => h(App),
}).$mount("#app");

vue页面代码

js 复制代码
<template>
  <div>
    <h2>实时消息</h2>
    <div>
      <input v-model="user" placeholder="请输入用户名" />
      <input v-model="message" placeholder="请输入消息内容" />
      <button @click="send">发送消息</button>
    </div>
    <div>
      <h3>消息列表</h3>
      <ul>
        <li v-for="(msg, index) in messages" :key="index">
          {{ msg.user }}: {{ msg.message }}
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import signalRService from "../utils/signalr";

export default {
  data() {
    return {
      user: "",
      message: "",
      messages: [],
    };
  },
  created() {
    // 连接到 SignalR hub
    signalRService.connect();

    // 监听事件总线上的消息
    this.$bus.$on("receiveMessage", (msg) => {
      this.messages.push(msg);
    });
  },
  beforeDestroy() {
    // 断开连接
    signalRService.disconnect();
    // 移除事件监听
    this.$bus.$off("receiveMessage");
  },
  methods: {
    send() {
      if (this.user && this.message) {
        signalRService.sendMessage(this.user, this.message);
        this.message = "";
      } else {
        alert("请输入用户名和消息内容");
      }
    },
  },
};
</script>

运行前端项目,就可以连接启动了,后面eventBus大家可以删掉

前端参考:https://jishuzhan.net/article/1949840778733334529

相关推荐
翔云 OCR API3 小时前
发票查验接口详细接收参数说明-C#语言集成完整示例-API高效财税管理方案
开发语言·c#
困惑阿三4 小时前
2025 前端技术全景图:从“夯”到“拉”排行榜
前端·javascript·程序人生·react.js·vue·学习方法
虫小宝4 小时前
高佣金的返利平台性能压测:从单接口到全链路的性能瓶颈分析
c#·linq
故事不长丨5 小时前
C#集合:解锁高效数据管理的秘密武器
开发语言·windows·c#·wpf·集合·winfrom·字典
深念Y6 小时前
仿B站项目 前端 4 首页 顶层导航栏
前端·vue·ai编程·导航栏·bilibili·ai开发
jghhh017 小时前
基于C#实现与三菱FX系列PLC串口通信
开发语言·算法·c#·信息与通信
故事不长丨7 小时前
C#队列深度剖析:解锁高效编程的FIFO密码
visualstudio·c#·wpf·多线程·winfrom·队列·queue
bugcome_com8 小时前
C# 反射(Reflection)超全解析
c#
bjzhang7510 小时前
Dorisoy.AMS--一款采用C# WinForm框架+SQLite数据库的企业/机构资产管理解决方案
sqlite·c#·资产管理
零度@11 小时前
Java消息中间件-Kafka全解(2026精简版)
java·kafka·c#·linq