问题来源:
此问题自己的实现方式是长轮询,但是实际效果不够好。
HTML5 中的WebSocket
1、WebSocket基于TCP协议,支持二进制通信,双工通信。(两端可以互相发送)
2、性能和并发能力更强。
3、WebSocket独立于HTTP协议,不过我们一般仍然把WebSocket服务器端部署到Web服务器上,因为可以借助HTTP协议完成初始的握手(可选),并且共享HTTP服务器的端口(主要)。
特别注意:webSocket 和 HTTP 是同一等级的东西,他们都是基于TCP协议的。
http是文本通讯,一般会经历序列化和反序列化,消耗比较高,WebSocekt是二进制,消耗低。
1、ASP.NET Core SignalR(以下简称SignalR),是.NET Core平台下对WebSocket的封装。
2、Hub(集线器),数据交换中心。
需要分别编写服务器端Hub和前端代码。
1、创建Web API项目,创建一个继承自Hub类
这段代码 的 意思:某个客户端连接到HUB,调用此方法,然后广播给所有连接到同一个HUB的客户端
public class ChatRoomHub:Hub
{
public Task SendPublicMessage(string message)//message是 服务器端接收到客户端的消息
{
string connId = this.Context.ConnectionId;//获取当前链接到HUB的链接字符串ID 不同的链接有对应的id
string msg = $"{connId} {DateTime.Now}:{message}";
return Clients.All.SendAsync("ReceivePublicMessage", msg);
// 服务器端向客户端发送消息 第一个参数是服务器端的名字
// Clients是HUB类的一个属性,不要迷惑
}
}
2、在项目里面注册 AddSingnalR 的服务
builder.Services.AddSignalR()
app.MapControllers()之前
调 app.MapHub<ChatRoomHub>(“/Hubs/ChatRoomHub”)
//默认还要启用CORS。
然后在MapControllers中:
解读一下,仍和客户端访问 /MyHub 这个路径的时候,都会交给MyHub class来处理
什么是MapControllers?
MapControllers is used to map any attributes that may exist on the controllers, like, [Route], [HttpGet], etc. From Microsoft: Adds endpoints for controller actions to the Microsoft.AspNetCore.Routing.IEndpointRouteBuilder without specifying any routes. Explain: This says it will map url to controller and action, you need specify your own route
注意还要开启CROS
复习:CORS原理:在服务器的响应报文头中通过access-control-allow-origin告诉浏览器允许跨域访问的域名。
A、在Program.cs的“var app=builder.Build()”这句代码之前注册
string[] urls = new[] { "http://localhost:3000" };
builder.Services.AddCors(options =>
options.AddDefaultPolicy(builder => builder.WithOrigins(urls)
.AllowAnyMethod().AllowAnyHeader().AllowCredentials()));
B、在Program.cs的app.UseHttpsRedirection()这句代码之前增加一行app.UseCors()
<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>
<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 () {
// 创建了 signalR 的链接!!
connection = new signalR.HubConnectionBuilder()
.withUrl('https://localhost:7112/Hubs/ChatRoomHub')//写全路径啊!
.withAutomaticReconnect().build();//重连机制 非必需
await connection.start();//启动
connection.on('ReceivePublicMessage', msg => {
state.messages.push(msg); //看!接收到服务器端端消息的时候,才执行哦!
});
});
return { state, txtMsgOnkeypress };
},
}
</script>
今天这个b学习先到此为止,关于更多的关于signalR的细节,等过两天再开一贴
前后端一起开放真累啊🤔
</template>
因篇幅问题不能全部显示,请点此查看更多更全内容