ASP.NET Core SingleR Core:WebApi + .net 客户端开发

文章目录

前言

我之前稍微研究了一下SignalR Core。用起来还行。简单来说SignalR就是用来解决实时通讯的问题的。

ASP.NET Core SingleR:初次体验和简单项目搭建

SignalR支持三种客户端,C#,Java,JavaScirpt。基本够用了。本身就是微软开发的,肯定支持自己的语言。因为是Websocket的上层封装,所以也要支持Websocket的主要客户,JavaScirpt。不过我没想到有Java版本的,那这样双语言互通的问题也就解决了。

环境

  • .net core 8.0
  • visual studio 2022

Webapi开发测试

服务端开发

我们新建一个WebApi

按照我之前设置的

.NET Core webapi 从零开始在IIS上面发布后端接口

再添加一下上次添加的聊天室代码

ASP.NET Core SingleR:初次体验和简单项目搭建

Program.cs

csharp 复制代码
var builder = WebApplication.CreateBuilder(args);
//配置跨域
var MyPolicy = "MyPolicy";
builder.Services.AddCors(options =>
{
    options.AddPolicy(MyPolicy, policy =>
    {
        policy.AllowAnyHeader().AllowAnyOrigin().AllowAnyMethod();
    });
});
//启用SignalR
builder.Services.AddSignalR();

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
//添加swagger接口配置
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "API标题",
        Description = $"API描述,v1版本"
    });
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    //IncludeXmlComments 第二参数 true 则显示 控制器 注释
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename), true);
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
   
}

app.UseSwagger();
app.UseSwaggerUI();
//自动重定向到swgger文件
app.UseStatusCodePagesWithRedirects("/swagger/index.html");
app.UseCors(MyPolicy);
app.UseHttpsRedirection();

app.UseAuthorization();
//SignalR位置
app.MapHub<ChatHub>("/ChatHub");

app.MapControllers();

app.Run();

ChatHub

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

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

客户端开发

官方文档

ASP.NET Core SignalR .NET 客户端

为了方便操作的实时性,我们新建一个WPF程序

微软官方示例代码

新建项目

Nuget添加

添加代码

MainWindow.xaml
xml 复制代码
<Window x:Class="SignalR_WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SignalR_WPF"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">
    <Grid Margin="0,0,193.333,50.667">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="109*" />
            <ColumnDefinition Width="288*" />
        </Grid.ColumnDefinitions>
        <Button x:Name="connectButton"
                Content="Connect"
                HorizontalAlignment="Left"
                Margin="275.333,63,0,0"
                VerticalAlignment="Top"
                Width="95"
                Click="connectButton_Click"
                Height="41"
                Grid.Column="1" />
        <Button x:Name="sendButton"
                Content="Send Message"
                HorizontalAlignment="Left"
                Margin="275.333,113,0,0"
                VerticalAlignment="Top"
                Width="95"
                Click="sendButton_Click"
                Height="41"
                Grid.Column="1"
                IsEnabled="False" />
        <TextBox x:Name="messageTextBox"
                 HorizontalAlignment="Left"
                 Height="41"
                 Margin="82,113,0,0"
                 TextWrapping="Wrap"
                 VerticalAlignment="Top"
                 Width="311"
                 Grid.ColumnSpan="2" />
        <ListBox x:Name="messagesList"
                 HorizontalAlignment="Left"
                 Height="141"
                 Margin="82,170,0,0"
                 VerticalAlignment="Top"
                 Width="311"
                 RenderTransformOrigin="-0.304,0.109"
                 BorderThickness="1"
                 Grid.ColumnSpan="2"
                 BorderBrush="Gainsboro" />
        <TextBox x:Name="userTextBox"
                 HorizontalAlignment="Left"
                 Height="41"
                 Margin="82,57,0,0"
                 TextWrapping="Wrap"
                 VerticalAlignment="Top"
                 Width="311"
                 Grid.ColumnSpan="2" />
        <Label Content="User"
               HorizontalAlignment="Left"
               Height="31"
               Margin="39,63,0,0"
               VerticalAlignment="Top"
               Width="38" />
        <Label Content="Message"
               HorizontalAlignment="Left"
               Height="26"
               Margin="19,120,0,0"
               VerticalAlignment="Top"
               Width="58" />

    </Grid>
</Window>
MainWindow.xaml.cs
csharp 复制代码
using Microsoft.AspNetCore.SignalR.Client;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SignalR_WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        HubConnection connection;
        public MainWindow()
        {
            InitializeComponent();

            connection = new HubConnectionBuilder()
                .WithUrl("http://localhost:53353/ChatHub")
                .Build();

            #region snippet_ClosedRestart
            connection.Closed += async (error) =>
            {
                await Task.Delay(new Random().Next(0, 5) * 1000);
                await connection.StartAsync();
            };
            #endregion
        }

        private async void connectButton_Click(object sender, RoutedEventArgs e)
        {
            #region snippet_ConnectionOn
            connection.On<string, string>("ReceiveMessage", (user, message) =>
            {
                this.Dispatcher.Invoke(() =>
                {
                    var newMessage = $"{user}: {message}";
                    messagesList.Items.Add(newMessage);
                });
            });
            #endregion

            try
            {
                await connection.StartAsync();
                messagesList.Items.Add("Connection started");
                connectButton.IsEnabled = false;
                sendButton.IsEnabled = true;
            }
            catch (Exception ex)
            {
                messagesList.Items.Add(ex.Message);
            }
        }

        private async void sendButton_Click(object sender, RoutedEventArgs e)
        {
            #region snippet_ErrorHandling
            try
            {
                #region snippet_InvokeAsync
                await connection.InvokeAsync("SendMessage",
                    userTextBox.Text, messageTextBox.Text);
                #endregion
            }
            catch (Exception ex)
            {
                messagesList.Items.Add(ex.Message);
            }
            #endregion
        }
    }
}

运行结果

代码解析

SignalR的代码将服务器的输入和输出分为两类:

  • 输入:类似于Http的接口
  • 输出:类似于Http的回调,因为SignalR的数据是通关另一个口进行返回的

服务端 客户端 接口1 接口2 接口3 回调1 回调2 回调3 服务端 客户端

服务端



SignalR_Core builder.Services添加SignalR服务 app.MapHub添加多个SignalR服务 xxxHub Task,名字是服务器的接口 Client.Send服务器的回调 ...Hub服务

客户端




客户端 服务端 监听回调1 监听回调2 监听回调... 尝试连接+断线自动重连 接口发送数据 返回回调,触发之前监听的接口 客户端 服务端

所以我们一般的代码逻辑

  • 监听所有的回调
  • 尝试连接
  • 连接成功,发送接口
  • 服务器返回回调,回调到监听的接口

总结

我们目前是单接口,单回调。收发数据,那还是比较简单。那么如果我们想对SignalR的接口进行复杂的调用呢?下篇文章我会对这个进行思考和探索。

相关推荐
caihuayuan522 分钟前
前端面试2
java·大数据·spring boot·后端·课程设计
郭尘帅66644 分钟前
SpringBoot学习(上) , SpringBoot项目的创建(IDEA2024版本)
spring boot·后端·学习
野犬寒鸦1 小时前
MySQL索引详解(下)(SQL性能分析,索引使用)
数据库·后端·sql·mysql
.生产的驴5 小时前
SpringBoot 集成滑块验证码AJ-Captcha行为验证码 Redis分布式 接口限流 防爬虫
java·spring boot·redis·分布式·后端·爬虫·tomcat
野犬寒鸦7 小时前
MySQL索引使用规则详解:从设计到优化的完整指南
java·数据库·后端·sql·mysql
思考的橙子7 小时前
Springboot之会话技术
java·spring boot·后端
兆。10 小时前
电子商城后台管理平台-Flask Vue项目开发
前端·vue.js·后端·python·flask
weixin_4373982110 小时前
RabbitMQ深入学习
java·分布式·后端·spring·spring cloud·微服务·rabbitmq
西京刀客15 小时前
Go多服务项目结构优化:为何每个服务单独设置internal目录?
开发语言·后端·golang
李匠202415 小时前
C++GO语言微服务之gorm框架操作MySQL
开发语言·c++·后端·golang