杨中科 ASP.NETCORE 高级14 SignalR

1、什么是websocket、SignalR

服务器向客户端发送数据

1、需求:Web聊天;站内沟通。
2、传统HTTP:只能客户端主动发送请求
3、传统方案:长轮询(Long Polling)。缺点是?(1.客户端发送请求后,服务端要等到有数据返回,返回数据后,才方法连接。2.或者是每秒向服务器发送消息,询问是否有数据返回)
一台服务器,能处理得并发量是有限的,这种方式就会很消耗资源

WebSocket

1、WebSocket基于TCP 协议,支持二进制通信,双工通信。
2、性能和并发能力更强
3、WebSocket 服务器独立于HTTP协议,不过我们一般仍然把WebSocket 服务器端部署到Web服务器上,因为可以借助HTTP 协议完成初始的握手(可选),并且共享HTTP服务器得端口(主要)。(好处是:不需要单独开放一个端口)

SignalR

1、ASP.NET Core SignalR(以下简称SignalR)是.NET Core平台中对WebSocket的封装,从而让开发人员可以更简单地进行WebSocket开发。
2、Hub(集线器),数据交换中心
在这里插入图片描述
SignalR中一个重要的组件是集线器(hub),它用于在WebSocket服务器端和所有客户端之间进行数据交换,所有连接到同一个集线器上的程序都可以互相通信。我们既可以通过集线器来完成服务器端向客户端的消息推送,也可以完成客户端之间的消息推送,当然WebSocket也允许客户端向服务器端发送消息。

SignalR使用场景

按照官方的说法,signal能够方便的为应用提供实时的服务器端和客户端双向通信功能,相当于服务器端能够观察到客户端的实时更新,并且将这个更新广播推送,这是一个很有用的功能。SignalR适用场景如下:

1、需要从服务器进行高频率更新的应用。 示例包括游戏、社交网络、投票、拍卖、地图和 GPS 应用。
2、仪表板和监视应用。 示例包括公司仪表板、即时销售更新或旅行警报。
3、协作应用。 协作应用的示例包括白板应用和团队会议软件。
4、需要通知的应用。 社交网络、电子邮件、聊天、游戏、旅行警报和很多其他应用都需使用通知。

2、基本SignalR项目

需要分别编写服务器端Hub和前端代码

1、创建Web API项目,创建一个继承自Hub类

public class ChatRoomHub:Hub
{
	public Task SendPublicMessage(String message)
	{
		string connId = this.Context.ConnectionId;
		string msg = $"{connId}{DateTime.Now}{message}";
		//某个客户端发送了消息msg 将他广播到其他客户端,广播模式项目中不可取
		//All 表示连接到的所有客户端
		return Clients.All.SendAsync("ReceivePublicMessage",msg);
	}
}
builder.Service.AddSignalR()
在 app.MapControllers() 之前调用
app.MapHub<ChatRoomHub>("/Hubs/ChatRoomHub") //默认还要启用CORS

新建WebAPI 项目
在这里插入图片描述

编写MyHub类
在这里插入图片描述
添加配置文件
在这里插入图片描述

2、跨域

在 app.MapControllers() 之前调用
app.MapHub(“/Hubs/ChatRoomHub”) //默认还要启用CORS
在这里插入图片描述
在这里插入图片描述

基本SignalR项目2
builder.Services.AddSignalR();stringl] urls = new[] {"http://localhost:3000" };
builder.Services.AddCors(options =>
options.AddDefaultPolicy(builder => 
builder.WithOrigins(urls)
	.AllowAnyMethod().AllowAnyHeader().AllowCredentials())
);
var app = builder.Build();//这里省略其他UsexxX代码

app.UseCors();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapHub<ChatRoomHub>("/Hubs/chatRoomHub");
app.MapControllers();

完整代码



using SignalRHttps.Hubs;

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();

//跨域
string[] urls = new[] { "http://localhost:3000", "http://localhost:8080" };
builder.Services.AddCors(opt =>
                         {
    opt.AddDefaultPolicy(builder => builder.WithOrigins(urls).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
});

// 引用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();

app.UseHttpsRedirection();


app.UseAuthentication();
app.UseAuthorization();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting(); // 路由中间件

// 将路径请求传入到SingalR.Hub类型中
// 泛型中的名字对应于Hubs文件夹下的类文件的名字
app.MapHub<ProgressHub>("/progressHub");

app.MapControllers(); // 路由配置
app.Run();

3、前端代码

项目目录下新建 FrontEnd在这里插入图片描述

基本SignalR项目3
3、编写前端项目。
yarn create @vitejs/app 
项目名字安装SignalR的JavaScript客户端SDK:npm install@microsoft/signalr
<template>
<input type="text"v-model="state.userMessage" v-on:keypress="txtMsgOnkeypress"/><div><ul>
<li v-for="(msg,index) instate.messages" :key="index">{{msg}}</li>
</ul></div>
</template>

打开cmd 执行命令
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
成功
在这里插入图片描述
在这里插入图片描述

编写页面

在这里插入图片描述

基本SignalR项目4
<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(asyncfunction () {
	connection= newsignalR.HubConnectionBuilder()
	.withUrl('https://localhost:7112/Hubs/ChatRoomHub’)
	.withAutomaticReconnect().build();
	await connection.start();
connection.on('ReceivePublicMessage',msg =>{
state.messages.push(msg);
		});
		});
return { state, txtMsgOnkeypress };
	},
	}
</script>

效果图

在这里插入图片描述

在这里插入图片描述

3、SignalR的协议协商

协议协商

1、SignalR支持多种服务器推送方式:Websocket、Server-Sent Events、长轮询。默认按顺序尝试。
2、F12查看协商过程。
3、websocket和HTTP是不同的协议,为什么能用同一个端口
4、在【开发人员工具】的【网络】页签中看WebSocket通信过程。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值