Fork me on GitHub
SignalR QuickStart

SignalR QuickStart

 

SignalR 是一个集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话。 换句话说,该对话可不受限制地进行单个无状态请求/响应数据交换;它将继续,直到明确关闭。 对话通过永久连接进行,允许客户端向服务器发送多个消息,并允许服务器做出相应答复,值得注意的是,还允许服务器向客户端发送异步消息。它和AJax类似,都是基于现有的技术。本身是一个复合体。一般情况下,SignalR会使用Javascript的长轮询( long polling),实现客户端和服务端通信。在WebSockets出现以后,SignalR也支持WebSockets通信。当然SignalR也使用了服务端的任务并行处理技术以提高服务器的扩展性。它的目标整个 .NET Framework 平台,它也不限 Hosting 的应用程序,而且还是跨平台的开源项目,支持Mono 2.10+,觉得它变成是 Web API 的另一种实作选择,但是它在服务端处理联机的功能上比 ASP.NET MVC 的 Web API 要强多了,更重要的是,它可以在 Web Form 上使用。

SignalR 内的客户端库 (.NET/JavaScript) 提供了自动管理的能力,开发人员只需要直接使用 SignalR 的 Client Library 即可,同时它的 JavaScript 库可和 jQuery 完美整合,因此能直接与像 jQuery 或 Knockout.js 一起使用。

SignalR内部有两类对象:

· Persistent Connection:持久性连接,用来解决长时间连接的能力,而且还可以由客户端主动向服务器要求数据,而服务器端也不需要实现太多细节,只需要处理 PersistentConnection 内所提供的五个事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。

· Hub:信息交换器,用来解决 realtime 信息交换的功能,服务器端可以利用 URL 来注册一个或多个 Hub,只要连接到这个 Hub,就能与所有的客户端共享发送到服务器上的信息,同时服务器端可以调用客户端的脚本,不过它背后还是不离 HTTP 的标准,所以它看起来神奇,但它并没有那么神奇,只是 JavaScript 更强,强到可以用像 eval() 或是动态解释执行的方式,允许 JavaScript 能够动态的加载与执行方法调用而己。

SignalR 将整个交换信息的行为封装得非常漂亮,客户端和服务器全部都使用 JSON 来沟通,在服务器端声明的所有 hub 的信息,都会一般生成 JavaScript 输出到客户端,.NET 则是依赖 Proxy 来生成代理对象,这点就和 WCF/.NET Remoting 十分类似,而 Proxy 的内部则是将 JSON 转换成对象,以让客户端可以看到对象。

下面我们来针对Persistent Connection和Hub 做个Demo试试:

新建一个ASP.NET MVC项目MvcApplicationSignalR,通过Nuget添加SignalR的包。

新建一个类MyConnection 继承自 PersistentConnection ,引用SignalR命名空间,重写OnReceivedAsync 的方法,并要求 SignalR 对传入的信息做广播

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using SignalR; 
using System.Threading.Tasks;

namespace MvcApplicationSignalR 

   public  class MyConnection : PersistentConnection

    { 
       protected override Task OnReceivedAsync(IRequest request, string connectionId, string data) 
        { 
            // Broadcast data to all clients 
            data = string.Format("数据是:{0} 时间是:{1}", data, DateTime.Now.ToString()); 
            return Connection.Send(connectionId, data); 
        }

    } 
}

接着在 Global.asax 中加入对应路由信息,这会由 SignalR 的路由表来处理 Metadata 的输出工作,红色部分代码:

protected void Application_Start() 

    RouteTable.Routes.MapConnection<MyConnection>("echo", "echo/{*operation}");

 

这样服务器端就完成了。现在我们在项目中Master、View (Home/Index),然后加入必要的代码:

<head> 
    <meta charset="utf-8" /> 
    <title>@ViewBag.Title</title> 
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> 
    <script src="@Url.Content("~/Scripts/jquery-1.6.4.min.js")" type="text/javascript"></script> 
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script> 
    <script src="@Url.Content("~/Scripts/jquery.signalR-0.5.2.min.js")" type="text/javascript"></script> 
</head>

@{ 
    ViewBag.Title = "Home Page"; 

<script type="text/javascript"> 
    $(function () { 
        var connection = $.connection('echo');

        connection.received(function (data) { 
            $('#messages').append('<li>' + data + '</li>'); 
        });

        connection.start();

        $("#broadcast").click(function () { 
            connection.send($('#msg').val()); 
        }); 
        $("#btnStop").click(function () { 
            connection.stop(); 
        }); 
    });

</script> 
<h2>@ViewBag.Message</h2> 
<input type="text" id="msg" /> 
<input type="button" id="broadcast" value="发送" /> 
<input type="button" id="btnStop" value="停止" /> 
<ul id="messages"> 
</ul>

运行起来就是这个效果:

image

下面我们来展示 SignalR 的另一个功能:由服务器端调用客户端的 JavaScript 脚本的功能,而这个功能的要求必须是要实现成 Hub 的模式,因此我们可以顺便看到如何实现一个 Hub 类型的 SignalR 应用程序。

向项目中加入一个类Chat继承自 Hub 类 (这是 Hub 应用程序的要求) :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using SignalR.Hubs; 
using System.Threading.Tasks; 
using System.Threading;

namespace MvcApplicationSignalR 

   [HubName("geffChat")] 
   public class Chat : Hub  
   { 
       public void SendMessage(string message) 
       { 
           Clients.sendMessage(message); 
       } 
   } 
}

这段程序代码的用意是,在连接进到 Hub 时,将连接代码加到联机用户的集合中,等会就会使用到,因为我们会依照客户端的 ID 来调用客户端脚本。

1. HubName:这个 atttibute 代表 client 端要如何建立对应 server 端对象的 proxy object。通过 HubName , server 端的 class name才不会被 client 绑死。如果没有设定,则会以 server 端 class name 为 HubName 默认值。

2. 继承 Hub:继承 Hub 之后,很多对应的设计就都不用写了,我们只需要把注意力放在 client 如何送 request 给 server的 hub , server 如何通知 client 即可。

3. public void SendMessage(string message) ,就像 WebService Method 或 PageMethod 一般, client 端通过 proxy object ,可以直接调用 server 端这个方法。后续会介绍到如何在页面上使用。

4. Clients 属性:代表所有有使用 Chat 的页面。而 Clients 的型别是 dynamic ,因为要直接对应到 JavaScript 的对象。

5. Clients.sendMessage(message):代表 server 端调用 Clients 上的 sendMessage 方法,也就是 JavaScript 的方法。

6. 总结: Chat 对象职责就是当 client 端调用SendMessage() 方法后,要把这个 message ,送给所有 client 页面上呈现。以达到聊天室的功能。

服务端的做完了,开始制作客户端,同样在Home/Index页面上增加以下html代码

<%--很重要的一个参考,一定要加,且在这一行之前,一定要先参考jQuery.js与signalR.js--%> 
<script src="@Url.Content("~/signalr/hubs")" type="text/javascript"></script>

@{ 
    ViewBag.Title = "Home Page"; 

<script type="text/javascript"> 
    $(function () { 
        var connection = $.connection('/echo');    

        connection.received(function (data) { 
            $('#messages').append('<li>' + data + '</li>'); 
        });

        connection.start();

        $("#broadcast").click(function () { 
            connection.send($('#msg').val()); 
        }); 
        $("#btnStop").click(function () { 
            connection.stop(); 
        });

        // 建立对应server端Hub class的对象,请注意geffChat的第一个字母要改成小写 
        var chat = $.connection.geffChat;

        // 定义client端的javascript function,供server端hub,通过dynamic的方式,调用所有Clients的javascript function 
        chat.sendMessage = function (message) { 
            //当server端调用sendMessage时,将server push的message数据,呈现在wholeMessage中 
            $('#wholeMessages').append('<li>' + message + '</li>'); 
        };

        $("#send").click(function () { 
            //调用叫server端的Hub对象,将#message数据传给server 
            chat.sendMessage($('#message').val()); 
            $('#message').val(""); 
        });

        //把connection打开 
        $.connection.hub.start();

    });

</script> 
<h2>@ViewBag.Message</h2> 
<input type="text" id="msg" /> 
<input type="button" id="broadcast" value="发送" /> 
<input type="button" id="btnStop" value="停止" /> 
<ul id="messages"> 
</ul>

<div> 
    <input type="text" id="message" /> 
    <input type="button" id="send" value="发送" /> 
    <div> 
        聊天室内容: 
        <br /> 
        <ul id="wholeMessages"> 
        </ul> 
    </div> 
</div>

1. 先引用 jQuery 与 signalR 的 js 文件。

2. 很重要的一个步骤:加入一个 js 引用,其路径为「根目录/signalr/hubs」。 SignalR 会建立相关的 JavaScript,放置于此。

3. 通过 $.connection.『server 端的 HubName』,即可建立对应该 hub 的 proxy object。要注意,首字母需小写。

4. 定义 client 端上,供 server 端通知的 JavaScript function,这边的例子是 sendMessage。

5. 当按下发送按钮时,调用 server 端的 SendMessage() 方法,只需要直接通过 proxy object 即可。要注意,首字母需小写。

6. 记得透过 $.connection.hub.start() ,把 connection 打开。

image

注意:SingalR 会自动生成一个siganlr/hub 的桥接js..,在本机使用localhost测试都不会有问题。当部署到IIS的时候会发生404错误,是由于被IIS误判可能是虚拟目录…,解决方法是在web.config加入一段:

<!-- 加入下面这一段-->

<system.webServer>

<validation validateIntegratedModeConfiguration="false" />

<modules runAllManagedModulesForAllRequests="true">

</modules>

</system.webServer>

参考:

实例代码:MvcApplicationSignalR

作者: 自由、创新、研究、探索……
出处:http://shanyou.cnblogs.com/
版权:本文版权归作者和博客园共有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任 
分类: ASP.NETSignalR
 
绿色通道: 好文要顶 已关注 收藏该文

什么是nosql

NoSQL(NoSQL = Not Only SQL),意思是不仅仅是SQL的扩展,一般指的是非关系型的数据库。

随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,传统的电信行业动辍就千万甚至上亿的数据,甚至有客户提出需要存储相关的日志数据50年以上,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。

关系型数据库难以克服的问题:

  • 不能很好处理对数据库高并发读写的需求
  • 不能很好处理对海量数据的高效率存储和访问的需求
  • 不能很好处理对数据库的高可扩展性和高可用性的需求

为什么使用nosql

SQL语言和关系型数据库(MySQL、PostgreSQL、Oracle等)是通用的数据解决方案,占有绝大多数的市场。但是就像上面提到的,它有很多难以解决的问题。不过在最近兴起的NoSQL运动中,涌现出一批具备高可用性、支持线性扩展、支持Map/Reduce操作等特性的数据产品,它们具有如下特性:

  • 频繁的写入操作、相对较少的读取统计信息的操作
  • 海量数据(如数据仓库中需要分析的数据)适合存储在一个结构松散、分布式的文件存储系统中
  • 存储二进制文件(如mp3或者pdf文档)并且能够直接为用户的浏览器提供下载功能

使用这些数据产品并不是要取代原有的数据产品,而是为不同的应用场景提供更多的选择。也就是说,在一些特定的情况下如果是关系型的数据库解决不了的问题,那么就可以考虑使用nosql,而不是说完全将应用移植到nosql上,毕竟适合才是最好的。

现在流行的nosql

下面对现在的nosql进行了整理,其中包括各种nosql的官方网站。

15个nosql数据库

HBase是什么

HBase是Apache Hadoop中的一个子项目,Hbase依托于Hadoop的HDFS作为最基本存储基础单元,通过使用hadoop的DFS工具就可以看到这些这些数据 存储文件夹的结构,还可以通过Map/Reduce的框架(算法)对HBase进行操作,如下图所示:

HBase在产品中还包含了Jetty,在HBase启动时采用嵌入式的方式来启动Jetty,因此可以通过web界面对HBase进行管理和查看当前运行的一些状态,非常轻巧方便。

HBase是Apache Hadoop中的一个子项目,现已成为Apache的顶级项目。

HBase是Google Bigtable(基于Google File System)的开源山寨版本。

为什么采用HBase

HBase 不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库.所谓非结构化数据存储就是说HBase是基于列的而不是基于行的模式,这样方便读写你的大数据内容。

HBase是介于Map Entry(key & value)和DB Row之间的一种数据存储方式。就点有点类似于现在流行的Memcache,但不仅仅是简单的一个key对应一个 value,你很可能需要存储多个属性的数据结构,但没有传统数据库表中那么多的关联关系,这就是所谓的松散数据。

简单来说,你在HBase中的表创建的可以看做是一张很大的表,而这个表的属性可以根据需求去动态增加,在HBase中没有表与表之间关联查询。你只需要 告诉你的数据存储到Hbase的那个column families 就可以了,不需要指定它的具体类型:char,varchar,int,tinyint,text等等。但是你需要注意HBase中不包含事务此类的功能。

Apache HBase 和Google Bigtable 有非常相似的地方,一个数据行拥有一个可选择的键和任意数量的列。表是疏松的存储的,因此用户可以给行定义各种不同的列,对于这样的功能在大项目中非常实用,可以简化设计和升级的成本。

HBase的存储结构

HBase 是基于列的数据库,让我们看一下关系型数据库和hbase数据库存储的对比。

行式存储和列式存储对比:

行式存储

  • 数据是按行存储的
  • 没有索引的查询使用大量I/O
  • 建立索引和物化视图需要花费大量时间和资源
  • 面对查询的需求,数据库必须被大量膨胀才能满足性能要求

列式存储

数据按列存储——每一列单独存放

数据即是索引

只访问查涉及的列——大量降低系统IO

每一列由一个线索来处理——查询的并发处理

数据类型一致,数据特征相似——高效压缩

HBase与关系型数据库的对比

HBase 是基于

下面的表格中hbase和RDBMS的对比关系

 

HBase

RDBMS

数据类型

只有字符串

丰富的数据类型

数据操作

简单的增删改查

各种各样的函数,表连接

存储模式

基于列存储

基于表格结构和行存储

数据保护

更新后旧版本仍然会保留

替换

可伸缩性

轻易的进行增加节点,兼容性高

需要中间层,牺牲功能

 

 

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
如果,您希望更容易地发现我的新博客,不妨关注一下 skyme。
因为,我的写作热情也离不开您的肯定支持。
未注明转载的文章,版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类: 
标签: 云计算nosql
posted on 2012-07-30 09:34  HackerVirus  阅读(309)  评论(0编辑  收藏  举报