长轮询问题在ABP中的解决方案,SignalR

问题来源:

前端请求后端动态生成资源的一种解决方案,防止http请求处于waiting态导致的499错误_董厂长的博客-CSDN博客

此问题自己的实现方式是长轮询,但是实际效果不够好。 

长轮询问题

服务器向客户端发送数据

1、需求:Web聊天;站内通知。

2、传统HTTP:只能客户端主动发送请求。

3、传统方案:长轮询(Long Polling)。缺点是 服务器🍐压力很大

 HTML5 中的WebSocket

1、WebSocket基于TCP协议,支持二进制通信,双工通信。(两端可以互相发送)

2、性能和并发能力更强。

3、WebSocket独立于HTTP协议,不过我们一般仍然把WebSocket服务器端部署到Web服务器上,因为可以借助HTTP协议完成初始的握手(可选),并且共享HTTP服务器的端口(主要)。

特别注意:webSocket 和 HTTP 是同一等级的东西,他们都是基于TCP协议的。 

http是文本通讯,一般会经历序列化和反序列化,消耗比较高,WebSocekt是二进制,消耗低。

那么在ABP中,我们使用SignalR

SignalR是什么,不过是封装罢了

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

3、编写前端项目。安装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) 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>

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董厂长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值