SignalR入门篇

写在前面的废话

在写关于SignalR的学习笔记之前研究了几天的webSocket,毕竟这才是未来的技术趋势,虽然很早就听说过WebSocket,但是并没有在实际项目中遇到过,所以也就没有深入研究。通过这几天的研究发现WebSocket虽好,但是实现起来还是蛮繁琐的(有第3方封装好的库可以直接调用),特别是对于握手成功之后数据帧的解析,这需要对RFC6455非常了解。而且IE10以下的浏览器并不支持,而且服务端也得IIS8及以上才支持。

通过百度各位大牛的足迹,了解到了SignalR,这货是微软封装好的基于B/S架构下的即时通讯组件,说白了就是如果条件支持,它就使用WebSocket技术来进行浏览器与服务器的实时通信,如果使用者的环境不支持的话,它就会采取Ajax轮循的方法来达到这一目的。而且还不用你解析WebSocket的数据帧,同时又能兼顾那些舍不得升级系统的老忠户,这不是一举两得么?

不过说真的,做为技术人员,学习最原始的WebSocket,并自己写代码去实现握手及解析数据帧,那是非常棒的一件事,只能说是有百利而无一害,不过这都是后话了。

关于这篇文章

首先声明这篇文章不是我的原创(有那心,没那能力哎!),充其量只是个学习笔记,如果有兴趣的话,请参考原文:Getting Started with SignalR 2,好了不说废话了,咱们就来讲一下如何利用SignalR来实现一个即时聊天的页面,聊天界面如下图所示。

聊天界面

创建项目

我使用的是Visual Studio 2015,下面的步骤也是基于vs2015来的,其它版本应该类似。

1.使用vs创建一个新的ASP.NET Web Application

创建新项目

2.在选择新建项目对话框中,选择Empty模板,然后点击OK创建项目

选择模板

3.在Solution Explorer,右击该项目,选择Add--New Item,然后选择Visual C#--Web--SignalR菜单,接着选中SignalR Hub Class(v2)选项,然后输入文件名ChatHub.cs后,创建文件。

注意:可以使用NuGet命令 ```
install-package Microsoft.AspNet.SignalR


![创建文件](http://images2015.cnblogs.com/blog/467479/201612/467479-20161214144542995-1805262978.png)

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

	using Microsoft.AspNet.SignalR;

    namespace SignalRChat
    {
        public class ChatHub : Hub
        {
            public void Send(string name, string message)
            {
                // 客户端通过调用broadcastMessage来获取数据
                Clients.All.broadcastMessage(name, message);
            }
        }
    }

5.在**Solution Explorer**中,右击项目,然后添加一个名为**Startup**的类,然后输入下面这段代码。

    using Microsoft.Owin;
    using Owin;

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

    namespace SignalRChat
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.MapSignalR();
            }
        }
    }

6.在项目中添加一个静态网页文件,并命名为**index.html**,然后右击该网页文件,并选择**Set As Start Page**

7.在**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.10.2.js"></script>
        <!--Reference the SignalR library. -->
        <script src="Scripts/jquery.signalR-2.1.2.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 () {
                // Declare a proxy to reference the hub.
                var chat = $.connection.chatHub;
                // Create a function that the hub can call to broadcast messages.
                chat.client.broadcastMessage = function (name, message) {
                    // Html encode display name and message.
                    var encodedName = $('<div />').text(name).html();
                    var encodedMsg = $('<div />').text(message).html();
                    // Add the message to the page.
                    $('#discussion').append('<li><strong>' + encodedName
                        + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
                };
                // Get the user name and store it to prepend to messages.
                $('#displayname').val(prompt('Enter your name:', ''));
                // Set initial focus to message input box.
                $('#message').focus();
                // Start the connection.
                $.connection.hub.start().done(function () {
                    $('#sendmessage').click(function () {
                        // Call the Send method on the hub.
                        chat.server.send($('#displayname').val(), $('#message').val());
                        // Clear text box and reset focus for next comment.
                        $('#message').val('').focus();
                    });
                });
            });
        </script>
    </body>
    </html>

8.保存项目,并按F5运行

## 运行结果

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

![hubs脚本](http://images2015.cnblogs.com/blog/467479/201612/467479-20161214144614761-958661854.png)

## 其它想说的话

使用SignalR,很容易就可以实现B/S模式下的即时通讯。

### 服务端

在**ChatHub**类中,可以看到它继承自**Microsoft.AspNet.SignalR.Hub**。在这个类(**ChatHub**)中定义的公共方法可以被网页内的脚本访问(服务器端的方法名和类名都会被默认设置为首字母小写的方式,想要自定义名称的话,可以参考**HubName**和**HubMethodName**这两个类)

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

### 客户端

客户端通过**jquery.signalR.js**和**signalr/hubs**来与服务器进行通信,首先它要声明一个代理。

	var chat = $.connection.chatHub

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

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

而下面的代码则是为了确保在将消息发送到服务器之前已经与服务器建立了连接。

	// 与服务器建立连接后才能发送消息到服务器
	$.connection.hub.start().done(function () {
        $('#sendmessage').click(function () {
            // 调用服务器端的ChatHub.Send方法,并把消息发送到服务器
            chat.server.send("name", "message");
        });
    });
原文地址:https://www.cnblogs.com/isrocking/p/started-with-signalr.html