Asp.NET MVC3 使用 SignalR 实现推送

一,简介

Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架。它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请求或使用轮询技术来获取消息。

二,实现机制

SignalR 的实现机制与 .NET WCF 或 Remoting 是相似的,都是使用远程代理来实现。在具体使用上,有两种不同目的的接口:PersistentConnection 和 Hubs,其中 PersistentConnection 是实现了长时间的 Javascript 轮询(类似于 Comet),Hub 是用来解决实时信息交换问题,它是利用 Javascript 动态载入执行方法实现的。SignalR 将整个连接,信息交换过程封装得非常漂亮,客户端与服务器端全部使用 JSON 来交换数据。

三,实现 Hub 服务器端代码

向工程中新建 SignalR 目录,在其中添加 ChatHub.cs 文件,内容如下:

namespace SignalTutorial.SignalR
{
    [HubName("chat")]
    public class Chat : Hub
    {
        public void Send(string clientName, string message)
        {
            //var toSelfinfo = "You had sent message " + message;
            //Caller.addSomeMessage(clientName, toSelfinfo);

            // Call the addMessage method on all clients
            Clients.addSomeMessage(clientName, message);
            //Clients[Context.ConnectionId].addSomeMessage(clientName, data);
        }
    }
}

1),HubName 这个特性是为了让客户端知道如何建立与服务器端对应服务的代理对象,如果没有设定该属性,则以服务器端的服务类名字作为 HubName 的缺省值;

2),Chat 继承自 Hub,从下面 Hub 的接口图可以看出:Hub 支持向发起请求者(Caller),所有客户端(Clients),特定组(Group) 推送消息。

3),public void Send(string clientName, string message) 这个接口是被客户端通过代理对象调用的;

4),Clients 是 Hub 的属性,表示所有链接的客户端页面,它和 Caller 一样是 dynamic,因为要直接对应到 Javascript 对象;

5),Clients.addSomeMessage(clientName, message); 表示服务器端调用客户端的 addSomeMessage 方法,这是一个 Javascript 方法,从而给客户端推送消息。

6),总结:这里实现的服务很简单,就是当一个客户端调用 Send 方法向服务器发送 message 后,服务器端负责将该 message 广播给所有的客户端(也可以给特定组或特定客户端,见屏蔽代码),以实现聊天室的功能。

四,实现 Hub 客户端代码

<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.5.1.min.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/jquery-1.6.4.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/jquery-ui-1.8.24.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/jquery.signalR-0.5.3.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/signalr/hubs")" type="text/javascript"></script>
    </head>

注意:signalR 依赖于 jquery,所以 signalR 必须放在 jquery 之后,而 hubs 又必须放在 signalR 之后。

然后在 body 部分加入 HubChat Tab:

@model dynamic

@{
    ViewBag.Title = "title";
}

<script src="@Url.Content("~/Scripts/hubDemo.js")" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function () {
    });
</script>

<h2>Hub Chat</h2>

<div>
    <input type="text" id="Placeholder" value="@ViewBag.ClientName" hidden="true"/>
    <input type="text" id="msg" />
    <input type="button" id="broadcast" value="广播" />
    
    <br />
    <br />

    <h3>
        消息记录: (你是:<span id="MyClientName">@ViewBag.ClientName</span>):
    </h3>

    <ul id="messages">
    </ul>
</div>

向 Scripts 目录添加新的 Javescript 脚本:hubDemo.js。其内容如下:

$(function () {

    var myClientName = $(‘#Placeholder‘).val();

    // Proxy created on the fly
    var chat = $.connection.chat;

    // Declare a function on the chat hub so the server can invoke it
    chat.addSomeMessage = function (clientName, message) {
        writeEvent(‘<b>‘ + clientName + ‘</b> 对大家说: ‘ + message, ‘event-message‘);
    };

    $("#broadcast").click(function () {
        // Call the chat method on the server
        chat.send(myClientName, $(‘#msg‘).val())
                            .done(function () {
                                console.log(‘Sent message success!‘);
                            })
                            .fail(function (e) {
                                console.warn(e);
                            });
    });

    // Start the connection
    $.connection.hub.start();

    //A function to write events to the page
    function writeEvent(eventLog, logClass) {
        var now = new Date();
        var nowStr = now.getHours() + ‘:‘ + now.getMinutes() + ‘:‘ + now.getSeconds();
        $(‘#messages‘).prepend(‘<li class="‘ + logClass + ‘"><b>‘ + nowStr + ‘</b> ‘ + eventLog + ‘.</li>‘);
    }
});

我已经运行过一次,可以正常运行,

Persistent Connection部分,下节再介绍。大家如果发现什么问题,可以指出,谢谢。


Asp.NET MVC3 使用 SignalR 实现推送,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。