这是一个极其简陋的聊天室!

这个例子只是在官方的例子上加了 Group 的用法而已,主要是官方给的 Group 的例子就两行代码,看不出效果.

第一步:修改 chat.js

"use strict";

//创建一个连接
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build(); //定义客户端的 ReceiveMessage 方法
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
var encodedMsg = user + " says " + msg;
var li = document.createElement("li");
li.textContent = encodedMsg;
document.getElementById("messagesList").appendChild(li);
}); //给"Send Message"按钮添加点击事件
document.getElementById("sendButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value; //调用服务端的 SendMessage 方法
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
}); //给"进入聊天室"按钮添加点击事件
document.getElementById("goChatRoom").addEventListener("click", function () {
goChatRoom();//开启连接
document.getElementById("outChatRoom").style.display = "block";
this.style.display = "none";
}); //给"退出聊天室"按钮添加点击事件
document.getElementById("outChatRoom").addEventListener("click", function () {
outChatRoom();//关闭连接
this.style.display = "none";
document.getElementById("goChatRoom").style.display = "block";
}); //开启连接
function goChatRoom() {
connection.start().catch(function (err) {
return console.error(err.toString());
});
} //关闭连接
function outChatRoom() {
connection.stop();
}

第二步:定义强类型中心

    public interface IChatClient
{
//就算是这种强类型方式,客户端定义的方法名也必须和这个方法名一样,包括签名.
Task ReceiveMessage(string user, string message);
} public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
{
//向所有连接的客户端中,在 "room" 小组的客户端发送消息
await Clients.Group("room").ReceiveMessage(user, message);
} public override async Task OnConnectedAsync()
{
//当客户端连接上后,将其归属到 "room" 小组.
await Groups.AddToGroupAsync(Context.ConnectionId, "room");
await base.OnConnectedAsync();
} public override async Task OnDisconnectedAsync(Exception exception)
{
//当客户端断开连接后,将其从 "room" 小组移除,一定要移除!不然会发送多条消息!!!!
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "room");
await base.OnDisconnectedAsync(exception);
}
}

第三步:注册 SignalR 服务,添加路由

        public void ConfigureServices(IServiceCollection services)
{
......
services.AddSignalR();
......
}
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
......
app.UseSignalR(routes => { routes.MapHub<StronglyTypedChatHub>("/chatHub"); }); app.UseMvc();
}

第四步:下载 singalr.js (略,可参照官方文档)

效果:

在没有进入聊天室的时候,点击 "Send Message" 是没有效果的:

1 进入聊天室:

2 也进入聊天室

其实我觉得用这个 Group 的概念,可以实现多个聊天室功能.

ASP.NET Core 2.2 基础知识(十七) SignalR 一个极其简陋的聊天室的更多相关文章

  1. ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述

    为了方便演示,以 .NET Core 控制台应用程序讲解. 我们新建一个控制台应用程序,安装 "Newtonsoft.Json" Nuget 包,然后右键点击该项目,选择" ...

  2. ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求

    可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如 ...

  3. ASP.NET Core 2.2 基础知识(十六) SignalR 概述

    我一直觉得学习的最好方法就是先让程序能够正常运行,才去学习他的原理,剖析他的细节. 就好像这个图: 所以,我们先跟着官方文档,创建一个 SignalR 应用: https://docs.microso ...

  4. ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)

    要啥自行车,直接看手表 //返回基元类型 public string Get() { return "hello world"; } //返回复杂类型 public Person ...

  5. ASP.NET Core 2.2 基础知识(十三) WebAPI 概述

    我们先创建一个 WebAPI 项目,看看官方给的模板到底有哪些东西 官方给出的模板: [Route("api/[controller]")] [ApiController] pub ...

  6. ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块

    ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...

  7. ASP.NET Core 2.2 基础知识(十) Web服务器 - Kestrel

    ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...

  8. ASP.NET Core 2.2 基础知识(九) 使用托管服务实现后台任务

    在 ASP.NET Core 中,后台任务作为托管服务实现.托管服务是一个类,而且必须实现 IHostedService 接口,该接口定义了两个方法: StartAsync(CancellationT ...

  9. ASP.NET Core 2.2 基础知识(八) 主机 (未完待续)

    主机负责应用程序启动和生存期管理.共有两个主机 API : 1.Web 主机 : 适用于托管 Web 应用,基于 IWebHostBuilder ; 2.通用主机 : 适用于托管非 Web 应用. 基 ...

随机推荐

  1. warning LNK4070的解决办法

           原文链接地址:http://blog.csdn.net/clever101/article/details/5898073#comments         重命名了一个MFC常规DLL ...

  2. webpack 3.8 使用 extract-text-webpack-plugin 3.0 抽取css失败:You may need an appropriate loader to handle this file type.

    webpack 3.8.1 使用 extract-text-webpack-plugin 3.0.2 抽取css时失败,报错: ERROR in ./src/static/style/localTim ...

  3. [fzu 2273]判断两个三角形的位置关系

    首先判断是否相交,就是枚举3*3对边的相交关系. 如果不相交,判断包含还是相离,就是判断点在三角形内还是三角形外.两边各判断一次. //http://acm.fzu.edu.cn/problem.ph ...

  4. JAX-WS 注解

    一.概述 “基于 XML 的 Web Service 的 Java API”(JAX-WS)通过使用注释来指定与 Web Service 实现相关联的元数据以及简化 Web Service 的开发.注 ...

  5. MSTest DeploymentItemAttribute

    该attribute可以把指定的文件拷贝到每次运行的Out目录下,比如有一个config文件,那么用下面的命令, [TestClass] [DeploymentItem("Default.c ...

  6. border-1px;避免移动端下边框部分2px

    .border-1px { position: relative; } .border-1px:after { display: block; position: absolute; left:; b ...

  7. PowerDesigner使用教程(转)

    PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...

  8. 转:JVM Server与Client运行模式

    转自:http://blog.csdn.net/zhuyijian135757/article/details/38391785 JVM Server模式与client模式启动,最主要的差别在于:-S ...

  9. nodejs与sqlite

    //打开数据库var db = new sqlite3.Database('xx.db'); // 关闭数据库db.close(); db.run('xx');  // 数据库对象的run函数可以执行 ...

  10. Python基础(5)_文件操作

    一.文件处理流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 二.文件打开模式 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文 ...