Asp.net通过SignalR2进行实时聊天

目录
  • 一:什么是signalR
    • 1、SignalR传输方式
      • 1、HTML5 传输
      • 2、Comet 传输
    • 2、SignalR连接模式
  • 二、服务端
    • 1、添加服务端Hub
    • 2、添加OWIN 启动类
  • 三、客户端
  • 四、运行结果
  • 五、一对一聊天实例

一:什么是signalR

Asp.net SignalR是微软为实现实时通信的一个类库。

一般情况下,signalR会使用JavaScript的长轮询(long polling)的方式来实现客户端和服务器通信,随着Html5中WebSockets出现,SignalR也支持WebSockets通信。

另外SignalR开发的程序不仅仅限制于宿主在IIS中,也可以宿主在任何应用程序,包括控制台,客户端程序和Windows服务等,另外还支持Mono,这意味着它可以实现跨平台部署在Linux环境下。

SignalR将整个信息的交换封装起来,客户端和服务器都是使用JSON来沟通的,在服务端声明的所有Hub信息,都会生成JavaScript输出到客户端,.NET则依赖Proxy来生成代理对象,而Proxy的内部则是将JSON转换成对象。

客户端和服务端的具体交互情况如下图所示:

1、SignalR传输方式

1、HTML5 传输

这种传输方式当然是需要对HTML5兼容支持。如果客户端不支持HTML5 标准,那么你可以使用其他方式。

  • WebSocket: (前提是服务器和客户端都可以支持WebSocket )。WebSocket 是唯一的能够支持服务器和客户端建立真正持久的双向连接的传输方式,但是就是WebSocket要求的条件比较苛刻。 
    WebSocket真正能够支持只是在最新的IE 浏览器、Chrome、Firefox和一些其他的浏览器比如Opera 和 Safari。
  • Server Sent Events (SSE)服务端发送事件 :就是我们常说的EventSource (除了IE的其他浏览器都支持支持服务器发送事件)。

2、Comet 传输

下面的传输方式都是建立在Comet Web应用模型上。这种传输方式会在浏览器或者其他客户端保持一个长连接的HTTP请求,服务器可以利用这个请求将数据推送到客户端,而不用等客户端单独去请求数据。

  • Forever Frame:(只有IE浏览器支持)Forever Frame 会创建一个隐藏的IFrame ,这个IFrame 会向服务器发起一个端点请求,但是这个请求不会结束。服务器会不停的发送脚本到客户端马上执行,提供一个从服务器端到客户端的单向实时连接。服务端到客户端和客户端到服务端分别是两个不同的连接,就像一个标准的HTTP请求,一旦有数据需要发送就会创建一个新的连接。
  • Ajax Long Polling长轮询:长轮询不会创建一个持久的连接,它是会保持一个客户端与服务器的连接,直到服务器做出应答就会立即关闭,然后创建一个新的连接。当连接重置的时候这会导致一些延迟。

2、SignalR连接模式

  • Http Persisten Connection(持久连接)对象:用来解决长时间连接的功能。 
    还可以由客户端主动向服务器要求数据,而服务器端不需要实现太多细节,只需要处理PersistentConnection 内所提供的五个事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
  • Hub(集线器)对象:用来解决实时(realtime)信息交换的功能,服务端可以利用URL来注册一个或多个Hub,只要连接到这个Hub,就能与所有的客户端共享发送到服务器上的信息,同时服务端可以调用客户端的脚本。 
    SignalR将整个信息的交换封装起来,客户端和服务器都是使用JSON来沟通的,在服务端声明的所有Hub信息,都会生成JavaScript输出到客户端,.NET则依赖Proxy来生成代理对象,而Proxy的内部则是将JSON转换成对象。

下面的图展示了Hub和持久连接的关系,让你对底层的传输技术一目了然。

二、服务端

原文参考:教程:通过 SignalR 2 进行实时聊天

使用vs2012创建一个新的ASP.NET Web Application项目。

1、添加服务端Hub

解决方案中添加SignalR Hub类选项,然后创建文件ChatHub.cs。此步骤将创建ChatHub.cs类文件并添加一组脚本文件和 SignalR 支持到项目的程序集引用。

注意:可以使用NuGet命令 install-package Microsoft.AspNet.SignalR 来引用SignalR到项目中

然后在ChatHub类中输入下面这段代码。

using Microsoft.AspNet.SignalR;

namespace WebApplication2
{
    public class ChatHub : Hub
    {
        //定义可以被网页脚本访问的公共方法
        public void Send(string name, string message) //在客户端可以使用hub.server.send()方法调用。
        {
            // 客户端通过调用broadcastMessage来获取服务端数据
            Clients.All.broadcastMessage(name, message);//在客户端通过hub.client.broadcastMessage=function(){…}定义这个回调函数。
        }
    }
}

ChatHub类中,可以看到它继承自Microsoft.AspNet.SignalR.Hub类。从Hub类派生出类是构建SignalR应用程序的有用方式。在这个类(ChatHub)中定义的公共方法可以被网页内的脚本访问。

在这段代码中(ChatHub类),客户端通过调用ChatHub.Send方法,并把名称和消息内容做为参数传递给ChatHub。而ChatHub则通过Clients.All.broadcastMessage方法把该消息广播给所有客户端。

Send方法演示了几个Hub概念:

  • 在hub上声明一些公共方法,以便客户端可以调用它们。
  • 使用Microsoft.AspNet.SignalR.Hub。客户端动态属性用于与连接到此中心的所有客户端进行通信。
  • 调用客户机上的函数(如broadcastMessage函数)来更新客户机。

2、添加OWIN 启动类

Solution Explorer中,右击项目,然后添加一个名为StartupOWIN 启动类,然后输入下面这段代码。

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(WebApplication2.Startup))]
namespace WebApplication2
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

三、客户端

在项目中添加一个静态网页文件,并命名为index.html,然后右击该网页文件,并选择Set As Start Page,在Index.html中输入下面的代码,注意引用正确的文件名。

<!DOCTYPE html>
<html>
<head>
    <title>SignalR Simple Chat</title>
    <style type="text/css">
        .container {
            background-color: #99CCFF;
            border: thick solid #808080;
            padding: 20px;
            margin: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />

        <input type="hidden" id="displayname" />
        <ul id="discussion"></ul>
    </div>

    Reference the jQuery library.
    <script src="Scripts/jquery-1.12.4.js"></script>
    Reference the SignalR library.
    <script src="Scripts/jquery.signalR-2.4.1.js"></script>
    Reference the autogenerated SignalR hub script.
    <script src="signalr/hubs"></script>
    Add script to update the page and send messages.
    <script type="text/javascript">
        $(function () {
            // 1、声明一个代理,用于引用服务端hub
            var chat = $.connection.chatHub;

            // 2、创建一个回调函数,让Hub调用它来广播消息。
            chat.client.broadcastMessage = function (name, message) {
                // Html编码形式显示名称和消息
                var encodedName = $('
').text(name).html();
                var encodedMsg = $('
').text(message).html();;
                // 将消息添加到页面。
                $('#discussion').append('
' + encodedName
                    + ':  ' + encodedMsg + '
');
            };
            // 获取用户名
            $('#displayname').val(prompt('Enter your name:', ''));
            // 将初始焦点设置为消息输入框。
            $('#message').focus();

            // 3、开始连接和发送消息
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    // 在Hub上调用Send方法.
                    chat.server.send($('#displayname').val(), $('#message').val());
                    // 清除文本框并为下一个注释重置焦点。
                    $('#message').val('').focus();
                });
            });
        });
    </script>
</body>
</html>

客户端通过jquery.signalR.jssignalr/hubs来与服务器进行通信,首先它要声明一个代理来引用集线器。

var chat = $.connection.chatHub

请注意:在JavaScript中,对服务器类及其成员的引用必须是camelCase形式。本例中将C#服务端的ChatHub类在JavaScript中的引用为chatHub。

然后它要再定义一个回调函数,这个回调函数主要是为了让服务器进行调用,从而将数据推送到客户端。

chat.client.broadcastMessage = function (name, message) {
    //TODO:接收服务器推送的消息
};

而下面的代码则是为了确保在将消息发送到服务器之前已经与服务器建立了连接。.done 函数表示连接成功后为发送的按钮绑定一个单击事件。

// 与服务器建立连接后才能发送消息到服务器
$.connection.hub.start().done(function () {
    $('#sendmessage').click(function () {
        // 调用服务器端的ChatHub.Send方法,把消息发送到服务器
        chat.server.send("name", "message");
    });
});

保存项目,并按F5运行,就可以实现B/S模式下的即时通讯。

四、运行结果

项目运行起来后,同时用多个浏览器打开的,输入各自的姓名之后,就能够实现即时通讯了。回到我们的vs,还能够看到自动生成的hubs脚本文件,如下图所示。

三个不同的浏览器中的运行方式。 当 Tom、 Anand 和 Susan 发送消息时,所有浏览器实时更新:

在ServerHub重写一个 OnConnected 方法来监控客户端的连接情况,程序运行的时候web页面就使用$.connection.hub.start() 与signalR服务开始建立连接了,在调试的时候可以在输入中看到 "客户端连接成功!"

public override Task OnConnected()
{
    System.Diagnostics.Trace.WriteLine("客户端连接成功!");
    return base.OnConnected();
}

五、一对一聊天实例

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

Client.Clients(IList connectionIds) 这个方法的意思就是想一组string 的几个ConnectionId发送消息。类似于QQ上@好友的那种功能。

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 WebApplication2
{
    [HubName("UserHub")]
    public class UserHub : Hub
    {
        #region 字段

        public static List users = new List();

        #endregion 字段

        #region 方法

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

        //登记名字
        public void LoginIn(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();
        }

        //发送消息
        [HubMethodName("sendMessage")]
        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("该用户已离线");
            }
        }

        /// 

        /// 重写连接事件
        ///
        ///
        public override Task OnConnected()
        {
            //查询用户
            var user = users.Where(w => w.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);
        }

        #endregion 方法
    }

    public class User
    {
        #region 构造函数

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

        #endregion 构造函数

        #region 属性

        [Key]
        public string ConnectionID { get; set; }

        public string Name { get; set; }

        #endregion 属性
    }
}

到此这篇关于Asp.net通过SignalR2进行实时聊天的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Asp.net MVC SignalR来做实时Web聊天实例代码

    本章和大家分享的内容是使用Signal R框架创建个简易的群聊功能,主要讲解如何在.Net的MVC中使用这个框架,由于这个项目有官方文档(当然全英文),后面也不打算写分享篇了,主要目的是让朋友们在需要使用Web实时通信的时候有更多一种解决方案,毕竟这是微软主推的一种解决方案之一. SignalR网上简介 ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用

  • Asp.net使用SignalR实现聊天室的功能

    一.引言 在前一篇文章<Asp.net使用SignalR实现酷炫端对端聊天功能>中,我向大家介绍了如何实现实现端对端聊天的功能的,在这一篇文章中将像大家如何使用SignalR实现群聊这样的功能. 二.实现思路 要想实现群聊的功能,首先我们需要创建一个房间,然后每个在线用户可以加入这个房间里面进行群聊,我们可以为房间设置一个唯一的名字来作为标识.那SignalR类库里面是否有这样现有的方法呢?答案是肯定的. // IGroupManager接口提供如下方法 // 作用:将连接ID加入某个组 //

  • Asp.net使用SignalR实现酷炫端对端聊天功能

    一.引言 在前一篇文章已经详细介绍了SignalR了,并且简单介绍它在Asp.net MVC 和WPF中的应用.在上篇博文介绍的都是群发消息的实现,然而,对于SignalR是为了实时聊天而生的,自然少了不像QQ一样的端对端的聊天了.本篇博文将介绍如何使用SignalR来实现类似QQ聊天的功能. 二.使用SignalR实现端对端聊天的思路 在介绍具体实现之前,我先来介绍了使用SignalR实现端对端聊天的思路.相信大家在前篇文章已经看到过Clients.All.sendMessage(name,

  • asp.net mvc signalr简单聊天室制作过程分析

    signalr的神奇.实用很早就知道,但一直都没有亲自去试用,仅停留在文章,看了几篇简单的介绍文字,感觉还是很简单易用的. 由于最后有个项目需要使用到它,所以就决定写个小程序测试一下,实践出真知:别人写的文章,由于环境(版本等)不同,还是或多或少存在一些出入的. 环境:vs2013 / asp.net mvc 5 / signalr 2.2.1 / jquery 1.10.2 先上两个效果图: 系统会自动给加入聊天室的人员分配一个ID,是该人员的唯一标识(绿色为当前用户说的话,橙色为当前用户之外

  • Asp.net SignalR创建实时聊天应用程序

    一.概述 使用 ASP.NET 那么 SignalR 2 创建一个实时聊天应用程序.将 SignalR 添加 MVC 5 应用程序中,并创建聊天视图发送并显示消息. 在Demo中,将学习SignalR 开发任务包括 ︰ 向 MVC 5 应用程序添加那么 SignalR 图书馆. 创建集线器和浩然启动类,以将内容推送到客户端. 使用 web 页中的那么 SignalR jQuery 库发送邮件并显示更新从集线器. 下面的屏幕快照显示在浏览器中运行的已完成的聊天应用程序. 二.实现 创建一个 ASP

  • Asp.net通过SignalR2进行实时聊天

    目录 一:什么是signalR 1.SignalR传输方式 1.HTML5 传输 2.Comet 传输 2.SignalR连接模式 二.服务端 1.添加服务端Hub 2.添加OWIN 启动类 三.客户端 四.运行结果 五.一对一聊天实例 一:什么是signalR Asp.net SignalR是微软为实现实时通信的一个类库. 一般情况下,signalR会使用JavaScript的长轮询(long polling)的方式来实现客户端和服务器通信,随着Html5中WebSockets出现,Signa

  • WPF+ASP.NET SignalR实现简易在线聊天功能的示例代码

    目录 涉及知识点 什么是ASP.NET SignalR 在线聊天整体架构 ASP.NET SignalR在线聊天服务端 1. 创建ASP.NET Web API项目 2. 创建消息通知中心Hub 3. 注册服务和路由 4. ASP.NET SignalR中心对象生存周期 SignalR客户端 1. 安装SignalR客户端依赖库 2. 客户端消息接收发送 运行示例 在实际业务中,当后台数据发生变化,客户端能够实时的收到通知,而不是由用户主动的进行页面刷新才能查看,这将是一个非常人性化的设计.有没

  • HTML5基于Tomcat 7.0实现WebSocket连接并实现简单的实时聊天

    1.什么是WebSocket? WebSocket 是一种自然的全双工.双向.单套接字连接.使用WebSocket,你的HTTP 请求变成打开WebSocket 连接(WebSocket 或者WebSocket over TLS(TransportLayer Security,传输层安全性,原称"SSL"))的单一请求,并且重用从客户端到服务器以及服务器到客户端的同一连接.WebSocket 减少了延迟,因为一旦建立起WebSocket 连接,服务器可以在消息可用时发送它们.例如,和轮

  • Node.js websocket使用socket.io库实现实时聊天室

    认识websocket WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duple).一开始的握手需要借助HTTP请求完成. 其实websocket 并不是很依赖Http协议,它也拥有自己的一套协议机制,但在这里我们需要利用的socket.io 需要依赖到http . 之前用java jsp写过一个聊天,其实实现逻辑并不难,只是大部分时间都用在UI的设计上,其实现原理就是一个基于websocket的通信,要想做一个好的聊天室,我觉得大部

  • javascript和jQuery实现网页实时聊天的ajax长轮询

    介绍 大家都知道,HTTP协议是一个属于应用层的面向对象的协议,HTTP 协议一共有五大特点: 1.支持客户/服务器模式; 2.简单快速; 3.灵活; 4.无连接; 5.无状态. 所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的长时间联系,从而源源不段地获取信息. 一直以来的方式无非有这么几种: 1.长连接,即服务器端不断开联系,PHP服务器端用ob系列函数来不停的读取输出,但是相当耗费服务器资源. 2.Flash socket,

  • 值得分享的php+ajax实时聊天室

    非常经典的一款php+ajax实时聊天室,其中使用PHP文件保存聊天记录,按天划分,PHP实现聊天的功能只有一个文件,整合了PHP与AJAX技术,也就是说只要运行这一个文件就可以启动PHP的聊天室了,关于代码上面也是非常的简单,但是实现了聊天室一般的功能,聊天时的昵称,更改昵称的颜色,聊天字号大小,字体,加粗,窗体的变大变小等等,如果你想搞个聊天室来玩玩,这个源码完全可以满足普通的需求. 具体的效果看如下图: 关键代码: <?php header('content-type:text/html;

  • 微信小程序实时聊天WebSocket

    本文实例为大家分享了微信小程序实时聊天WebSocket的具体代码,供大家参考,具体内容如下 1.所有监听事件先在onload监听. // pages/index/to_news/to_news.js var app = getApp(); var socketOpen = false; var SocketTask = false; var url = 'ws://192.168.0.120:7011'; Page({ data: { inputValue: '', returnValue:

  • 详解微信小程序开发聊天室—实时聊天,支持图片预览

    第一次写小程序,老板就让我用websoket写个聊天对话,群聊这种.第一次写聊天功能,第一次用websoket,第一次用小程序,这是在考验我吗?不过我还是研究了一下,终于实现了. 首先看一下界面,界面很简单,就是首页刚进来获取了用户信息头像,昵称等.点击进入聊天室就可以聊天了,下面我介绍的是前端代码实现,后台需要做的很简单,就是你给他发送什么数据,他就给你返回什么数据,就是在接收前台发送过来的图片的时候需要做个格式转换,因为有时候前端将接收到的json字符串转换json对象的时候,遇到有特殊的标

  • Django Channels 实现点对点实时聊天和消息推送功能

    简介在很多实际的项目开发中,我们需要实现很多实时功能:而在这篇文章中,我们就利用django channels简单地实现了点对点聊天和消息推送功能. 手边有一个项目需要用到后台消息推送和用户之间一对一在线聊天的功能.例如用户A评论了用户B的帖子,这时候用户B就应该收到一条通知,显示自己的帖子被评论了.这个功能可以由最基本的刷新页面后访问数据库来完成,但是这样会增加对后台服务器的压力,同时如果是手机客户端的话,也会造成流量的损失.于是,我们考虑使用websocket建立一个连接来完成这个功能. 但

随机推荐