SignalR基本认识以及使用

什么是WebSocket、SignalR

WebSocket

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

SignalR

1、ASP.NET Core SignalR(以下简称SignalR),是.NET Core平台下对WebSocket的封装。
2、Hub(集线器),数据交换中心。

image-1660061256016

服务器向客户端发送数据

1、需求:Web聊天;站内通知。
2、传统HTTP:只能客户端主动发送请求。
3、传统方案:长轮询(Long Polling):其缺点是浏览器先向服务器端发送Ajax请求,但是服务器端不立即给浏览器端发送响应,而是一直挂起这个请求,直到服务器端有需要推送给客户端的消息,服务器端才把要推送的消息作为响应发送给浏览器。由于Http并不是为这种长轮询机制设计的,因此长轮询对服务器的资源消耗非常大,而且由于http是文本传输协议,因此数据传输效率低。

SignalR的基本使用

创建一个继承自Hub的类
using Microsoft.AspNetCore.SignalR;

namespace SignalRStudy.Hubs
{
    public class ChatRoomHub : Hub
    {
        //SignalR的基本使用

        public Task SendPublicMessage(string messgae)
        {
            //获取当前连接id
            var connid = this.Context.ConnectionId;
            var msg = $"{connid}:{DateTime.Now}发送了{messgae}";
            //SendAsync 是对SendCoreAsync的封装 
            //对所有人发送消息 只有一个异步方法可以 不写async 和 await
            //ReceivePublicMessage 为前端接受消息方法
            var res = Clients.All.SendAsync("ReceivePublicMessage", msg);
            return res;
        }

    }
}
Program
//1.在builder.Build(); 之前添加跨域白名单 
builder.Services.AddSignalR();

//允许访问的白名单
string[] urls = new[] { "http://localhost:3000" };
builder.Services.AddCors(options =>
    options.AddDefaultPolicy(builder => builder.WithOrigins(urls)
        .AllowAnyMethod().AllowAnyHeader().AllowCredentials())
);
var app = builder.Build();

//2.允许跨域 在UseHttpsRedirection之前Use
app.UseCors();
app.UseHttpsRedirection();

//3.
//添加对应的Hub请求路线
app.MapHub<ChatRoomHub>("/Hubs/ChatRoomHub");

编写前端项目。

安装SignalR的JavaScript客户端SDK:npm install @microsoft/signalr

vue3我也不怎么会,这个后续再慢慢学习,只是单纯的hello word页面改写的

<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>
</template>
<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 () {
                connection = new signalR.HubConnectionBuilder()
                    .withUrl('https://localhost:7298/Hubs/ChatRoomHub')
                    .withAutomaticReconnect().build();
                await connection.start();
                connection.on('ReceivePublicMessage', msg => {
                    state.messages.push(msg);
                });
            });
            return { state, txtMsgOnkeypress };
        },
    }
</script>

测试发送消息成功

image-1660061273645

本文内容大部分都为杨中科老师《ASP.NET Core技术内幕与项目实战》一书中内容,此文只是做学习记录,如有侵权,联系立马删除。