SignalR快速入門 ~ 仿QQ即時聊天,消息推送,單聊,羣聊,多羣公聊(基礎=》提高)

 SignalR快速入門 ~ 仿QQ即時聊天,消息推送,單聊,羣聊,多羣公聊(基礎=》提高,5個Demo貫徹全篇,感興趣的玩纔是真的學)javascript

官方demo:http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalrcss

源碼http://pan.baidu.com/s/1dETGYGThtml

應用情景之一:前端

 

 

沒太多連續的時間來研究SignalR,因此我把這篇文章分了三個階段:java

第一個階段,簡單使用,熟悉並認識SignalRjquery

第二個階段,實現上圖的單聊效果web

第三個階段,實現相似QQ羣發的功能瀏覽器

擴展階段,若是有時間,逆天會再開一篇,封裝一個LoTSignalR,看過逆天封裝的人都知道,絕對簡單又輕量級服務器

好比LoTQQ,如今已經不少人在用了,後期會添加新功能,敬請期待~~架構

++++++++++++++++++ 我是華麗的分割線 +++++++++++++++++++++

步入正軌:

第一個階段:

1.什麼是ASP.NET SignalR?

ASP .NET SignalR是一個 ASP .NET 下的類庫,能夠在ASP .NET 的Web項目中實現實時通訊。什麼是實時通訊的Web呢?就是讓客戶端(Web頁面)和服務器端能夠互相通知消息及調用方法,固然這是實時操做的。

WebSockets是Html5提供的新的API,能夠在Web網頁與服務器端間創建Socket鏈接,當WebSockets可用時(即瀏覽器支持Html5)SignalR使用WebSockets,當不支持時SignalR將使用其它技術來保證達到相同效果。

SignalR固然也提供了很是簡單易用的高階API,使服務器端能夠單個或批量調用客戶端上的JavaScript函數,而且很是 方便地進行鏈接管理,例如客戶端鏈接到服務器端,或斷開鏈接,客戶端分組,以及客戶端受權,使用SignalR都很是 容易實現。

2.可使用ASP.NET SingalR作什麼?
SignalR 將與客戶端進行實時通訊帶給了ASP .NET 。固然這樣既好用,並且也有足夠的擴展性。之前用戶須要刷新頁面或使用Ajax輪詢才能實現的實時顯示數據,如今只要使用SignalR,就能夠簡單實現了。

最重要的是您無需從新創建項目,使用現有ASP .NET項目便可無縫使用SignalR。

網上某架構圖:

上面亂七八糟的估計不少人懶得看,好吧,你能夠這樣理解:

使用了SignalR就可讓客戶端經過SignalR代理直接調用服務端的方法,讓服務端經過SignalR直接調用客戶端的方法

下面咱們來實例演示一下,先演示一下不用IIS的狀況:

新建一個控制檯項目,引入 signalR Self Host (能夠思考一下爲何會用NuGet包,他到底好在哪?O(∩_∩)O~不清楚等項目演示完你應該就知道了

這是他的依賴項

安裝一下Owin.Cors

依賴項:

新增一個Owin的Startup類,相似於咱們傳統項目的Global文件

註冊一下signalR中間組件(學過mvc的能夠變相的理解爲註冊路由之類的)

在main方法中綁定端口(不必定是8080,好比我demo中就用的其餘端口)

建立一個「SignalR集線器」(控制檯這邊由於沒有集線器因此只能本身建類)

建了一個DntHub,定義了一個服務器端的方法,叫ServiceSend(一會會用到)

轉到定義,看看Hub類(好東西啊,還有分組啥的,下面會講)

運行一下,若是出錯請參考個人這篇文章:http://www.cnblogs.com/dunitian/p/5232229.html

先看看共引用多少dll(和MVC之類的比起是否是簡潔不少?一會演示好處在哪)最小引用

建立一個web的Client,引用一下 SignalR的js包,其實你會發現就是多了幾個js包並無引用任何dll(必須的,否則豈不是太臃腫?)

前端的調用步驟:

    <!--
    總結一下:
    1.先引入jq包,再引入signalR的js包,再引入signalR動態生成的hubs
    2.設置signalR的hubs url地址:$.connection.hub.url =xxx
    3.聲明一個代理對象來引用集線器:var chat = $.connection.dntHub;
    4.建立一個客戶端方法:chat.client.xxxx=function(){}
    5.啓動並調用服務端方法:
        $.connection.hub.start().done(function(){
            chat.server.xxx()
        });
    -->

代碼貼起:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>簡單聊天程序</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>
    <script src="Scripts/jquery-1.8.3.min.js"></script>
    <script src="Scripts/jquery.signalR-2.2.0.js"></script>
    <!--動態生成的-->
    <script src="http://localhost:5438/signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {
            //日記記錄
            $.connection.hub.logging = true;

            //設置hubs的url
            $.connection.hub.url = "http://localhost:5438/signalr";

            // 聲明一個代理來引用該集線器。
            var chat = $.connection.dntHub;

            // 建立一個方法供服務端調用
            chat.client.addMessage = function (name, message) {
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                $('#discussion').append('<li><strong>' + encodedName + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
            };
            $('#displayname').val('路人');

            // 啓動 connection
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    //調用服務器端方法
                    chat.server.serviceSend($('#displayname').val(), $('#message').val());
                });
            });
        });
    </script>
    <!--
    總結一下:
    1.先引入jq包,再引入signalR的js包,再引入signalR動態生成的hubs
    2.設置signalR的hubs url地址:$.connection.hub.url =xxx
    3.聲明一個代理對象來引用集線器:var chat = $.connection.dntHub;
    4.建立一個客戶端方法:chat.client.xxxx=function(){}
    5.啓動並調用服務端方法:
        $.connection.hub.start().done(function(){
            chat.server.xxx()
        });
    -->
</body>
</html>
View Code

若是要調試的話,保證服務端先運行,調試小技巧:

下面說一下上面的好處:

webclient我就單獨拿出來了(一個js包,一個index.html),控制檯的程序我也單獨拿出來了,下面先運行一下服務端,再打開index.html

再次驗證最上面說的,端口不固定

第二個階段:

 QQ聊天案例,先講一種常規的方法,下面會講一種簡單方法

先看看gif效果圖把

定義一個BaseHub類,裏面用 qqModeList來臨時存放數據(用戶數據)

QQModel,目前就用到兩個屬性,其餘的能夠本身擴展

定義了一個上線方法,一會每一個客戶端都會調用(原本是準備用OnConnected的,沒辦法他沒參數。。。並且這個時候,qq暱稱尚未產生,因而我取其次的方案)

定義一個發消息的方法

下面就是前端的東西了,註釋很詳細,不清楚能夠直接留言,我沒高興深度封裝,主要就是簡單演示一下

代碼貼上:

客戶端-逆天

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>仿QQ聊天--我是逆天</title>
    <link href="Style/MyQQ.css" rel="stylesheet" />
</head>
<body>
    <div><input id="inputMsg" /><input id="btn" type="button" value="發消息" /></div><br /><br />
    <div id="main"></div>

    <script src="Scripts/jquery-2.2.1.min.js"></script>
    <script src="Scripts/jquery.signalR-2.2.0.min.js"></script>
    <script src="http://localhost:5438/signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {
            var leftHtml = [
                '<div class="sender">',
                '<div><img src="http://img.jfdown.com/jfdown/201403/ygald3wajct.jpg"></div>',
                '<div><div class="left_triangle"></div>',
                '<span>{msg}</span></div></div>'
            ].join('');

            var rightHtml = [
                '<div class="receiver">',
                '<div><img src="http://tb.himg.baidu.com/sys/portrait/item/306c9328?t=1397975854"></div>',
                '<div><div class="right_triangle"></div>',
                '<span>{msg}</span></div></div>'
            ].join('');

            //設置hubs的url
            $.connection.hub.url = 'http://localhost:5438/signalR';
            // 聲明一個代理
            var qqProxy = $.connection.qQHub;
            // 建立一個方法供服務端調用
            qqProxy.client.sendMsg = function (msg) {
                $('#main').append(leftHtml.replace('{msg}', msg));
            }
            // 啓動 connection
            $.connection.hub.start().done(function () {
                qqProxy.server.online('逆天');//QQ暱稱
                $('#btn').click(function () {
                    //獲取輸入
                    var qqmsg = $('#inputMsg').val();
                    //給逆天發消息
                    qqProxy.server.serviceSend('妹子', qqmsg);
                    $('#main').append(rightHtml.replace('{msg}', qqmsg));
                });
            });
        });
    </script>
</body>
</html>
View Code

客戶端-美女

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>仿QQ聊天--我是美女</title>
    <link href="Style/MyQQ.css" rel="stylesheet" />
</head>
<body>
    <div><input id="inputMsg" /><input id="btn" type="button" value="發消息" /></div><br /><br />
    <div id="main"></div>


    <script src="Scripts/jquery-2.2.1.min.js"></script>
    <script src="Scripts/jquery.signalR-2.2.0.min.js"></script>
    <script src="http://localhost:5438/signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {
            var rightHtml = [
                '<div class="sender">',
                '<div><img src="http://img.jfdown.com/jfdown/201403/ygald3wajct.jpg"></div>',
                '<div><div class="left_triangle"></div>',
                '<span>{msg}</span></div></div>'
            ].join('');

            var leftHtml = [
                '<div class="receiver">',
                '<div><img src="http://tb.himg.baidu.com/sys/portrait/item/306c9328?t=1397975854"></div>',
                '<div><div class="right_triangle"></div>',
                '<span>{msg}</span></div></div>'
            ].join('');

            //設置hubs的url
            $.connection.hub.url = 'http://localhost:5438/signalR';
            // 聲明一個代理
            var qqProxy = $.connection.qQHub;
            // 建立一個方法供服務端調用
            qqProxy.client.sendMsg = function (msg) {
                $('#main').append(leftHtml.replace('{msg}',  msg));
            }
            // 啓動 connection
            $.connection.hub.start().done(function () {
                qqProxy.server.online('妹子');//QQ暱稱
                $('#btn').click(function () {
                    //獲取輸入
                    var qqmsg = $('#inputMsg').val();
                    //給逆天發消息
                    qqProxy.server.serviceSend('逆天', qqmsg);
                    $('#main').append(rightHtml.replace('{msg}', qqmsg));
                });
            });
        });
    </script>
</body>
</html>
View Code

 

第三階段

 羣發

咱們先接着昨天的QQ聊天來講

此次用一個簡單的方法搞定

一個鍵值對集合存放ConnectionId和GroupName

每一個客戶端鏈接的時候會加入一個組

 斷開的時候退出組
 發消息

前端也進行了優化。ok,signalR第三個demo誕生,比昨天簡單多了

 

下面能夠說說相似於QQ羣的羣發消息了

 

這個是逆天的自學筆記:

相關文章
相關標籤/搜索