ASP.NET Signalr 2.0 实现一个简单的聊天室

  学习了一下SignalR 2.0,http://www.asp.net/signalr 文章写的很详细,如果头疼英文,还可以机翻成中文,虽然不是很准确,大概还是容易看明白。

理论要结合实践,自己动手做了个简单的聊天室。

   

开发环境:Win7 + Visual Studio 2012

主要步骤:

  • 添加SignalR库到你的ASP.NET web 应用.
  • 建立一个Hub类推送内容到客户端.
  • 建立一个 OWIN Startup 类来配置应用.
  • 使用SignalR jQuery库发送和显示信息.

打开vs2012,新建项目ASP.NET MVC4 Web 应用程序(选择.NET Framework 4.5),名称为MyChat

  

下一步选择 Internet 应用程序模板

  

项目建立完成后在解决方案资源管理器中,项目名称上点右键菜单中选择 管理Nuget 程序包... 打开对话框,选择联机 搜索 SignalR

返回搜索结果后 找到并下载,如果没有问题,就会安装SignalR库到你的项目,如果安装过程出现错误,可能是依赖项不符合要求。

需要跨域访问,需要同样方法下载 Microsoft.Owin.Cors 到项目

在解决方案资源管理器 新建文件夹 Hubs ,在这个文件夹上右键菜单 添加一个类文件 ChatHub.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using System.Threading.Tasks;

namespace MyChat.Hubs
{
    public class ChatHub : Hub
    {
        private static Dictionary<string,string> _clients = new Dictionary<string,string>(); //保存在线用户列表
        public Task OnConnected() //暂时无用
        {
            return base.OnConnected();
        }

        public void Send(string name, string message) //处理发送信息
        {
            _clients[Context.ConnectionId] = name;
            Clients.All.addNewMessageToPage(name, message); //广播消息给所有连接到此Hub的客户端,addNewMessageToPage 是客户端定义的
        }

        public void List() //获取在线用户列表
        {
            List<string> list = new List<string>();
            foreach (var k in _clients)
            {
                list.Add(k.Value);
            }
            Clients.Caller.listAll(list);//只发送给调用者, listAll 也是客户端定义的
        }
    }
}

要运行起来还需要一个启动文件,在项目根目录添加一个类文件 Startup.cs ,SignalR 依赖于Owin,需要这个文件,否则会报错

using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Cors;
[assembly: OwinStartup(typeof(MyChat.Startup))]
namespace MyChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.UseCors(CorsOptions.AllowAll); //跨域支持
            app.MapSignalR(); //路由映射
        } 
    }
}

服务端就写好了,下面开始客户端。在Controller 文件夹右键,添加一个控制器 ChatController, 并给Index 方法添加一个视图

代码如下

@{
    ViewBag.Title = "聊天";
}
<h2>聊天</h2>
<div class="container">
    <br />
    <div>在线:<span id="clientlist">&nbsp;</span></div>
    <div style="height:200px;margin-top:20px; padding:10px; border:solid 1px #ccc; overflow:auto;">
    <ul id="discussion">
    </ul>
    </div>
    <div>昵称: <input type="text" id="displayname" style="width:100px;" /> &nbsp;信息: <input type="text" id="message" style="width:200px;" />
    &nbsp;<input type="button" id="sendmessage" value="发送" /> <input type="button" id="getclients" value="获取列表" /></div>
</div>
@section scripts {
    <!--Script references. -->
    <!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
    <!--Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.0.0.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="~/signalr/hubs"></script>
    <!--SignalR script to update the chat page and send messages.--> 
    <script>
        $(function () {
            // Reference the auto-generated proxy for the hub.  
            var chat = $.connection.chatHub; //客户端代理,
            // Create a function that the hub can call back to display messages.
            chat.client.addNewMessageToPage = function (name, message) {
                // Add the message to the page. 
                $('#discussion').append('<li><strong>' + htmlEncode(name) 
                    + '</strong>: ' + htmlEncode(message) + '</li>');
            }; //服务器端会调用
            chat.client.listAll = function (list) {
                var html = '';
                for (i = 0; i < list.length; i++) {
                    html += list[i] + '&nbsp;';
                }
                $('#clientlist').html(html);
            }; //服务器端会调用
            // 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 () {
                    var dispname = $('#displayname').val();
                    var message = $('#message').val();
                    if (dispname == '') {
                        alert('请输入昵称');
                        return false;
                    }
                    if (message == '') {
                        alert('请输入信息');
                        return false;
                    }
                    // Call the Send method on the hub. 
                    chat.server.send(dispname, message );
                    // Clear text box and reset focus for next comment. 
                    $('#message').val('').focus();
                });
                $('#getclients').click(function () {
                    chat.server.list();
                });
            });
        });
        // This optional function html-encodes messages for display in the page.
        function htmlEncode(value) {
            var encodedValue = $('<div />').text(value).html();
            return encodedValue;
        }
    </script>
}

$.connection.chatHub 是个客户端代理,定义在 ~/signalr/hubs 脚本文件中,火狐浏览器,查看源码,可以看到这个文件的源码。

为了方便,我们可以在布局文件中加个菜单

<li>@Html.ActionLink("聊天", "Index", "Chat")</li>

至此,简单的聊天室完成了,点击运行,就可以在浏览器中查看效果,多开几个窗口,就可以互相聊天了。
代码下载 http://pan.baidu.com/s/1ePme7 (百度网盘 30M)

有时间实践一下SignalR的分组,就可以实现一对一聊天,多聊天室功能

posted @ 2013-11-11 13:15  码农V40  阅读(2517)  评论(4编辑  收藏  举报