SignalR详解(简易聊天室案例)

SignalR是什么?

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

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

 如何使用SignalR?

主要从客户端与服务器端来分解使用的流程:

对于客户端(基于TypeScript):需要创建SignalR的连接服务

import "./css/main.css";
import * as signalR from "@microsoft/signalr";

const divMessages: HTMLDivElement = document.querySelector("#divMessages");
const tbMessage: HTMLInputElement = document.querySelector("#tbMessage");
const btnSend: HTMLButtonElement = document.querySelector("#btnSend");
const username = new Date().getTime();

// 创建与服务器端的连接,这个/hub即定位到后台的集线器文件目录
const connection = new signalR.HubConnectionBuilder()
    .withUrl("/hub")
    .build();

//这里写的一个消息名字为 "messageReceived" 对应于后台的发送消息名称
connection.on("messageReceived", (username: string, message: string) => {
    let messages = document.createElement("div");

    messages.innerHTML =
        `<div class="message-author">${username}</div><div>${message}</div>`;

    divMessages.appendChild(messages);
    divMessages.scrollTop = divMessages.scrollHeight;
});
//开启连接,有时可以在中间加上then
connection.start().catch(err => document.write(err));

tbMessage.addEventListener("keyup", (e: KeyboardEvent) => {
    if (e.key === "Enter") {
        send();
    }
});

btnSend.addEventListener("click", send);
//定义一个方法,发送消息定位到后台集线器的newMessage方法,并且置空输入框
function send() {
    connection.send("newMessage", username, tbMessage.value)
        .then(() => tbMessage.value = "");
}

发送消息也可以使用invoke

connection.invoke("方法名",发送的参数)

 

对于服务器端:需要创建集线器Hub并且在启动项中配置SignalR的服务

首先需要在启动项目中创建SignalR的服务

services.AddSignalR();

然后创建Hub集线器,另外还可以重写OnConnectedAsync和OnDisConnectedAsync方法来展示连接成功和断开连接时发生的动作

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace SignalRWebPack.Hubs
{
    public class ChatHub : Hub
    {
        //此处对应前台的send方法中映射到newMessage
        public async Task NewMessage(long username, string message)
        {
            await Clients.All.SendAsync("messageReceived", username, message);
        //如果只想被人接收,而自己不接收,可以将All换成others
        }
    }
}

前后台的关系流转可以用下图来表示

简单web聊天室

客户端代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    
</head>
<body>

    <div>
        <input type="text" id="userName" placeholder="用户名"/>
        <input type="text" id="message" name="message" value="" placeholder="在此输入需要发送的信息" />
        <button type="button" id="sendBtn">发送</button>
    </div>
    <div>
        <div>
            <h3>聊天信息</h3>
        </div>
        <div>
            <ul id="messageList" style="height:340px"></ul>
        </div>
    </div>

    <script src="lib/aspnet/signalr/dist/browser/signalr.js"></script>
    <script type="text/javascript">
        //连接
        const connection = new signalR.HubConnectionBuilder()
            .withUrl("/myChatHub")
            .configureLogging(signalR.LogLevel.Information)
            .build();
        connection.start().catch(err => console.error(err.toString()));

        connection.on("SendMessage", (user, message) => {
            const encodedMsg = user + "说:" + message;
            const li = document.createElement("li");
            li.textContent = encodedMsg;
            document.getElementById("messageList").appendChild(li);
        });

        document.getElementById("sendBtn").addEventListener("click", function () {
            var user = document.getElementById('userName').value;
            var message = document.getElementById('message').value;
            connection.invoke("SendMessage", user, message).catch(err => console.error(err.toString()));
        });
    </script>
</body>
</html>

 服务端代码:

using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace webchat
{
    public class MychatHub:Hub
    {
        public async Task SendMessage(string userName,string message)
        {
            await Clients.All.SendAsync("SendMessage", userName, message);
        }
        public override Task OnConnectedAsync()
        {
            return base.OnConnectedAsync();
        }
        public override Task OnDisconnectedAsync(Exception exception)
        {
            return base.OnDisconnectedAsync(exception);
        }
    }
}

 在starup.cs文件中添加SignalR服务以及路由

services.AddSignalR();
app.UseSignalR(route =>
            {
                route.MapHub<MychatHub>("/myChathub");
            });

 聊天室效果如下

 

参考博客:

https://www.cnblogs.com/cgzl/p/9515516.html

https://blog.csdn.net/qq_36825683/article/details/80758988?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight

https://www.cnblogs.com/yaopengfei/category/1202154.html (从websocket谈到signalR)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值