原文:一步一步学习SignalR进行实时通信_2_Persistent Connections

一步一步学习SignalR进行实时通信\_2_Persistent Connections

SignalR


前言

上一篇文章简单的介绍了下SignalR,从此篇文章就开始对SignalR进行剖析。在介绍Persistent connections之前,先简单介绍下安装signalR的方法。

我的开发环境:win10+vs2013

安装

  1. 首先我们新建一个空的MVC5的项目

  2. 通过Nuget[1]安装SignalR,通过Tools->Nuget Package Manager->Package Manager Console打开Package Manager Console
  3. 输入安装语句Install-Package Microsoft.AspNet.SignalR

    可以看到添加了JQuery和SignalR2.0

Persistent Connections

映射并配置持久连接

如果我们要是实现基于PersistentConnection的实时信息传输,首先第一步我们需要在服务器启动时对SignalR进行配置。由于我们是基于Owin来实现SignalR的所以,我们在Startup中找到Configuration中配置,类似如果我们要实现其他的Owin框架我们也可以在这里进行配置。

  1. 映射

    1. using System;
    2. using System.Threading.Tasks;
    3. using Microsoft.Owin;
    4. using Owin;
    5. using SignalR_2.Models;
    6. //设置Owin的启动项
    7. [assembly: OwinStartup(typeof(SignalR_1.Startup))]
    8. namespace SignalR_·
    9. {
    10. public class Startup
    11. {
    12. public void Configuration(IAppBuilder app)
    13. {
    14. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
    15. app.MapSignalR<EchoConnection>("/echo");
    16. }
    17. }
    18. }

    通过MapSignalR()方法来做映射,/echo表示将会映射到/echo,后面我我们转到MapSignalR定义

    " title="">

    MapSignalR()是一个扩展方法,它有许多重载方法,而我们主要关心的就是如图所示的泛型方法。这个方法的TConnection要求是一个PersistentConnection类型。

    好了,到此为止我们已经知道我们需要什么了,没必要继续深究下去。通过以上的研究,很明显,我们需要构造这么一个类去继承PersistentConnection来实现SignalR服务

  2. 实现SignalR服务

    我们新建一个类叫做EchoConnection,代码如下:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Threading;
    5. using System.Threading.Tasks;
    6. using System.Web;
    7. using Microsoft.AspNet.SignalR;
    8. namespace SignalR_1.Models
    9. {
    10. public class EchoConnection : PersistentConnection
    11. {
    12. /// <summary>
    13. /// 当前连接数
    14. /// </summary>
    15. private static int _connections = 0;
    16. /// <summary>
    17. /// 连接建立时执行
    18. /// </summary>
    19. /// <param name="request"></param>
    20. /// <param name="connectionId"></param>
    21. /// <returns></returns>
    22. protected override async Task OnConnected(IRequest request, string connectionId)
    23. {
    24. //原子操作,防止多条现成同时+1而只做一次变化
    25. Interlocked.Increment(ref _connections);
    26. await Connection.Send(connectionId, "Hi, " + connectionId + "!");
    27. await Connection.Broadcast("新连接 " + connectionId + "开启. 当前连接数: " + _connections);
    28. }
    29. /// <summary>
    30. /// 连接关闭时执行
    31. /// </summary>
    32. /// <param name="request"></param>
    33. /// <param name="connectionId"></param>
    34. /// <returns></returns>
    35. protected override Task OnDisconnected(IRequest request, string connectionId)
    36. {
    37. //原子操作,防止多条现成同时-1而只做一次变化
    38. Interlocked.Decrement(ref _connections);
    39. return Connection.Broadcast(connectionId + " 连接关闭. 当前连接数: " + _connections);
    40. }
    41. /// <summary>
    42. /// 连接开始时执行
    43. /// </summary>
    44. /// <param name="request"></param>
    45. /// <param name="connectionId"></param>
    46. /// <param name="data"></param>
    47. /// <returns></returns>
    48. protected override Task OnReceived(IRequest request, string connectionId, string data)
    49. {
    50. var message = connectionId + ">> " + data;
    51. return Connection.Broadcast(message);
    52. }
    53. }
    54. }

    我们定义了一个EchoConnection类继承PersistentConnetion,并写了OnConnectedOnDisconnectedOnReceived、三个方法,大致功能是当客户端连接时,服务器会通过Send()方法向它打招呼,参数是他的ConnectionId,并发送广播消息给所有客户端,并使总连接数+1,当客户端关闭连接时,服务器会广播给所有客户端XXX连接关闭,并使总连接数-1

  3. 客户端实现

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <title>persistent connections</title>
  5. <script src="Scripts/jquery-1.10.2.min.js"></script>
  6. <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
  7. </head>
  8. <body>
  9. <h1>Echo service</h1>
  10. <div>
  11. <input type="text" id="text" />
  12. <button id="send">Send</button>
  13. </div>
  14. <script>
  15. $(function () {
  16. var connection = $.connection("/echo");
  17. connection.logging = true;
  18. connection.received(function (data) {
  19. $("body").append(data + "<br />");
  20. });
  21. connection.error(function (err) {
  22. alert("存在一个错误. \n" +
  23. "Error: " + err.message);
  24. });
  25. connection.start().done(function () {
  26. $("#send").click(function () {
  27. connection.send($("#text").val());
  28. $("#text").val("").focus();
  29. });
  30. });
  31. });
  32. </script>
  33. </body>
  34. </html>

对上面的代码有疑问看下面的图片

如图所示:左边是客户端的javascript代码,右边是服务器的代码

当客户端调用start方法时,会执行服务器的OnConnected方法

当客户端点击发送按钮发送消息时,服务端会在OnReceived中接收到消息

当服务端对消息进行发送或广播给客户端时,客户端receive会接收到此消息

结束语

这里通过PersistentConnection实现了在线聊天的简单例子。

注意在项目运行期间,我出现过几次程序集版本不对的情况,若出现此种情况,通过Install-Package XXX 重装该程序集或Update-Package XXX升级该程序集,一般均可解决

源码下载

本文发布至作业部落

参考文献

SignalR Programming in Microsoft ASP.NET pdf 下载


[1] NuGet 是免费、开源的包管理开发工具。

一步一步学习SignalR进行实时通信_2_Persistent Connections的更多相关文章

  1. 一步一步学习SignalR进行实时通信_1_简单介绍

    一步一步学习SignalR进行实时通信\_1_简单介绍 SignalR 一步一步学习SignalR进行实时通信_1_简单介绍 前言 SignalR介绍 支持的平台 相关说明 OWIN 结束语 参考文献 ...

  2. 一步一步学习SignalR进行实时通信_8_案例2

    原文:一步一步学习SignalR进行实时通信_8_案例2 一步一步学习SignalR进行实时通信\_8_案例2 SignalR 一步一步学习SignalR进行实时通信_8_案例2 前言 配置Hub 建 ...

  3. 一步一步学习SignalR进行实时通信_9_托管在非Web应用程序

    原文:一步一步学习SignalR进行实时通信_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信\_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信_9_托管在非We ...

  4. 一步一步学习SignalR进行实时通信_7_非代理

    原文:一步一步学习SignalR进行实时通信_7_非代理 一步一步学习SignalR进行实时通信\_7_非代理 SignalR 一步一步学习SignalR进行实时通信_7_非代理 前言 代理与非代理 ...

  5. 一步一步学习SignalR进行实时通信_5_Hub

    原文:一步一步学习SignalR进行实时通信_5_Hub 一步一步学习SignalR进行实时通信\_5_Hub SignalR 一步一步学习SignalR进行实时通信_5_Hub 前言 Hub命名规则 ...

  6. 一步一步学习SignalR进行实时通信_6_案例

    原文:一步一步学习SignalR进行实时通信_6_案例 一步一步学习SignalR进行实时通信\_6_案例1 一步一步学习SignalR进行实时通信_6_案例1 前言 类的定义 各块功能 后台 上线 ...

  7. 一步一步学习SignalR进行实时通信_4_Hub

    原文:一步一步学习SignalR进行实时通信_4_Hub 一步一步学习SignalR进行实时通信\_4_Hub SignalR 一步一步学习SignalR进行实时通信_4_Hub 前言 创建Hub 配 ...

  8. 一步一步学习SignalR进行实时通信_3_通过CORS解决跨域

    原文:一步一步学习SignalR进行实时通信_3_通过CORS解决跨域 一步一步学习SignalR进行实时通信\_3_通过CORS解决跨域 SignalR 一步一步学习SignalR进行实时通信_3_ ...

  9. 12.Linux软件安装 (一步一步学习大数据系列之 Linux)

    1.如何上传安装包到服务器 有三种方式: 1.1使用图形化工具,如: filezilla 如何使用FileZilla上传和下载文件 1.2使用 sftp 工具: 在 windows下使用CRT 软件 ...

随机推荐

  1. python heapq

    这个模块(build-in)实现了一个堆的数据结构,完美的解决了Top-K问题,以后解决Top-K问题的时候,直接把这个模块拿来用就可以了 注意,默认的heap是一个小顶堆! heapq模块提供了如下 ...

  2. PHP MySql数据库访问

    PHP MySql数据库访问 计应134   凌豪 1.MySql数据库的连接 要操作MySql数据库,首先必须与MySQl数据库建立连接,连接MySQL服务器的语句如下: <?php$link ...

  3. symfony的安装

    Symfony 是一个基于MVC的PHP框架,最新版本为2.7 工作原理 Synfony安装的两种方法 1.使用composer进行安装 1)下载composer http://getcomposer ...

  4. C#学习日志 day 6 ------ 常用正则表达式例举

    c#支持正则表达式匹配文本,这里讨论一下正则表达式的使用方法以及例举一些常用的正则表达式的匹配. 1.在vs中使用正则表达式 在vs中使用正则表达式,需要using System.Text.Regul ...

  5. 9.java.lang.ClassCastException

    java.lang.ClassCastException 数据类型转换异常 当试图将对某个对象强制执行向下转型,但该对象又不可转换又不可转换为其子类的实例时将引发该异常,如下列代码. Object o ...

  6. JavaEE Tutorials (17) - Java消息服务示例

    17.1JMS示例概述23317.2编写简单的JMS应用233 17.2.1启动JMS提供者234 17.2.2创建JMS受管理对象234 17.2.3构建所有简单示例235 17.2.4发送消息23 ...

  7. MFC 可以设置背景色、字体、字体颜色、透明背景的 Static 静态文本控件

    MFC库里没有符合这个条件的控件,于是我自己写了一个,初步测试有效. 注:可以设置透明背景,但还不能做到透明度设置(如50%透明度) 如果设置了背景色,就不保留透明背景 默认背景色是透明的 [cpp] ...

  8. [Leetcode][Python]26: Remove Duplicates from Sorted Array

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 26: Remove Duplicates from Sorted Array ...

  9. powerpc e500系列,linux初始化的tlb汇编,添加人肉代码注释

    powerpc e500的内核启动,关于tlb的初始化可以说是重头戏.看懂这段代码后,powerpc的虚实映射基本不在话下. 这段初始化tlb要考虑的,主要是将boot可能初始化过的tlb全清零,然后 ...

  10. [置顶] 北漂的大三IT男(暂完)

    今天是2013年8月9日,是我待在北京的最后一个晚上,今天我已经正式向公司提出辞职了,虽然公司已经答应从下个月起涨部分工资,但是我还是坚决的离开了,回想当时进公司的想法----------干了一个月后 ...