首页 > 其他分享 >SignalR基本使用

SignalR基本使用

时间:2022-09-27 21:33:56浏览次数:42  
标签:基本 WebSocket 服务器端 app 集线器 SignalR 使用 客户端

在传统的HTTP中,只能客户端主动向服务器端发起请求,服务器端无法主动向客户端发送消息。有的业务场景下,我们需要服务器端主动向客户端发送消息,比如Web聊天室、OA系统、站内消息等。

为了实现服务器端向客户端推送消息,在2008年诞生了WebSocket协议,并且该协议在2011年成为国际标准。目前所有的主流浏览器都已经支持WebSocket协议。WebSocket基于TCP(transmission control protocol,传输控制协议),支持二进制通信,因此通信效率非常高,它可以让服务器处理大量的并发WebSocket连接;WebSocket是双工通信,因此服务器可以高效地向客户端推送消息。

ASP.NET Core SignalR(以下简称SignalR)是.NET Core平台中对WebSocket的封装,从而让开发人员可以更简单地进行WebSocket开发。

虽然WebSocket是独立于HTTP的,但是我们一般仍然把WebSocket服务器端部署到Web服务器上,因为我们需要借助HTTP完成初始的握手,并且共享HTTP服务器的端口,这样就可以避免为WebSocket单独打开新的服务器端口。因此,SignalR的服务器端一般运行在ASP.NET Core项目中。

SignalR中一个重要的组件是集线器(hub),它用于在WebSocket服务器端和所有客户端之间进行数据交换,所有连接到同一个集线器上的程序都可以互相通信。我们既可以通过集线器来完成服务器端向客户端的消息推送,也可以完成客户端之间的消息推送,当然WebSocket也允许客户端向服务器端发送消息。
集线器.png
下面通过开发一个简单的聊天室来了解SignalR的基本使用。

第1步:创建一个ASP.NET Core Web API项目,安装Nuget包Microsoft.AspNetCore.SignalR.StackExchangeRedis,并且在项目中创建一个继承自Hub类的ChatRoomHub类,所有的客户端和服务器端都通过这个集线器进行通信。

public class ChatRoomHub : Hub
{
    public Task SendPublicMessage(string message)
    {
        string connId = this.Context.ConnectionId;
        string msg = $"{connId}{DateTime.Now}:{message}";
        return Clients.All.SendAsync("ReceivePublicMessage", msg);
    }
}

ChatRoomHub类中定义的方法可以被客户端调用,也就是客户端可以向服务器端发送请求,方法的参数就是客户端向服务器端传送的消息,参数的个数原则上来讲不受限制,而且参数的类型支持string、bool、int等常用的数据类型。
在ChatRoomHub类中,我们定义了一个方法SendPublicMessage,方法的参数message为客户端传递过来的消息。在第5行代码中,我们获得了当前发送消息的客户端连接的唯一标识ConnectionId;在第6行代码中拼接出一个包含连接ID、当前时间、客户端消息的字符串;随后我们把msg字符串以名字为“ReceivePublicMessage”的消息发送到所有连接到集线器的客户端上。

第2步:编辑Program.cs,在builder.Build之前调用builder.Services.AddSignalR注册所有SignalR的服务,在app.MapControllers之前调用app.MapHub<ChatRoomHub>("/Hubs/ChatRoomHub")启用SignalR中间件,并且设置当客户端通过SignalR请求“/Hubs/ChatRoomHub”这个路径的时候,由ChatRoomHub进行处理。

builder.Services.AddSignalR(); //注册所有SignalR的服务
string[] urls = new[] { "http://localhost:3000" };
builder.Services.AddCors(options =>
    options.AddDefaultPolicy(builder => 
        builder.WithOrigins(urls).AllowAnyMethod()
            .AllowAnyHeader().AllowCredentials())
);
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseCors();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapHub<ChatRoomHub>("/Hubs/ChatRoomHub"); //启用SignalR中间件
app.MapControllers();

第3步:我们需要编写一个静态HTML页面提供交互界面。按照前后端分离的理念,我们应该把HTML页面放到一个单独的前端项目中。创建一个前端项目,然后执行如下命令安装SignalR的JavaScript客户端SDK(software development kit,软件开发工具包):npm install @microsoft/signalr。

在SignalR的JavaScript客户端中:

  1. 使用HubConnectionBuilder来创建从客户端到服务器端的连接;
  2. 通过withUrl方法来设置服务器端集线器的地址,该地址必须是包含域名等的全路径,必须和在服务器端MapHub设置的路径一致;
  3. 通过withAutomaticReconnect设置自动重连机制。虽然withAutomaticReconnect不是必须设置的,但是设置这个选项之后,如果连接被断开,客户端就会尝试重连,因此使用起来更方便。需要注意的是,客户端重连之后,由于这是一个新的连接,因此在服务器端获得的ConnectionId是一个新的值。
  4. 对HubConnectionBuilder设置完成后,我们调用build就可以构建完成一个客户端到集线器的连接。
  5. 我们通过build获得的到集线器的连接只是逻辑上的连接,还需要调用start方法来实际启动连接。
  6. 一旦连接建立完成,我们就可以通过连接对象的invoke函数来调用集线器中的方法,我们也可以通过on函数来注册监听服务器端使用SendAsync发送的消息的代码。
<template>
  <input
    type="text"
    v-model="state.userMessage"
    v-on:keypress="txtMsgOnkeypress"
    />
    <div>
      <ul>
        <li v-for="(msg, index) in state.messages" :key="index">{{ msg }}</li>
      </ul>
    </div>
  </template>


<script>
  import { reactive, onMounted } from "vue";
  import * as signalR from "@microsoft/signalr";
  let connection;
  export default {
    name: "Login",
    setup() {
      const state = reactive({ userMessage: "", messages: [] });
      const txtMsgOnkeypress = async function (e) {
        if (e.keyCode != 13) return;
        await connection.invoke("SendPublicMessage", state.userMessage);
        state.userMessage = "";
      };
      onMounted(async function () {
        connection = new signalR.HubConnectionBuilder() // 创建从客户端到服务器端的连接
          .withUrl("https://localhost:7002/Hubs/ChatRoomHub") // 设置服务器端集线器的地址
          .withAutomaticReconnect() // 设置自动重连机制
          .build(); // 构建完成
        await connection.start(); // 启动
        // 通过on函数来注册监听服务器端使用SendAsync发送的消息的代码
        connection.on("ReceivePublicMessage", (msg) => {
          state.messages.push(msg);
        });
      });
      return { state, txtMsgOnkeypress };
    },
  };
</script>

可以看到,在onMounted方法中,我们创建并且启动了客户端到服务器端集线器的连接,并且监听了服务器端向客户端发送的“ReceivePublicMessage”消息,客户端还会把收到的消息添加到页面上。

在23到27行中,对用户在输入框内的按键进行监听,当用户按Enter键的时候,我们就调用集线器中的SendPublicMessage方法把用户输入的消息发送给服务器端,服务器端再把消息转发给连接到这个集线器的全部客户端。这样我们就实现了一个简单的聊天室。

接下来,启动ASP.NET Core项目和前端项目,然后打开两个聊天室页面,并分别在两个页面中发送一些消息。我们可以发现,在A页面中发送的消息,在B页面中能立即看到;在B页面中发送的消息,在A页面中也能立即看到。

本文学习参考自:ASP.NET Core技术内幕与项目实战

标签:基本,WebSocket,服务器端,app,集线器,SignalR,使用,客户端
From: https://www.cnblogs.com/nullcodeworld/p/16736072.html

相关文章

  • vs code使用技巧
    vscode是微软推出的一款开源免费的代码编辑器,可运行在Windows,Linux,MacOS平台,官方下载地址如下:https://code.visualstudio.com/如果系统版本比较旧(如Ubuntu16),安装新版......
  • 字符类型的使用和字符细节
    1、字符常量是用单引号(‘’)括起来的单个字符。如charc='a';charc2='中';2、Java中允许使用转义字符‘\’来将其后的字符转变为特殊字符型常量,例如charc3='\n';(......
  • Spring MVC框架:第四章:属性域使用(request域、session域、application域)
    第六节属性域使用(request域、session域、application域)1.request域在SpringMVC中,当我们想把一个对象存入请求域有很多种操作方式,用哪一个都可以。①使用Model对象@R......
  • C++学习 Day9-01 指针-定义及使用
    指针变量定义语法:数据类型*变量名;示例:intmain(){ //1、指针的定义 inta=10;//定义整型变量a //指针定义语法:数据类型*变量名; int*p; //指针变量......
  • python之基本数据类型
    python之基本数据类型目录基本数据类型(知识点整合)1.整型int2.浮点型float3.字符串string4.列表list5.字典dictionary6.布尔值bool7.元组tuple8.集合set基本数据类型(知......
  • 【python】使用python处理excel数据
      目标使用python处理excel文件的数据,基本操作包括:excel文件读写,增删sheet页。 调研python-pandas模块 实现读 写    sheet页修......
  • Java使用ProtoBuffer3时报错: Cannot resolve method 'isStringEmpty' in 'GeneratedM
    错误描述我的机器是MacM1,项目中使用了ProtoBuffer3。使用protoc程序,根据proto文件生成了Java代码。在编译Java项目的时候,报错:cannotresolvemethod'isstringempty'in......
  • MongoDB安装使用教程
    MongoDB安装使用教程介绍MongoDB是一个基于分布式文件存储的数据库,是一个文档数据库,支持的数据结构非常松散,是类似json的bson格式,可以存储比较复杂的数据类型。下载......
  • Git的使用
    Git的概念Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的项目Git的安装Git官网https://git-scm.com/下载安装直接下一步安装成功之......
  • 第02章 Windows11的基本使用
    第02章Windows11的基本使用第01阶段Java语言核心技术1.Windows11的介绍Windows11是由微软公司(Microsoft)开发的操作系统,应用于计算机和平板电脑等设备。也是全世界......