集線器Hub類
使用持久連接類去開發是有些困難的,因為基於事件的開發方式,我們可以進行操作的地方也僅僅只是OnReceived事件內,這有些像websocket的方式。我們迫切的需要一種更人性化,更為適用的開發方式。
集線器就是我們想要的,集線器是對持久連接類再一次的進行封裝,集線器類都繼承自Hub,集線器類可以讓我們使用RPC的方式進行交互。
創建一個集線器類也是非常簡單的
這時我們需要對Startup類進行一些改造了,這更為簡單只需要一行代碼就可以實現
app.MapSignalR();
到源碼可以看到,它實際上給了我們一個默認的path,如果不想要的話也可以自定義path,這都是很簡單的
app.MapSignalR("/simpleHub", new HubConfiguration());
現在創建了一個HubDemo的集線器類,代碼如下,HelloService是服務器的方法而helloClient是客戶端的方法
public class HubDemo : Hub { public void HelloService() { Clients.All.helloClient(); } }
到了前端,除了要引用jq和signalR之外還需要引用一下我們的集線器,可以看到這是有一定規律的 /simpleHhub 是MapSignalR的Path,后面是/js。這是什么意思呢?
在應用程序運行后,HubDemo這個類會代理成js,路徑就在simpleHub/js 。可以運行看一下
<script src="/simpleHub/js"></script>
這個js就是輔助我們進行RPC方式調用的一個核心成員,有興趣的同學可以研究一下生成的js
下面我們從連接中拿到hubDemo這個集線器類,然后定義客戶端的 helloClient方法。因為后面我們的服務器會調用這個函數。
然后我們打開連接,連接完成后調用服務器的 helloService方法,還記得在helloService函數里調用了客戶端的helloClient函數。所以運行起來應該是會看到打印的內容
<script type="text/javascript"> let hubDemo = $.connection.hubDemo; hubDemo.client.helloClient = function () { console.log("收到服務器的問候"); } $.connection.hub.start().done(function () { hubDemo.server.helloService(); }); </script>
現在看起來是很好用,但是也會造成困擾,因為代理生成的js只會在應用程序啟動后生成,在之前是沒有這個js文件的。也是就我們在開發的時候引入的只是一個虛擬的目錄文件,這會帶來什么問題呢,會導致我們的IDE沒有智能的提示,像$.connection.hubDemo這種東西是點不出來的。還會有更大的困擾,每次修改hub類后還要再把項目運行起來才可以,按照編程習慣應該是生成項目就已經OK才對,這一系列問題都需要我們換一種方式
<script src="/simpleHub/js"></script>
所幸在nuget上有一個叫Microsoft.AspNet.SignalR.Utils的包,我們可以把它下載下來,打開可以看到它是一個.exe的可執行文件。這時候就需要配置我們的Visual Studio一起協同工作了
在項目上右鍵屬性,找到生成事件,然后編輯后期生成事件
語法是 {signalr.exe的地址} ghp /path:{項目bin的地址} /o:{js文件輸出的地址}
下面是生成到項目下的Scripts文件夾下文件名為 hubDemo.js
$(SolutionDir)\packages\Microsoft.AspNet.SignalR.Utils.2.2.1\tools\signalr.exe ghp /path:$(TargetDir) /o:$(ProjectDir)\Scripts\hubDemo.js
這個時候生成項目就可以看到文件了,再把它引入到我們的項目中,那自然是一點問題也沒有