一步一步學習SignalR進行實時通信_3_通過CORS解決跨域


一步一步學習SignalR進行實時通信_3_通過CORS解決跨域

標簽(空格分隔): SignalR


前言

這周工作比較忙,一直沒有時間學習SignalR,大致希望一周能寫一篇關於SignalR的文章。上一篇用Persistent Connections方式實現了個簡單的在線聊天功能,這次我們繼續深入學習。

關於start()的補充

在上一篇文章里前台的html頁面我們通過幾句javascript創建了一個,代碼如下,也可以下載上次的源碼。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>persistent connections</title>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
</head>
<body>
    <h1>Echo service</h1>
    <div>
        <input type="text" id="text" />
        <button id="send">Send</button>
    </div>
    <script>
        $(function () {
            var connection = $.connection("/echo");
            connection.logging = true;
            connection.received(function (data) {
                $("body").append(data + "<br />");
            });
            connection.error(function (err) {
                alert("存在一個錯誤. \n" +
                            "Error: " + err.message);
            });
            connection.start().done(function () {
                $("#send").click(function () {
                    connection.send($("#text").val());
                    $("#text").val("").focus();
                });
            });
        });
    </script>
</body>
</html>

這里需要做些說明:通過代碼var connection = $.connection("/echo");
我們創建了一個連接,通過connection.start().done()來開啟連接並在連接完成時處理我們需要處理的事件。
如果你將以下代碼

connection.start().done(function () {
    connection.send('Hi');
});

分成2部分寫,如:

connection.start();
connection.send('Hi');

那么你必須注意:
雖然你在connection.send()之前調用了connection.start()開啟了連接,但是connection.start()是一個__異步__方法,意味着有可能你在調用connection.send()時connection並未開啟,那么項目將會報錯。
正確方法如之前代碼所示,再加上一段開啟失敗的代碼:

var connection = $.connection("/echo");
connection.start(function() {
    // 連接開啟成功才會進入這里
    connection.send("Hi");
}).fail(function() {
    //連接開啟失敗則進入這里
    alert("服務開啟失敗");
});

跨域解決方案

上篇文章里有同學問到跨域的問題,那么在接下來的時間我將會帶着大家一起學習。
在SignalR解決跨域,有兩種方式:第一種是JSONP,第二種是CORS。

JSONP

如果你的服務必須要支持老版本的瀏覽器,那么JSONP是唯一選擇,否則處於安全的考慮這並不被推薦,具體什么安全因素我並不知曉(有同學知道的話可以說明下),基於快速學習的情況下,我們無需糾纏於此。服務器默認會禁用此功能,我們可以通過初始化時提供一個ConnectionConfiguration對象並設置EnableJSONP屬性為true來激活此功能。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new ConnectionConfiguration()
        {
            EnableJSONP = true
        };
        app.MapSignalR<EchoConnection>("/echo", config);
    }
}

我想這幾句代碼應該很好理解,我們在前面提到過MapSignalR<TConnection>()有許多重載方法,這是另一個重載方法通過提供一個ConnectionConfiguration對象進行相關配置。

CORS

CORS是一個獨立的框架,它可以很方便的解決跨域問題,通過Nuget安裝
安裝命令:Install-Package microsoft.owin.cors
CORS是通過Owin實現的,所以我們需要在項目啟動時對他進行一些配置,和做SignalR映射一樣實在Startup中進行配置。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        //app.MapSignalR<EchoConnection>("/echo");
        app.Map("/echo", 
            map => {
                       map.UseCors(CorsOptions.AllowAll);
                       map.RunSignalR<EchoConnection>();
                   }
        );
    }
}

代碼應該也不難,這次我們通過app.Map()進行映射,第一個參數是映射的地址,第二個參數是一個lambda表達式,通過UseCors(CorsOptions.AllowAll)允許允許跨域。

CORS跨域演示

JSONP我不做演示了有興趣的可以自己嘗試下,接下來我這里做一個通過CORS來進行跨域聊天。首先我講上次的項目復制一份,省得再重新打代碼,並將__復制__出來的項目名稱由__SignalR_1__改為__SignalR_2_CORS__。
項目目錄如下圖所示:

省得麻煩,我把SignalR_1部署在IIS上面,這就充當了 一個遠程的SignalR服務。

部署成功后,如圖所示:

此時我們講SignalR_2_CORS項目稍作修改

  1. 將Startup中的映射刪去,此時SignalR_2_CORS已不做SignalR服務器了,只做客戶端來連接SignalR_1提供的服務
  2. 將echo中的var connection = $.connection("/echo");改為
    var connection = $.connection("http://127.0.0.1:8083/echo");

    然后運行SignalR_2_CORS中的echo頁面,結果如圖所示:

    出現了一個錯誤,這個錯誤提示是我們自己寫的

    因為我們的__SignalR_1__並沒有允許跨域連接,那么在__SignalR_2_CORS__中當然無法連接,接下來我們在項目一中允許跨域連接。

    重新編譯項目一后再刷新下__SignalR_1__的_echo.html_頁面,注意我們這個頁面地址

    然后刷新下__SignalR_2_CORS__的頁面,注意這個地址

    連接成功,沒有報錯了,發送個消息試試看(●ˇ∀ˇ●)

結束語

這里通過CORS實現了SignalR的跨域問題,跨域如此簡單趕快試試吧 。

注意:在通過Nuget安裝CORS包時,我這邊提示了Unable to find package 'Microsoft.AspNet.Cors'我已經翻牆了,所以這個應該不是需要翻牆才能下載,但是在Nuget頁面中搜索確實有這個包,具體什么原因引起的我也不清楚,如果你有碰到這個問題請下載解壓並添加引用即可,由於Microsoft.AspNet.Cors依賴於Microsoft.AspNet.Cors,所以里面的2個包都要添加引用

源碼下載
本文發布至作業部落

參考文獻

SignalR Programming in Microsoft ASP.NET pdf 下載


免責聲明!

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



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