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

这个例子只是在官方的例子上加了 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. [codeforces] 17E Palisection

    原题 题目要求相交的回文串对数,这显然非常难,但是要有一种正难则反的心态,求不出来相交的,求出来不相交的不就好了! 对于每以位置i结尾的字符串,在他后面与他不相交的就是以这个位置为结尾的个数和以这个位 ...

  2. HZOI String STL的正确用法

                                                                      String          3s 512 MB描述硬盘中里面有n ...

  3. 如何解析Json返回的数据

    Json在Web开发的用处非常广泛,作为数据传递的载体,如何解析Json返回的数据是非常常用的.下面介绍下四种解析Json的方式: Part 1 var list1 = [1,3,4]; alert( ...

  4. CVPR2014 Objectness 源码转换(完整版) VS2012 X64 –>win32

    一.版本转换  1.将源码中vs2012 X64版本转换为vs2012 win32版本. 2.源码下载及其相关资料下载http://mmcheng.net/zh/bing/ 3.需要下载源码(Pape ...

  5. myisam_sort_buffer_size vs sort_buffer_size

    Q: I am MySQL on server with 6GB RAM. I need to know what is the difference between myisam_sort_buff ...

  6. [bzoj 1143]最长反链二分图最大匹配

    Dilworth定理:偏序集能划分成的最少的全序集的个数与最大反链的元素个数相等. 证明:http://www.cnblogs.com/itlqs/p/6636222.html 题目让求的是最大反链的 ...

  7. C++构造函数重载以及默认参数引起的二义性

    大家都知道当我们声明一个类时,系统会提供一个默认构造函数.当我们需要提供参数进行对类数据成员进行初始化时,就需要对类的带参构造函数进行重载.同时,如果我们需要调用默认构造函数进行类数据成员的初始化时, ...

  8. MyBatis的SQL语句映射文件详解(三)----多参数传递的几种方式

    1.单一基本类型参数(String,int等) 单一的基本类型参数,将对应语句中的parameterType的值与参数的类型相同.然后直接 用“#{参数名}” 来获取 java代码 //String类 ...

  9. 膨胀、腐蚀、开、闭(matlab实现)

    膨胀.腐蚀.开.闭运算是数学形态学最基本的变换. 本文主要针对二值图像的形态学 膨胀:把二值图像各1像素连接成分的边界扩大一层(填充边缘或0像素内部的孔): B=[0 1 0      1 1 1   ...

  10. 【BZOJ】1596: [Usaco2008 Jan]电话网络

    [算法]树上贪心 [题解] 因为一个点必须被覆盖,那么它如果没有被子树节点覆盖的话,就覆盖它的父节点. 从叶子开始贪心. 注意,如果它自己已经被选了就不需要选父节点了. #include<cst ...