asp.net mvc signalR 实现一对一聊天

之前做了一篇关于asp.net mvc signalR聊天室的简单入门例子, 其中用的是 Clients.All.xxx_js   ,这个All代表了全体广播,今天写了   一对一聊天的例子 。 

//前一篇文章
https://blog.csdn.net/MFCdestoryer/article/details/116304333

按照之前的例子,先用NuGet工具下载好signalr的包 , 然后进行开发。

首先建立一个简单的controller 和 view , 比方说 HomeController.SL  , 备注:我平时页面布局都是用bootstrap 这套样式,所以除了 jquery 之外,html页面还引入了bootstrap样式。

   public class HomeController : Controller
    {
         

        //私聊
        public ActionResult SL()
        {
            return View();
        }

    }

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>SL</title>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
 
    <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

    <!--Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
    <!--Reference the autoGenerated SignalR hub script. -->
    <script src="~/signalr/hubs"></script>

    

</head>
<body>
    <div class="container"> 
        <div class="row">
            <div class="col-md-12 col-sm-12">
                <div class="well well-sm">
                    <div class="text-center">
                        当前用户: 
                        <span id="curUserName"></span>
                    </div>
                </div>
            </div>
        </div>

        <div class="row">
            <div class="col-md-2 col-sm-4">
                <div id="user-list-group" class="list-group">
                    <button type="button" class="list-group-item" title="aaa" onclick="listGroupItemClick(this);" >小黄</button>
                    <button type="button" class="list-group-item" title="bbb" >李小龙</button>
                    <button type="button" class="list-group-item">乔丹</button>
                    <button type="button" class="list-group-item">李荣浩</button>
                    <button type="button" class="list-group-item">大哥</button>
                </div>
                <!--hiden value-->
                <div style="display:none;">
                    <input type="text" id="userName" name="userName" />
                </div>
            </div>  <!--end left-->

            <div class="col-md-10 col-sm-8">
                <div class="row">
                    <!--CHART text-->
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            对话框:
                            <span id="sname"></span> 
                            【<span id="sid"></span>】
                        </div>

                        <div class="panel-body">
                            <div id="contextDIV" style="height:500px;overflow:auto;">
                                @*<p><span class="label label-success">Myself</span> Example heading </p>
                                  <p><span class="label label-info">Info</span> heellelee222 </p>*@
                            </div>
                        </div> <!--end panel body-->

                        <div class="panel-footer">
                            <div class="row">
                                <div class="col-md-12 col-sm-12">
                                    <div class="input-group">
                                        <input type="text" id="message" name="message" class="form-control" />
                                        <span class="input-group-btn">
                                            <input type="button" class="btn btn-default" id="sendmessage" name="sendmessage" value="发送" />
                                        </span>
                                    </div>
                                </div>
                            </div>
                        </div><!--end pannel foot-->

                    </div> <!--end pannel-->
                </div>
            </div>  <!--end right-->
        </div>
        
    </div>
</body>
</html>

运行可以看到一个简单的例子页面:

然后,我们 新建一个 signalr hub class ,在  new item 里面选择 signalr hub class ,这个步骤可以看以前写的文章 , 这里不截图了 , 建好之后,改下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using signalrTest7.Models;

namespace signalrTest7.Controllers
{
     


    [HubName("chartHubb")]
    public class ChartHubb : Hub
    {
        private static List<UserInfo> USERLIST = new List<UserInfo>();

        //连接
        public override Task OnConnected()
        {
            var currentUser = USERLIST.Where(x => x.ConnectionID == Context.ConnectionId).FirstOrDefault();
            if (currentUser == null) {
                UserInfo newUser = new UserInfo(Context.ConnectionId, "");
                USERLIST.Add(newUser);
            }

            return base.OnConnected();
        }

        //断开
        public override Task OnDisconnected(bool stopCalled)
        {
            var currentUser = USERLIST.Where(x => x.ConnectionID == Context.ConnectionId).FirstOrDefault();
            if (currentUser != null) {
                USERLIST.Remove(currentUser);
            }

            ShowAllUser();
            return base.OnDisconnected(stopCalled);
        }


        /// <summary>
        /// 广播登陆用户列表到全体连接客户端
        /// </summary>
        [HubMethodName("showAllUser")]
        public void ShowAllUser()
        {
            string userJson = Newtonsoft.Json.JsonConvert.SerializeObject(USERLIST);
            Clients.All.broadcastUserList(userJson);
            //前端js定义 function broadcastUserList(userList)
        }

        /// <summary>
        /// 登陆时设置名字
        /// </summary>
        /// <param name="inputName"></param>
        [HubMethodName("setUserName")]
        public void SetUserName(string inputName)
        {
            var currentUser = USERLIST.Where(x => x.ConnectionID == Context.ConnectionId).FirstOrDefault();
            if (currentUser != null) {
                currentUser.UserName = inputName;
            }
            //广播给全体客户端
            this.ShowAllUser();
        }

        /// <summary>
        /// 发送信息给某人
        /// </summary>
        /// <param name="outsideID"></param>
        /// <param name="message"></param>
        [HubMethodName("sendTo")]
        public void SendTo(string outsideID,  string message)
        {
            var myUser = USERLIST.Where(y => y.ConnectionID == Context.ConnectionId).FirstOrDefault();
            var outsideUser = USERLIST.Where(x => x.ConnectionID == outsideID).FirstOrDefault();

            //前端js定义function showMessage(speakerName , message)
            if (outsideUser != null)
            {
                Clients.Client(outsideUser.ConnectionID).showMessage(myUser.UserName, message);
                Clients.Client(myUser.ConnectionID).showMessage(myUser.UserName, message);
                //对方  和  我方 的界面都要显示语录
            }
            else {
                Clients.Client(myUser.ConnectionID).showMessage(outsideUser.UserName + outsideUser.ConnectionID , "离线");
            }
        }


    }


}

这个 hub class 有一些注意的地方,(1)onConnect 和 onDisconnect 都是可以通过 override出来的 , 在visual studio 中,只要输入 override关键字,然后按一下键盘的tab键, 就会有相应的提示弹出来了 , 不用自己手动一个个字母敲。

(2)这里用到一个实体类  UserInfo

 public class UserInfo
    {
        public string ConnectionID { get; set; }
        public string UserName { get; set; }

        //构造函数
        public UserInfo(string cid, string unm) {
            this.ConnectionID = cid;
            this.UserName = unm;
        }
    }

 然后接着是  owin startup 的代码(也可以参考之前写的文章,这里不截图了)

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(signalrTest7.Startup))]

namespace signalrTest7
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }


}

剩下的就是对应编辑注册前端html页面中js function ,慢慢读代码,就能发现:

后台hub 类里面的代码是通过  Clients.All / Client.xxx_js (  )  来触发前端js 方法 ,

前端js 是通过   chat.server.xxx  来触发后台 hub method , 

 

其实微软给开发者提供了这一个比较简单的思路,让我们能写出实时对话的代码。我是菜鸟,写的不对请见谅。

刚刚的SL  view里面 ,js代码改为以下:


@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>SL</title>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
 
    <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

    <!--Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
    <!--Reference the autoGenerated SignalR hub script. -->
    <script src="~/signalr/hubs"></script>

    <script type="text/javascript">

        $(function () {

            //存储当前用户名称
            $('#userName').val(prompt('请输入您的名称', ''));
             
            //连接后端hub
            chat = $.connection.chartHubb;
            console.info(chat);

            //注册后台
            chat.client.broadcastUserList = function (data) {
                if (data) {
                    var json = $.parseJSON(data);
                    console.info(json); 

                    $('#user-list-group').html('');
                    for (var i = 0; i < json.length; i++) {
                        
                        var mhtml = '<button type="button" class="list-group-item" title="' + json[i].ConnectionID + '" onclick="listGroupItemClick(this);" >' + json[i].UserName + '</button>';
                         
                        $('#user-list-group').append(mhtml);
                    }
                }
            }  //end broadcastUserList

            //注册后台
            chat.client.showMessage = function (speakerName, message) {
                var msg = ''; 

                if (speakerName == $('#curUserName').text()) {
                    msg = '<p><span class="label label-success"> ' + speakerName + '</span>' + message + '</p>';
                }
                else {
                    msg = '<p><span class="label label-info"> ' + speakerName + '</span>' + message + '</p>';
                }
                
                $('#contextDIV').append(msg);
                $('#message').val('');
                $('#message').val('').focus();
            }   //end showMessage

            //发送按钮
            $('#sendmessage').click(function () {
                var outid = $('#sid').text();
                var outmessage = $('#message').val();

                if (outid != '' && outmessage != '' ) {
                    chat.server.sendTo(outid, outmessage);
                } 
                else {
                    alert('请选择接收消息的用户(或者没有输入任何内容)');
                }
                
            });  //end click

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

        });   //end page ready


        //左侧名字列表 点击事件
        function listGroupItemClick(that) {
            var tname = $(that).text();
            var tid = $(that).attr('title');

            $('#sname').text(tname);
            $('#sid').text(tid);
        }//end listGroupItemClick


        //回车键
        $(document).keydown(function () {
            if (event.keyCode == 13) {
                $('#sendmessage').click();
            }
        });  //end keydown



    </script>

</head>
<body>
    <div class="container"> 
        <div class="row">
            <div class="col-md-12 col-sm-12">
                <div class="well well-sm">
                    <div class="text-center">
                        当前用户: 
                        <span id="curUserName"></span>
                    </div>
                </div>
            </div>
        </div>

        <div class="row">
            <div class="col-md-2 col-sm-4">
                <div id="user-list-group" class="list-group">
                    <button type="button" class="list-group-item" title="aaa" onclick="listGroupItemClick(this);" >小黄</button>
                    <button type="button" class="list-group-item" title="bbb" >小龙</button>
                    <button type="button" class="list-group-item">乔</button>
                    <button type="button" class="list-group-item">李</button>
                    <button type="button" class="list-group-item">大哥</button>
                </div>
                <!--hiden value-->
                <div style="display:none;">
                    <input type="text" id="userName" name="userName" />
                </div>
            </div>  <!--end left-->

            <div class="col-md-10 col-sm-8">
                <div class="row">
                    <!--CHART text-->
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            对话框:
                            <span id="sname"></span> 
                            【<span id="sid"></span>】
                        </div>

                        <div class="panel-body">
                            <div id="contextDIV" style="height:500px;overflow:auto;">
                                @*<p><span class="label label-success">Myself</span> Example heading </p>
                                  <p><span class="label label-info">Info</span> heellelee222 </p>*@
                            </div>
                        </div> <!--end panel body-->

                        <div class="panel-footer">
                            <div class="row">
                                <div class="col-md-12 col-sm-12">
                                    <div class="input-group">
                                        <input type="text" id="message" name="message" class="form-control" />
                                        <span class="input-group-btn">
                                            <input type="button" class="btn btn-default" id="sendmessage" name="sendmessage" value="发送" />
                                        </span>
                                    </div>
                                </div>
                            </div>
                        </div><!--end pannel foot-->

                    </div> <!--end pannel-->
                </div>
            </div>  <!--end right-->
        </div>
        
    </div>
</body>
</html>

到这里就写好了一对一聊天的功能了 ,试一试。

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
ASP.NET MVC 中使用 SignalR 实现一对一聊天需要以下步骤: 1. 创建一个名为 ChatHub 的 SignalR Hub 类,并在其中定义需要推送的消息方法。 ```csharp using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace MvcSignalR.Hubs { public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.User(user).SendAsync("ReceiveMessage", message); } } } ``` 2. 在 Startup.cs 中配置 SignalR 中间件,并启用身份验证。 ```csharp using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Authentication; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.DependencyInjection; using MvcSignalR.Hubs; using System.Security.Claims; namespace MvcSignalR { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSignalR(); services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie("Cookies") .AddOpenIdConnect("oidc", options => { options.Authority = "https://demo.identityserver.io/"; options.ClientId = "interactive.confidential"; options.ClientSecret = "secret"; options.ResponseType = "code"; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseStaticFiles(); app.UseAuthentication(); app.UseSignalR(routes => { routes.MapHub<ChatHub>("/chathub"); }); app.UseMvcWithDefaultRoute(); } } } ``` 在这个示例中,我们使用 IdentityServer 作为身份验证提供程序。当用户登录后,我们将使用 SignalR 的 User 方法将消息推送到特定的用户。 3. 在客户端 JavaScript 中引用 SignalR 库,并连接到 SignalR Hub。 ```javascript <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="/lib/signalr/dist/browser/signalr.js"></script> <script> var connection = new signalR.HubConnectionBuilder().withUrl("/chathub").build(); connection.start().then(function () { console.log("connected"); }).catch(function (err) { return console.error(err.toString()); }); $("#sendButton").click(function () { var user = $("#userInput").val(); var message = $("#messageInput").val(); connection.invoke("SendMessage", user, message).catch(function (err) { return console.error(err.toString()); }); }); connection.on("ReceiveMessage", function (message) { console.log(message); }); </script> ``` 在这个示例中,我们使用 jQuery 获取用户输入的用户名和消息,并将它们传递给 SignalR Hub 的 SendMessage 方法。 4. 在服务器端调用 SendMessage 方法以向特定的用户发送消息。我们将使用 HttpContext.User.Identity.Name 获取当前用户的用户名。 ```csharp public class HomeController : Controller { private readonly IHubContext<ChatHub> _chatHub; public HomeController(IHubContext<ChatHub> chatHub) { _chatHub = chatHub; } [Authorize] public IActionResult Index() { return View(); } [HttpPost] [Authorize] public async Task<IActionResult> SendMessage(string message) { var user = HttpContext.User.Identity.Name; await _chatHub.Clients.User(user).SendAsync("ReceiveMessage", message); return Ok(); } } ``` 在这个示例中,我们使用 IHubContext 获取 ChatHub 的实例,并使用 Clients.User 方法将消息推送到特定的用户。 以上就是在 ASP.NET MVC 中使用 SignalR 实现一对一聊天的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值