經過前面幾篇文章javascript
史上最全面的SignalR系列教程-一、認識SignalRcss
史上最全面的SignalR系列教程-二、SignalR 實現推送功能-永久鏈接類實現方式html
史上最全面的SignalR系列教程-三、SignalR 實現推送功能-集線器類實現方式java
RDIFramework.NET敏捷開發框架經過SignalR技術整合即時通信(IM)jquery
咱們對SignalR的概念以及SignalR的最主要的兩類通訊模型(Persistent Connections與Hubs)進行了詳細的對比講解,也作了案例展現。本篇將爲你們介紹.NET特有的Self-Host自託管的應用,即以Self-Host自託管爲宿主加載SignalR服務。git
宿主一詞咱們不會陌生,它能夠看做是一個基礎設施,它爲一些服務和功能提供最底層的支持,如你的web應用程序能夠運行在iis或者apache上,而這兩個東西就是web應用程序的宿主,而今天說的自主宿主SelfHost它能夠本身去監聽本身的服務,如你能夠把一個web應用程序宿主到一個console控制檯程序上,或者把一個webApi宿主到一個console或者windowService上,這都是能夠的。github
Self-Host的介紹咱們能夠參考msdn官方事例https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/self-host 這是一個wcf的事例。web
SignalR經常依託於ASP.NET應用程序運行於IIS中,但它還能夠自我託管(好比做爲console winform、Windows service),只要咱們使用self-host庫就能夠了。該庫向全部的SignalR 2庫同樣,構建於OWIN (Open Web Interface for .NET)。OWIN定義了一個在.NET web 服務端和web 應用程序的抽象。OWIN解耦了從服務端來的web 應用程序,這使得OWIN對於子託管web應用程序於本身的進程中得以表現得很完美。apache
有的小夥伴可能就要問了,爲何必定要使用這種方式來託管呢?基於IIS的方式不是更簡單嗎?不託管於IIS的緣由主要有如下方面的考慮:跨域
本篇主要講解如下內容:
爲了更簡單的說明self-host託管的方式,咱們用控制檯應用程序來作演示。固然咱們也能夠自託管到Windows服務中去,若是你更但願託管到Windows服務,能夠參考Self-Hosting SignalR in a Windows Service
在上一項目的基礎上,咱們新建一個名爲:SignalRSelfHost的控制檯應用程序,以下所所示:
要使用Selft-Host宿主SignalR,必須引用Microsoft.AspNet.SignalR.SelfHost包。咱們在程序包管理控制檯輸入如下命令安裝SelfHost包。
Install-Package Microsoft.AspNet.SignalR.SelfHost
要想支持跨域訪問,還須要安裝
Install-Package Microsoft.Owin.Cors
若是用命令的方式安裝失敗,咱們能夠用NuGet的方式安裝,以下圖所示。
編寫代碼以下:
using Microsoft.AspNet.SignalR; using Microsoft.Owin.Cors; using Microsoft.Owin.Hosting; using Owin; using System; namespace SignalRSelfHost { class Program { static void Main(string[] args) { // This will *ONLY* bind to localhost, if you want to bind to all addresses // use http://*:8080 to bind to all addresses. // See http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx // for more information. string url = "http://localhost:8077"; using (WebApp.Start(url)) { Console.WriteLine("SignalR Server running on {0}", url); Console.ReadLine(); } } } /// <summary> /// 該類含有SignalR服務端的配置(該教程使用的惟一的配置是用來調用UseCors), /// MapSignalR爲全部形式的Hub對象建立了路由規則 /// </summary> class Startup { public void Configuration(IAppBuilder app) { app.UseCors(CorsOptions.AllowAll); app.MapSignalR(); } } /// <summary> /// SignalR的Hub 類是程序要提供給客戶端的 /// 該類就一個方法,Send:客戶端能夠用來發送消息給其餘客戶端 /// </summary> public class MyHub : Hub { //服務端的方法,客戶端能夠去調用 public void Send(string name, string message) { //調用客戶端的方法addMessage(string s1,string s2); Clients.All.addMessage(name, message); } } }
代碼說明:
Program:包含程序的主方法。在這個方法中,類型爲Startup的web應用程序啓動於指定的URL (http://localhost:8077)。 若是須要更加安全一點,能夠支持SSL,請去這裏看看How to: Configure a Port with an SSL Certificate
Startup: 該類含有SignalR服務端的配置(該教程使用的惟一的配置是用來調用UseCors), MapSignalR爲全部形式的Hub對象建立了路由規則。
MyHub:SignalR的Hub 類是程序要提供給客戶端的。 該類就一個方法:Send, 客戶端能夠用來發送消息給其餘客戶端。
編譯運行SignalR控制檯服務端以下。
能夠看到咱們的控制檯服務端已經成功啓動起來了。
代碼以下:
<!DOCTYPE html> <html> <head> <title>SignalRSelfHostJSClient Chat</title> <style type="text/css"> .container { background-color: #a1c6ec; border: thick solid #e62fc7; padding: 20px; margin: 20px; } </style> </head> <body> <div class="container"> <input type="text" id="message" style="width:350px;" placeholder="請輸入消息內容..."/> <input type="button" id="sendmessage" value="發送" /> <input type="hidden" id="displayname" /> <ul id="discussion"></ul> </div> <!--Script references. --> <!--Reference the jQuery library. --> <script src="Scripts/jquery-1.6.4.min.js"></script> <!--Reference the SignalR library. --> <script src="Scripts/jquery.signalR-2.4.1.min.js"></script> <!--Reference the autogenerated SignalR hub script. --> <script src="http://localhost:8077/signalr/hubs"></script> <!--Add script to update the page and send messages.--> <script type="text/javascript"> $(function () { //Set the hubs URL for the connection $.connection.hub.url = "http://localhost:8077/signalr"; // Declare a proxy to reference the hub. var chat = $.connection.myHub; // Create a function that the hub can call to broadcast messages. chat.client.addMessage = function (name, message) { // Html encode display name and message. var encodedName = $('<div />').text(name).html(); var encodedMsg = $('<div />').text(message).html(); // Add the message to the page. $('#discussion').prepend('<li><strong>' + encodedName + '</strong>: ' + encodedMsg + '</li>'); }; // 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 () { // Call the Send method on the hub. chat.server.send($('#displayname').val(), $('#message').val()); // Clear text box and reset focus for next comment. $('#message').val('').focus(); }); }); }); </script> </body> </html>
先運行SignalRSelfHost控制檯服務端後,再運行兩個咱們的測試客戶端,分別輸入不一樣的用戶名,試試聊天的效果,以下圖所示。
編寫界面代碼以下:
using Microsoft.AspNet.SignalR.Client; using System; using System.Configuration; using System.Windows.Forms; namespace SignalRSelfHostWinFormClient { /// <summary> /// SignalRSelfHost WinForm測試客戶端 /// 用於接收消息(需配合SignalRSelfHostJSClient項目使用) /// </summary> public partial class SignalRSelfHostWinFormClientTest : Form { //定義代理,廣播服務鏈接相關 private static IHubProxy HubProxy { get; set; } private static readonly string ServerUrl = ConfigurationManager.AppSettings["SignalRServer"]; //定義一個鏈接對象 public static HubConnection Connection { get; set; } public SignalRSelfHostWinFormClientTest() { CheckForIllegalCrossThreadCalls = false; InitializeComponent(); } private void SignalRSelfHostWinFormClientTest_Load(object sender, EventArgs e) { Connection = new HubConnection(ServerUrl); Connection.Closed += Connection_Closed; HubProxy = Connection.CreateHubProxy("MyHub"); HubProxy.On<string, string>("addMessage", RecvMsg);//接收實時信息 Connection.Start().ContinueWith(task => { if (!task.IsFaulted) { msgContent.AppendText(string.Format("與Signal服務器鏈接成功,服務器地址:{0}\r\n",ServerUrl)); } else { msgContent.AppendText("與服務器鏈接失敗,請確認服務器是否開啓。\r\n"); } }).Wait(); } private void Connection_Closed() { msgContent.AppendText("鏈接關閉...\r\n"); } private void RecvMsg(string name, string message) { msgContent.AppendText(string.Format("接收時間:{0},發送人:{1},消息內容:{2},\r\n", DateTime.Now, name, message)); } } }
經過以上的詳細講解,咱們已經很是清楚的瞭解瞭如何經過SignalR打通各終端以實現相互溝通的通訊。例子雖然比較簡潔,但徹底能夠以此爲基礎,擴展更復雜的業務應用。
實例源碼能夠移步github下載,地址:https://github.com/yonghu86/SignalRTestProj
一路走來數個年頭,感謝RDIFramework.NET框架的支持者與使用者,你們能夠經過下面的地址瞭解詳情。
RDIFramework.NET官方網站:http://www.rdiframework.net/
RDIFramework.NET官方博客:http://blog.rdiframework.net/
同時須要說明的,之後的全部技術文章以官方網站爲準,歡迎你們收藏!
RDIFramework.NET框架由海南國思軟件科技有限公司專業團隊長期打造、一直在更新、一直在升級,請放心使用!
歡迎關注RDIFramework.net框架官方公衆微信(微信號:guosisoft),及時瞭解最新動態。
掃描二維碼當即關注