`

史上最全面的SignalR系列教程-5、SignalR 实现一对一聊天

阅读更多

史上最全面的SignalR系列教程-5、SignalR 实现一对一聊天

通过前面几篇文章

史上最全面的SignalR系列教程-1、认识SignalR

史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式

史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式

史上最全面的SignalR系列教程-4、SignalR 自托管全解(使用Self-Host)-附各终端详细实例

RDIFramework.NET敏捷开发框架通过SignalR技术整合即时通讯(IM)

我们对SignalR算入门了,知道如何把SignalR合理应用到实际的项目中。前面的文章主要讲解的是SignalR的概念,托管方式,以及推送的功能。本篇主要讲解通过SignalR实现一对一、点对点的聊天。

新建一个空的ASP.NET Mvc项目,取名为:SignalROneToOne,如下图所示。为了整个系列的完整性,我们直接在上一项目的基础上新增的一个测试项目,后面有项目的源码托管地址。

新建SignalROneToOne测试项目

创建好项目后,要使用SignalR,需要先安装SignalR包,可以通过程序包管理控制台输入包安装命令进行安装。

Install-Package Microsoft.AspNet.SignalR

也可以使用界面方式,如下图所示。

安装SignalR包-Microsoft.AspNet.SignalR

向工程中添加HubConnections目录,在其中添加OneToOneHub.cs文件,如下图所示:

添加OneToOneHub

实现的主要步骤:

  1. 重写OnConnected连接方法和OnDisconnected断开方法。
  2. 使用SendMessage服务器端方法发送消息,GetName获取用户名。
  3. 客户端响应的提示返回信息方法,如Clients.Client(Context.ConnectionId).addMessage(message)

OneToOneHub代码内容如下:

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace SignalROneToOneDemo.Connections
{
    /// <summary>
    /// 用户实体类
    /// </summary>
    public class User
    {
        /// <summary>
        /// 连接ID
        /// </summary>
        [Key]
        public string ConnectionID { get; set; }

        /// <summary>
        /// 用户名称
        /// </summary>
        public string Name { get; set; }

        public User(string name, string connectionId)
        {
            this.Name = name;
            this.ConnectionID = connectionId;
        }
    }

    /// <summary>
    /// 点对点(一对一)聊天
    /// </summary>
    [HubName("chat")]
    public class OneToOneHub : Hub
    {
        public static List<User> users = new List<User>();

        //发送消息
        public void SendMessage(string connectionId, string message)
        {
            Clients.All.hello();
            var user = users.Where(s => s.ConnectionID == connectionId).FirstOrDefault();
            if (user != null)
            {
                Clients.Client(connectionId).addMessage(message + "" + DateTime.Now, Context.ConnectionId);
                //给自己发送,把用户的ID传给自己
                Clients.Client(Context.ConnectionId).addMessage(message + "" + DateTime.Now, connectionId);
            }
            else
            {
                Clients.Client(Context.ConnectionId).showMessage("该用户已离线...");
            }
        }

        [HubMethodName("getName")]
        public void GetName(string name)
        {
            //查询用户
            var user = users.SingleOrDefault(u => u.ConnectionID == Context.ConnectionId);
            if (user != null)
            {
                user.Name = name;
                Clients.Client(Context.ConnectionId).showId(Context.ConnectionId);
            }
            GetUsers();
        }

        /// <summary>
        /// 重写连接事件
        /// </summary>
        /// <returns></returns>
        public override Task OnConnected()
        {
            //查询用户
            var user = users.Where(u => u.ConnectionID == Context.ConnectionId).SingleOrDefault();
            //判断用户是否存在,否则添加集合
            if (user == null)
            {
                user = new User("", Context.ConnectionId);
                users.Add(user);
            }
            return base.OnConnected();
        }

        public override Task OnDisconnected(bool stopCalled)
        {
            var user = users.Where(p => p.ConnectionID == Context.ConnectionId).FirstOrDefault();
            //判断用户是否存在,存在则删除
            if (user != null)
            {
                //删除用户
                users.Remove(user);
            }
            GetUsers();//获取所有用户的列表
            return base.OnDisconnected(stopCalled);
        }

        //获取所有用户在线列表
        private void GetUsers()
        {
            var list = users.Select(s => new { s.Name, s.ConnectionID }).ToList();
            string jsonList = JsonConvert.SerializeObject(list);
            Clients.All.getUsers(jsonList);
        }
    }
}

如果你是vs2015 的话添加的mvc项目 不进行身份验证的那种吧,必须得添加一个Startup 类。如果没有这个类请添加,不然的话项目运行不起来的,具体代码如下:

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(SignalROneToOneDemo.App_Start.SignalRQuickStart))]

namespace SignalROneToOneDemo.App_Start
{
    public class SignalRQuickStart
    {
        public void Configuration(IAppBuilder app)
        {
            // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888
            // 配置集线器
            app.MapSignalR();
        }
    }
}
@{
    ViewBag.Title = "OneToOneChat";
}

<h2>点对点(一对一)聊天实例代码</h2>

<div>
    <div>用户名称:<label id="userName"></label>(<label id="conId"></label>)</div>

    <div style="width:25%;border:1px solid #ff0000">
        <div>在线用户列表</div>
        <ul id="users"></ul>
    </div>
    <div id="userBox">
    </div>
</div>

@section scripts {
    <script src="~/Scripts/jquery-3.3.1.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
    <script src="~/signalr/hubs"></script>
    <script type="text/javascript">
        var clients = [];
        var chat;
        $(function () {        
            chat = $.connection.chat;
            console.info(chat);

            //显示提示方法
            chat.client.showMessage = function (message) {
                alert(message);
            }

            //注册显示信息的方法
            chat.client.addMessage = function (message, connectionId) {
                //debugger
                if ($.inArray(connectionId, clients)==-1) {
                    showWin(connectionId);
                }

                $("#messages" + connectionId).each(function () {
                    $(this).append('<li>'+message+'</li>');
                })
            }

            //注册显示所有用户的方法
            chat.client.getUsers = function (data) {            
                if (data) {
                    var json = $.parseJSON(data);                    
                    console.info(json);
                    $("#users").html(" ");
                    for (var i = 0; i < json.length; i++) {                        
                        var html = '<li>用户名:' + json[i].Name + '<input type="button" connectionId="' + json[i].ConnectionID + '" id="'  + json[i].ConnectionID + '" value="聊天"  onclick="userChat(this)" />' ;
                        $("#users").append(html);
                    }
                }
            }

            //注册显示推出聊天提示的方法
            chat.client.exitUser = function (data)
            {
                alert(data);
            }

            //注册显示个人信息的方法
            chat.client.showId = function (data)
            {
                $("#conId").html(data);
                clients.push(data);
            }

            //获取用户名称
            $('#userName').html(prompt('请输入您的名称', ''));

            //连接成功后获取自己的信息
            $.connection.hub.start().done(function () {
                chat.server.getName($('#userName').html());
            });
        });

        //开始聊天
        function userChat(obj)
        {
            var connectionId = $(obj).attr('connectionId');
            showWin(connectionId);
        }

        function showWin(connectionId)
        { 
            clients.push(connectionId);
            var html = '<div style="float:left;margin-top:5px;margin-right: 5px;margin-bottom: 5px;border:1px solid #ff0000" id="' + connectionId + '" connectionId="' + connectionId + '">' + connectionId + '"的房间聊天记录如下:<button onclick="exitChat(this)">退出</button><ul id="messages' + connectionId + '"></ul><input type="text" /> <button onclick="sendMessage(this)">发送</button></div>';
            $("#userBox").append(html);
        }

        function exitChat(btnObj)
        {          
            $(btnObj).parent().remove();
            chat.server.exitChat(connectionId);
        }

        //发送消息
        function sendMessage(data)
        {
            var message = $(data).prev().val();
            var  userObj = $(data).parent();
            var username = $("#userName").html();
            message = username + ":" + message;
            console.info($(userObj).attr("connectionId"));
            var targetConnectionId = $(userObj).attr("connectionId");
            chat.server.sendMessage(targetConnectionId, message);
            $(data).prev().val("");
        }
    </script>
}

一对一聊天效果展示

到此,一个SignalR一对一(点对点)聊天例子就完成了,下面我们简单的对代码作下分析:

Clients.Client(connectionId).addMessage():作用客户端注册addMessage方法,向指定连接Id的客户端发送消息。由于一对一聊天发送的消息也应该回发给自己,所以回发给自己连接的Id可以通过Context.ConnectionId来获取。当然也也可以使用Client.Caller()代替Client.Client(Context.ConnectionId)方法直接发送。

Client.Clients(IList connectionIds):同时向多个ConnectionId发送消息,类似于QQ上@好友的功能。

通过浏览器F12我们可以看到SignalR给我们生成的方法:

F12Hubs代码效果

可以看到我们服务端开发的两个方法,需要特别说明的是服务器端的方法名在客户端调用都约定第一个字母为小写,当然我们也可以通过方法名上加特性HubMethodName进行标识处理。

实例源码可以移步github下载,地址:https://github.com/yonghu86/SignalRTestProj


一路走来数个年头,感谢RDIFramework.NET框架的支持者与使用者,大家可以通过下面的地址了解详情。

RDIFramework.NET官方网站:http://www.rdiframework.net/

RDIFramework.NET官方博客:http://blog.rdiframework.net/

同时需要说明的,以后的所有技术文章以官方网站为准,欢迎大家收藏!

RDIFramework.NET框架由海南国思软件科技有限公司专业团队长期打造、一直在更新、一直在升级,请放心使用!

欢迎关注RDIFramework.net框架官方公众微信(微信号:guosisoft),及时了解最新动态。

扫描二维码立即关注

微信号:guosisoft

0
0
分享到:
评论

相关推荐

    .Net MVC5下SignalR简单web即时聊天小程度

    综上所述,这个项目教程将涵盖如何在.Net MVC5环境中设置SignalR,创建实时聊天室的后端服务,以及如何在前端使用JavaScript与后端进行交互,展示消息。开发者可能还会学习到如何处理用户身份验证、群聊、私聊、消息...

    ASP.NET Core项目实战视频教程--基于ASP.NET Core x SignalR实现的实时在线聊天应用程序

    ChatApp项目的视频版本

    .NET6API-Vue使用SignalR文档教程

    SignalR 是一个用于在服务器和客户端之间建立实时双向通信的库,非常适合实时通知、聊天应用或任何需要实时更新的场景。 ### 1. 引入 SignalR 在`.NET Core API`项目中,首先需要通过NuGet包管理器或在`csproj`...

    SignalR 2.0 and MVC 5即时通讯完整版示例

    本教程使用与SignalR入门教程相同的聊天应用程序代码,但演示如何将其添加到MVC 5应用程序。 在这个主题中,您将学习以下SignalR开发任务: 将SignalR库添加到MVC 5应用程序。 创建集线器和OWIN启动类来将内容推...

    基于.Net Core3.1 与signalR实现一个即时通讯工具-资源包

    这个资源包的标题表明它提供了一个使用SignalR实现即时通讯工具的示例或教程。在这个项目中,"wwwroot"是ASP.NET Core应用中的静态文件目录,通常存放HTML、CSS、JavaScript等前端资源。 即时通信(Instant ...

    视频教程Asp.Net SignalR

    Asp.Net SignalR视频教程,淘宝买来自己听的,挺有深度,分享一下

    AspNetCore3.0 WebApi+SignalR 实现通信

    本教程介绍生成使用 SignalR 的实时应用的基础知识。 您将学习如何: 创建 Web 项目。 添加 SignalR 客户端库。 创建 SignalR 中心。 配置项目以使用 SignalR。 添加可将消息从任何客户端发送到所有连接客户端的代码...

    SignalR进度条简单示例-教程_JavaScript_C#_下载.zip

    这个"SignalR进度条简单示例-教程_JavaScript_C#_下载.zip"文件包含了一个使用SignalR、JavaScript和C#实现的进度条功能的示例项目,非常适合初学者了解如何将实时更新应用到Web应用程序中。 首先,我们要理解...

    带有ASP.NET WebForm和BootStrap的SignalR聊天应用程序-第三部分

    综上所述,这个教程将带你一步步构建一个功能完备的实时聊天应用,融合了ASP.NET WebForms的后端处理能力、Bootstrap的前端设计美感,以及SignalR的实时通信特性。通过学习和实践,你将掌握构建类似应用的关键技术点...

    带有ASP.NET WebForm和BootStrap的SignalR聊天应用程序-第一部分

    标题中的“带有ASP.NET WebForm和BootStrap的SignalR聊天应用程序-第一部分”表明我们将探讨如何使用ASP.NET Web Forms框架、Bootstrap前端框架以及SignalR库来构建一个实时的聊天应用。SignalR是Microsoft推出的一...

    Signalr组播与广播例子

    这个"Signalr组播与广播例子"是关于如何使用SignalR来实现多播和广播通信模式的教程。 首先,我们要理解多播和广播的概念。在计算机网络中,多播是指一个消息被发送到一组特定的接收者,而广播则是将消息发送给所有...

    Xamarin Signalr入门例子

    **Xamarin SignalR入门教程** Xamarin 是一种跨平台的移动应用开发框架,它允许开发者使用C#语言和.NET框架来构建iOS、Android以及Windows应用。SignalR则是一种实时通信库,它使得服务器与客户端之间的双向通信变...

    数学分析教程(上册)-常庚哲-史济怀-习题解答

    数学分析教程(上册)-常庚哲-史济怀-习题解答 数学分析教程(上册)-常庚哲-史济怀-习题解答 数学分析教程(上册)-常庚哲-史济怀-习题解答 数学分析教程(上册)-常庚哲-史济怀-习题解答 数学分析教程(上册)-常庚哲-史济怀...

    Vue结合SignalR实现前后端实时消息同步

    Vue结合SignalR实现前后端实时消息同步 Vue结合SignalR实现前后端实时消息同步是指在客户端和服务器端之间实现实时消息同步的技术解决方案。这项技术解决方案主要依赖于SignalR这个库, SignalR是一个ASP.NET的库,...

    ASP.NET SignalR编程实战(附书中完整Demo示例源码)

    本教程基于"ASP.NET SignalR编程实战"一书,将深入探讨SignalR的核心概念、工作原理以及如何在实际项目中应用。 1. **SignalR简介** SignalR是.NET Framework的一部分,它提供了跨平台的解决方案,支持多种浏览器...

    ASP.NET SignalR编程实战(附书中完整Demo示例源码)__0525.rar

    在"ASP.NET SignalR编程实战(附书中完整Demo示例源码)__0525.rar"这个压缩包中,你将找到一系列关于SignalR实际应用的教程和实例代码。这些源码可以帮助你深入理解SignalR的工作原理以及如何在实际项目中有效利用它...

    FP-Growth算法python实现(完整代码)

    包含两个文件,一个是刚构造好FP-tree的代码,另一个是FP-Growth算法python实现的完全代码。更多的介绍请见博客:http://blog.csdn.net/bone_ace/article/details/46746727

    android--ListView实现聊天记录

    本教程将深入探讨如何在Android中利用ListView来实现一个聊天记录的界面。 一、ListView的基本概念 ListView是Android SDK中的一个视图容器,它能够显示一列可滚动的项目列表。每个列表项可以由自定义的View或布局...

    Global Mapper系列教程-经典

    Global Mapper系列教程 [第一章]对光栅进行指定范围剪裁及羽化 6 [第二章]创建范围环(环交集) 9 [第三章]平铺地形(地形编辑) 13 [第四章]结合地形层 18 [第五章]添加自定义椭球 27 [第六章]用CASS数据创建地形 ...

Global site tag (gtag.js) - Google Analytics