1. ASP.NET Core
ASP.NET Core是一个跨平台、高性能及开源的框架,用于生成基于云且连接互联网的新式应用程式。
官方文档:ASP.NET documentation | Microsoft Learn
2. ASP.NET Core SignalR
ASP.NET Core SignalR是开源库,用于服务端与客户端建立实时通信,可以自动管理连接;SignalR支持WebSockets、服务器发送的事件和长轮询。
官方文档:ASP.NET Core SignalR JavaScript 客户端 | Microsoft Learn
3. 编译环境
本文编译软件使用Visual Studio 2022与VS Code,服务端使用.NET6框架和C#编程语言,客户端使用Vue3框架、Vue-CLI和TypeScript编程语言以及Element UI组件。
4. 服务端代码编写
创建基于C#的ASP.NET Core Web API项目,命名为“core-server”。
在“Program.cs”文件里编写如下代码:
using core_server.Hubs;
using core_server.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers(); // 添加控制器
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// 引用SignalR
builder.Services.AddSignalR();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// 使用跨域
app.UseCors(x => x.SetIsOriginAllowed(_ => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting(); // 路由中间件
// 将路径请求传入到SingalR.Hub类型中
// 泛型中的名字对应于Hubs文件夹下的类文件的名字
app.MapHub<ProgressHub>("/progressHub");
app.MapControllers(); // 路由配置
app.Run();
在“core-server”下新建“Hubs”文件夹,在其下新建“ProgressHub.cs”,代码如下:
using Microsoft.AspNetCore.SignalR;
namespace core_server.Hubs
{
public class ProgressHub: Hub
{
// 每个客户端连接后, 都会触发此方法
public override async Task OnConnectedAsync()
{
await Clients.Client(Context.ConnectionId).SendAsync("SetHubConnId", Context.ConnectionId);
await base.OnConnectedAsync();
}
}
}
在“core-server”下的“Controllers”控制器文件夹下新建“ProgressControler.cs”文件,代码如下:
using Microsoft.AspNetCore.Mvc;
using core_server.Hubs;
using core_server.Models;
using Microsoft.AspNetCore.SignalR;
using System.Diagnostics;
using System;
namespace core_server.Controllers
{
[ApiController]
[Route("api/progress")] // 路由
public class ProgressController: Controller
{
private readonly ILogger<ProgressController> _logger;
private readonly IHubContext<ProgressHub> progressHubContext;
public ProgressController(ILogger<ProgressController> logger, IHubContext<ProgressHub> _hubContext)
{
_logger = logger;
progressHubContext = _hubContext;
}
[HttpPost]
public async Task<IActionResult> Port(Dictionary<string, string> inModel)
{
Dictionary<string, string> outModel = new Dictionary<string, string>();
int progress = 0;
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(500);
progress = i * 10;
// UpdProgress用于客户端请求的方法或事件
await progressHubContext.Clients.All.SendAsync("UpdProgress", progress);
}
outModel["ResultMsg"] = "上传图片完成,正在处理中...";
outModel["status"] = "200";
return Json(outModel);
}
[HttpGet]
public async Task<IActionResult> Port1()
{
int progress = 0;
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(1000); // 暂停1秒
progress = i * 10;
await progressHubContext.Clients.All.SendAsync("HandleProgress", progress);
}
return Accepted(1);
}
}
}
至此服务端代码书写完毕,项目文件夹:
启动运行,浏览器弹出Swagger UI界面,可以进行API测试。
5. 前端代码编写
创建Vue脚手架项目,使用TypeScript,在JavaScript中亦可,安装signalR和axios。
npm install @microsoft/signalr
npm install axios // yarn add axios
在“main.ts”中配置axios。
import axios from "axios";
axios.defaults.baseURL = "https://localhost:7103/"; // 服务端地址
// 全局挂载axios
app.config.globalProperties.$http = axios;
在“views“文件夹里创建HomeView.vue,代码如下 :
<template>
<el-container class="map-container">
<el-header height="45px">
<el-row :gutter="20">
<el-col :span="4"><img class="logo" src="../assets/logo.png" /></el-col>
<el-col :span="16"><h2>测试进度条</h2></el-col>
<el-col :span="4"></el-col>
</el-row>
</el-header>
<el-container>
<el-container class="main-container">
<el-main>
<el-steps :active="1" align-center space="420px">
<el-step title="上传图片" :icon="Edit" />
<el-step title="处理中..." :icon="Upload" />
<el-step title="处理完成" :icon="Picture" />
</el-steps>
<div class="demo-progress">
<el-progress
type="circle"
:percentage="progressUpload"
:status="finishedUpload"
/>
<el-progress
type="circle"
:percentage="progressHandle"
:status="finishedHandle"
/>
<el-progress type="circle" :percentage="100" status="success" />
</div>
<div class="progress">
<el-button type="primary" @click="StartProgress"
>开始执行</el-button
>
<br />
<el-tag v-if="isShow" effect="dark" type="success" class="result"
>执行结果: {{ message }}</el-tag
>
</div>
</el-main>
</el-container>
</el-container>
</el-container>
</template>
<script lang="ts">
import { ref, defineComponent, reactive, getCurrentInstance } from "vue";
import { ElMessage } from "element-plus";
import { Edit, Picture, Upload } from "@element-plus/icons-vue";
import * as signalR from "@microsoft/signalr";
export default defineComponent({
name: "HomeView",
setup() {
let progressUpload = ref(0);
let progressHandle = ref(0);
let message = ref("");
let isShow = ref(false);
let hub = reactive({
connection: {},
HubConnId: "",
resultInfo: {},
});
let finishedUpload = ref("");
let finishedHandle = ref("");
// #region
// 与服务器建立连接
const connectionServer = (hub.connection =
new signalR.HubConnectionBuilder()
.withUrl("https://localhost:7103/progressHub")
.build());
connectionServer
.start()
.then(() => {
ElMessage({
message: "服务器连接成功了",
type: "success",
});
})
.catch((error) => {
ElMessage.error(`服务器连接失败了\r${error.message.toString()}`);
});
connectionServer.onclose((error) => {
ElMessage.error(`服务器疑似断开了\r${error?.message.toString()}`);
});
connectionServer.on("SetHubConnId", (id) => {
hub.HubConnId = id;
});
connectionServer.on("UpdProgress", (percent) => {
progressUpload.value = percent;
});
connectionServer.on("HandleProgress", (percent) => {
progressHandle.value = percent;
});
// 使用axios
const internalInstance = getCurrentInstance();
const axios = internalInstance?.appContext.config.globalProperties.$http;
async function StartProgress() {
ElMessage({
message: "开始上传图片",
type: "success",
});
isShow.value = true;
const postData = {};
postData["HubConnId"] = hub.HubConnId;
progressUpload.value = 0;
progressHandle.value = 0;
finishedUpload.value = "";
finishedHandle.value = "";
message.value = "正在执行中...";
const { data: res } = await axios.post("api/progress", hub.resultInfo);
if (res.status !== 200 + "") {
finishedUpload.value = "exception";
return ElMessage.error("上传图片失败了, 请重试");
}
finishedUpload.value = "success";
message.value = res.ResultMsg;
const res1 = await axios.get("api/progress");
console.log(res1);
if (res1.status !== 202) {
finishedHandle.value = "exception";
return ElMessage.error("图片处理失败了, 请重试");
}
finishedHandle.value = "success";
message.value = "处理已完成";
}
// #endregion
return {
progressUpload,
progressHandle,
message,
isShow,
hub,
finishedUpload,
finishedHandle,
Edit,
Picture,
Upload,
StartProgress,
};
},
});
</script>
<style lang="scss" scoped>
.map-container {
height: 100%;
}
.logo {
height: 40px;
}
h2 {
margin-left: 12px;
letter-spacing: 0.06em;
color: #fff;
font-size: 20px;
height: 40px;
line-height: 40px;
}
.el-header {
background-color: rgb(26, 54, 82);
display: flex;
justify-content: space-between;
padding-left: 0;
font-size: 22px;
align-items: center;
}
.main-container {
background-color: #eee;
}
.demo-progress {
display: flex;
justify-content: center;
margin-left: 150px;
}
.demo-progress .el-progress--line {
margin-bottom: 15px;
width: 500px;
}
.demo-progress .el-progress--circle {
margin-right: 288px;
}
.el-steps {
padding-bottom: 20px;
}
:deep(.el-step__icon.is-icon) {
width: 40px;
background-color: #eee;
}
.progress {
margin: 3% 12%;
.result {
margin-top: 20px;
font-size: 14px;
}
}
</style>
启动运行:
文章来源:https://www.toymoban.com/news/detail-456622.html
文章来源地址https://www.toymoban.com/news/detail-456622.html
到了这里,关于服务端使用ASP.NET Core SignalR与Vue3(TypeScript与JavaScript)前端建立通信(以进度条为例)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!