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


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

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

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

應用情景之一:

 

 

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

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

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

第三個階段,實現類似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群的群發消息了

 

這個是逆天的自學筆記:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM