一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - ASP.NET教程 - Asp.net SignalR快速入門(mén)

Asp.net SignalR快速入門(mén)

2020-01-02 13:55Learning hard ASP.NET教程

這篇文章主要介紹了Asp.net SignalR快速入門(mén),幫助大家可以快速的上手Asp.net SignalR,感興趣的小伙伴們可以參考一下

今天的專(zhuān)題就是讓大家可以快速的上手Asp.net SignalR。廢話(huà)不多說(shuō)了,下面正式進(jìn)入今天專(zhuān)題的內(nèi)容。

二、Asp.net SignalR 是個(gè)什么東東
   Asp.net SignalR是微軟為實(shí)現(xiàn)實(shí)時(shí)通信的一個(gè)類(lèi)庫(kù)。一般情況下,SignalR會(huì)使用JavaScript的長(zhǎng)輪詢(xún)(long polling)的方式來(lái)實(shí)現(xiàn)客戶(hù)端和服務(wù)器通信,隨著Html5中WebSockets出現(xiàn),SignalR也支持WebSockets通信。另外SignalR開(kāi)發(fā)的程序不僅僅限制于宿主在IIS中,也可以宿主在任何應(yīng)用程序,包括控制臺(tái),客戶(hù)端程序和Windows服務(wù)等,另外還支持Mono,這意味著它可以實(shí)現(xiàn)跨平臺(tái)部署在Linux環(huán)境下。

  SignalR內(nèi)部有兩類(lèi)對(duì)象:

Http持久連接(Persisten Connection)對(duì)象:用來(lái)解決長(zhǎng)時(shí)間連接的功能。還可以由客戶(hù)端主動(dòng)向服務(wù)器要求數(shù)據(jù),而服務(wù)器端不需要實(shí)現(xiàn)太多細(xì)節(jié),只需要處理PersistentConnection 內(nèi)所提供的五個(gè)事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
Hub(集線(xiàn)器)對(duì)象:用來(lái)解決實(shí)時(shí)(realtime)信息交換的功能,服務(wù)端可以利用URL來(lái)注冊(cè)一個(gè)或多個(gè)Hub,只要連接到這個(gè)Hub,就能與所有的客戶(hù)端共享發(fā)送到服務(wù)器上的信息,同時(shí)服務(wù)端可以調(diào)用客戶(hù)端的腳本。
  SignalR將整個(gè)信息的交換封裝起來(lái),客戶(hù)端和服務(wù)器都是使用JSON來(lái)溝通的,在服務(wù)端聲明的所有Hub信息,都會(huì)生成JavaScript輸出到客戶(hù)端,.NET則依賴(lài)Proxy來(lái)生成代理對(duì)象,而Proxy的內(nèi)部則是將JSON轉(zhuǎn)換成對(duì)象。

  客戶(hù)端和服務(wù)端的具體交互情況如下圖所示:

Asp.net SignalR快速入門(mén)

  從上面的介紹可以看出,SignalR既然是為實(shí)時(shí)而生的,這樣就決定了其使用場(chǎng)所。具體適用情景有如下幾點(diǎn):

1、聊天室,如在線(xiàn)客服系統(tǒng),IM系統(tǒng)等
2、股票價(jià)格實(shí)時(shí)更新
3、消息的推送服務(wù)
4、游戲中人物位置的實(shí)時(shí)推送
   目前,我所在公司在開(kāi)發(fā)的就是在線(xiàn)客服系統(tǒng)。

三、使用Asp.net SignalR在Web端實(shí)現(xiàn)廣播消息
   通過(guò)第二部分的介紹,相信大家對(duì)Asp.net SignalR有了一個(gè)初步的了解,接下來(lái)通過(guò)兩個(gè)例子來(lái)讓大家加深對(duì)SignalR運(yùn)行機(jī)制的理解。第一個(gè)例子就是在Web端如何使用SignalR來(lái)實(shí)現(xiàn)廣播消息。

使用Visual Studio 2013,創(chuàng)建一個(gè)MVC工程
通過(guò)Nuget安裝SignalR包。右鍵引用-》選擇管理Nuget程序包-》在出現(xiàn)的窗口中輸入SignalR來(lái)找到SignalR包進(jìn)行安裝。
安裝SignalR成功后,SignalR庫(kù)的腳本將被添加進(jìn)Scripts文件夾下。具體如下圖所示:

Asp.net SignalR快速入門(mén)

4. 向項(xiàng)目中添加一個(gè)SignalR集線(xiàn)器(v2)并命名為ServerHub。

Asp.net SignalR快速入門(mén)

  5. 將下面代碼填充到剛剛創(chuàng)建的ServerHub類(lèi)中。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
 
namespace SignalRQuickStart
{public class ServerHub : Hub
  {
    private static readonly char[] Constant =
    {
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
      'w', 'x', 'y', 'z',
      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
      'W', 'X', 'Y', 'Z'
    };
 
    /// <summary>
    /// 供客戶(hù)端調(diào)用的服務(wù)器端代碼
    /// </summary>
    /// <param name="message"></param>
    public void Send(string message)
    {
      var name = GenerateRandomName(4);
 
      // 調(diào)用所有客戶(hù)端的sendMessage方法
      Clients.All.sendMessage(name, message);
    }
 
    /// <summary>
    /// 產(chǎn)生隨機(jī)用戶(hù)名函數(shù)
    /// </summary>
    /// <param name="length">用戶(hù)名長(zhǎng)度</param>
    /// <returns></returns>
    public static string GenerateRandomName(int length)
    {
      var newRandom = new System.Text.StringBuilder(62);
      var rd = new Random();
      for (var i = 0; i < length; i++)
      {
        newRandom.Append(Constant[rd.Next(62)]);
      }
      return newRandom.ToString();
    }
  }
}

  6. 創(chuàng)建一個(gè)Startup類(lèi),如果開(kāi)始創(chuàng)建MVC項(xiàng)目的時(shí)候沒(méi)有更改身份驗(yàn)證的話(huà),這個(gè)類(lèi)會(huì)默認(rèn)添加的,如果已有就不需要重復(fù)添加了。按照如下代碼更新Startup類(lèi)。

  7. 在Home控制器中創(chuàng)建一個(gè)Home Action方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class HomeController : Controller
  {
    public ActionResult Index()
    {
      return View();
    }
 
    public ActionResult About()
    {
      ViewBag.Message = "Your application description page.";
 
      return View();
    }
 
    public ActionResult Contact()
    {
      ViewBag.Message = "Your contact page.";
 
      return View();
    }
 
    public ActionResult Chat()
    {
      return View();
    }
  }

  8. 在Views文件中Home文件夾中創(chuàng)建一個(gè)Chat視圖,視圖代碼如下所示:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@{
  ViewBag.Title = "聊天窗口";
}
 
<h2>Chat</h2>
 
<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>
 
@section scripts
{
  <!--引用SignalR庫(kù). -->
  <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
   <!--引用自動(dòng)生成的SignalR 集線(xiàn)器(Hub)腳本.在運(yùn)行的時(shí)候在瀏覽器的Source下可看到 -->
  <script src="~/signalr/hubs"></script>
  
  <script>
    $(function () {
      // 引用自動(dòng)生成的集線(xiàn)器代理
      var chat = $.connection.serverHub;
      // 定義服務(wù)器端調(diào)用的客戶(hù)端sendMessage來(lái)顯示新消息
      
      chat.client.sendMessage = function (name, message) {
        // 向頁(yè)面添加消息
        $('#discussion').append('<li><strong>' + htmlEncode(name)
          + '</strong>: ' + htmlEncode(message) + '</li>');
      };
      
      // 設(shè)置焦點(diǎn)到輸入框
      $('#message').focus();
      // 開(kāi)始連接服務(wù)器
      $.connection.hub.start().done(function () {
        $('#sendmessage').click(function () {
          // 調(diào)用服務(wù)器端集線(xiàn)器的Send方法
          chat.server.send($('#message').val());
          // 清空輸入框信息并獲取焦點(diǎn)
          $('#message').val('').focus();
        });
      });
    });
    
    // 為顯示的消息進(jìn)行Html編碼
    function htmlEncode(value) {
      var encodedValue = $('<div />').text(value).html();
      return encodedValue;
    }
  </script>
  }

  9. 修改App_Start文件夾內(nèi)的RoutConfig類(lèi),將Action方法默認(rèn)設(shè)置為Chat.

?
1
2
3
4
5
6
7
8
9
10
11
12
public class RouteConfig
  {
    public static void RegisterRoutes(RouteCollection routes)
    {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
      routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Chat", id = UrlParameter.Optional }
      );
    }
  }

  到此,我們的例子就實(shí)現(xiàn)完成了,接下來(lái)我們先來(lái)看看運(yùn)行效果,之后再來(lái)解釋到底SignalR是如何來(lái)完成廣播消息的。運(yùn)行的運(yùn)行結(jié)果如下。

Asp.net SignalR快速入門(mén)

  從運(yùn)行結(jié)果,你可以發(fā)現(xiàn),在任何一個(gè)窗口輸入信息并發(fā)送,所有客戶(hù)端將收到該消息。這樣的效果在實(shí)際應(yīng)用中很多,如QQ,一登錄QQ的時(shí)候都會(huì)推送騰訊廣告消息。

  看完了運(yùn)行結(jié)果,接下來(lái)我們來(lái)分析下代碼,進(jìn)而來(lái)剖析下SignalR到底是如何工作的。

  按照B/S模式來(lái)看,運(yùn)行程序的時(shí)候,Web頁(yè)面就與SignalR的服務(wù)建立了連接,具體的建立連接的代碼就是:$.connection.hub.start()。這句代碼的作用就是與SignalR服務(wù)建立連接,后面的done函數(shù)表明建立連接成功后為發(fā)送按鈕注冊(cè)了一個(gè)click事件,當(dāng)客戶(hù)端輸入內(nèi)容點(diǎn)擊發(fā)送按鈕后,該Click事件將會(huì)觸發(fā),觸發(fā)執(zhí)行的操作為: chat.server.send($('#message').val())。這句代碼表示調(diào)用服務(wù)端的send函數(shù),而服務(wù)端的Send韓式又是調(diào)用所有客戶(hù)端的sendMessage函數(shù),而客戶(hù)端中sendMessage函數(shù)就是將信息添加到對(duì)應(yīng)的消息列表中。這樣就實(shí)現(xiàn)了廣播消息的功能了。

  看到這里,有人是否會(huì)有疑問(wèn),前面的實(shí)現(xiàn)都只用到了集線(xiàn)器對(duì)象,而沒(méi)有用到持久連接對(duì)象。其實(shí)并不是如此,$.connection這句代碼就是使用持久連接對(duì)象,當(dāng)然你也可以在重新OnConnected方法來(lái)查看監(jiān)控客戶(hù)端的連接情況,更新的代碼如下所示:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class ServerHub : Hub
 {
   private static readonly char[] Constant =
   {
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
     'w', 'x', 'y', 'z',
     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
     'W', 'X', 'Y', 'Z'
   };
 
   /// <summary>
   /// 供客戶(hù)端調(diào)用的服務(wù)器端代碼
   /// </summary>
   /// <param name="message"></param>
   public void Send(string message)
   {
     var name = GenerateRandomName(4);
 
     // 調(diào)用所有客戶(hù)端的sendMessage方法
     Clients.All.sendMessage(name, message);
   }
 
   /// <summary>
   /// 客戶(hù)端連接的時(shí)候調(diào)用
   /// </summary>
   /// <returns></returns>
   public override Task OnConnected()
   {
     Trace.WriteLine("客戶(hù)端連接成功");
     return base.OnConnected();
   }
 
   /// <summary>
   /// 產(chǎn)生隨機(jī)用戶(hù)名函數(shù)
   /// </summary>
   /// <param name="length">用戶(hù)名長(zhǎng)度</param>
   /// <returns></returns>
   public static string GenerateRandomName(int length)
   {
     var newRandom = new System.Text.StringBuilder(62);
     var rd = new Random();
     for (var i = 0; i < length; i++)
     {
       newRandom.Append(Constant[rd.Next(62)]);
     }
     return newRandom.ToString();
   }
 }

  這樣在運(yùn)行頁(yè)面的時(shí)候,將在輸出窗口看到“客戶(hù)端連接成功”字樣。運(yùn)行效果如下圖所示:

Asp.net SignalR快速入門(mén)

  在第二部分介紹的時(shí)候說(shuō)道,在服務(wù)端聲明的所有Hub信息,都會(huì)生成JavaScript輸出到客戶(hù)端,為了驗(yàn)證這一點(diǎn),可以在Chrome中F12來(lái)查看源碼就明白了,具體如下圖所示:

Asp.net SignalR快速入門(mén)

 看到上圖,你也就明白了為什么Chat.cshtml頁(yè)面需要引入"signalr/hubs"腳本庫(kù)了吧。

?
1
2
3
4
<!--引用SignalR庫(kù). -->
  <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
   <!--引用自動(dòng)生成的SignalR 集線(xiàn)器(Hub)腳本.在運(yùn)行的時(shí)候在瀏覽器的Source下可看到 -->
  <script src="~/signalr/hubs"></script>

四、在桌面程序中如何使用Asp.net SignalR
   上面部分介紹了SignalR在Asp.net MVC 中的實(shí)現(xiàn),這部分將通過(guò)一個(gè)例子來(lái)看看SignalR在WPF或WinForm是如何使用的。其實(shí)這部分實(shí)現(xiàn)和Asp.net MVC中非常相似,主要不同在于,Asp.net MVC中的SignalR服務(wù)器寄宿在IIS中,而在WPF中應(yīng)用,我們把SignalR寄宿在WPF客戶(hù)端中。

下面讓我們看看SignalR服務(wù)端的實(shí)現(xiàn)。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/// <summary>
    /// 啟動(dòng)SignalR服務(wù),將SignalR服務(wù)寄宿在WPF程序中
    /// </summary>
    private void StartServer()
    {
      try
      {
        SignalR = WebApp.Start(ServerUri); // 啟動(dòng)SignalR服務(wù)
      }
      catch (TargetInvocationException)
      {
        WriteToConsole("一個(gè)服務(wù)已經(jīng)運(yùn)行在:" + ServerUri);
        // Dispatcher回調(diào)來(lái)設(shè)置UI控件狀態(tài)
        this.Dispatcher.Invoke(() => ButtonStart.IsEnabled = true);
        return;
      }
 
      this.Dispatcher.Invoke(() => ButtonStop.IsEnabled = true);
      WriteToConsole("服務(wù)已經(jīng)成功啟動(dòng),地址為:" + ServerUri);
    }
 
public class ChatHub : Hub
  {
    public void Send(string name, string message)
    {
      Clients.All.addMessage(name, message);
    }
 
    public override Task OnConnected()
    {
      //
      Application.Current.Dispatcher.Invoke(() =>
        ((MainWindow)Application.Current.MainWindow).WriteToConsole("客戶(hù)端連接,連接ID是: " + Context.ConnectionId));
 
      return base.OnConnected();
    }
 
    public override Task OnDisconnected(bool stopCalled)
    {
       Application.Current.Dispatcher.Invoke(() =>
        ((MainWindow)Application.Current.MainWindow).WriteToConsole("客戶(hù)端斷開(kāi)連接,連接ID是: " + Context.ConnectionId));
 
      return base.OnDisconnected(true);
    }
  }
 
 public class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      // 有關(guān)如何配置應(yīng)用程序的詳細(xì)信息,請(qǐng)?jiān)L問(wèn) http://go.microsoft.com/fwlink/?LinkID=316888
      // 允許CORS跨域
      //app.UseCors(CorsOptions.AllowAll);
      app.MapSignalR();
    }
  }

  通過(guò)上面的代碼,我們SignalR服務(wù)端的實(shí)現(xiàn)就完成了,其實(shí)現(xiàn)邏輯與Asp.net MVC的代碼類(lèi)似。

  接下來(lái),讓我們看看,WPF客戶(hù)端是如何連接和與服務(wù)器進(jìn)行通信的。具體客戶(hù)端的實(shí)現(xiàn)如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public IHubProxy HubProxy { get; set; }
   const string ServerUri = "http://localhost:8888/signalr";
   public HubConnection Connection { get; set; }
 
   public MainWindow()
   {
     InitializeComponent();
 
     // 窗口啟動(dòng)時(shí)開(kāi)始連接服務(wù)
     ConnectAsync();
   }
 
   /// <summary>
   /// 發(fā)送消息
   /// </summary>
   /// <param name="sender"></param>
   /// <param name="e"></param>
   private void ButtonSend_Click(object sender, RoutedEventArgs e)
   {
     // 通過(guò)代理來(lái)調(diào)用服務(wù)端的Send方法
     // 服務(wù)端Send方法再調(diào)用客戶(hù)端的AddMessage方法將消息輸出到消息框中
     HubProxy.Invoke("Send", GenerateRandomName(4), TextBoxMessage.Text.Trim());
 
     TextBoxMessage.Text = String.Empty;
     TextBoxMessage.Focus();
   }
 
   private async void ConnectAsync()
   {
     Connection = new HubConnection(ServerUri);
     Connection.Closed += Connection_Closed;
 
     // 創(chuàng)建一個(gè)集線(xiàn)器代理對(duì)象
     HubProxy = Connection.CreateHubProxy("ChatHub");
 
     // 供服務(wù)端調(diào)用,將消息輸出到消息列表框中
     HubProxy.On<string, string>("AddMessage", (name, message) =>
        this.Dispatcher.Invoke(() =>
         RichTextBoxConsole.AppendText(String.Format("{0}: {1}\r", name, message))
       ));
 
     try
     {
       await Connection.Start();
     }
     catch (HttpRequestException)
     {
       // 連接失敗
       return;
     }
 
     // 顯示聊天控件
     ChatPanel.Visibility = Visibility.Visible;
     ButtonSend.IsEnabled = true;
     TextBoxMessage.Focus();
     RichTextBoxConsole.AppendText("連上服務(wù):" + ServerUri + "\r");
   }

  上面的代碼也就是WPF客戶(hù)端實(shí)現(xiàn)的核心代碼,主要邏輯為,客戶(hù)端啟動(dòng)的時(shí)候就調(diào)用Connection.Start方法與服務(wù)器進(jìn)行連接。然后通過(guò)HubProxy代理類(lèi)來(lái)調(diào)用集線(xiàn)器中Send方法,而集線(xiàn)器中的Send方法又通過(guò)調(diào)用客戶(hù)端的addMessage方法將消息輸出到客戶(hù)端的消息框中進(jìn)行顯示,從而完成消息的推送過(guò)程。接下來(lái),讓我們看看其運(yùn)行效果:

Asp.net SignalR快速入門(mén)

   從上面的運(yùn)行效果看出,其效果和Asp.net MVC上的效果是一樣的。

五、總結(jié)
   到這里,本專(zhuān)題的所有內(nèi)容就結(jié)束了,這篇SignalR快速入門(mén)也是本人在學(xué)習(xí)SignalR過(guò)程中的一些心得體會(huì),希望可以幫助一些剛接觸SignalR的朋友快速入門(mén)。本篇主要實(shí)現(xiàn)了SignalR的廣播消息的功能,可以實(shí)現(xiàn)手機(jī)端消息推送的功能,接下來(lái)一篇將介紹如何使用SignalR實(shí)現(xiàn)一對(duì)一的聊天。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产欧美一区二区三区免费 | 男人天堂新 | 免费日本在线 | 欧美kkk4444在线观看 | chinesezoozvideos| 色多多在线观看视频 | 成年人在线免费观看视频网站 | 日韩黄色影视 | 色先锋 影音先锋a 资源站 | 亚洲午夜久久久 | 小小水蜜桃视频高清在线观看免费 | 图片专区小说专区卡通动漫 | 人禽l交视频在线播放 视频 | a免费看 | 欧美一级免费看 | 欧美精品久久久亚洲 | 欧美女孩videos| 成人资源影音先锋久久资源网 | 国产精品热久久毛片 | 羲义嫁密着中出交尾gvg794 | 天美影视文化传媒mv免费 | porono日本人xxx| 色cccwww| 538免费精品视频搬运工 | 男人天堂色男人 | 亚洲国产成人精品激情 | 国产四虎 | 999精品视频在线观看热6 | 国产欧美视频高清va在线观看 | 亚洲激情综合 | 亚洲成片在线看 | 精品国产一级毛片大全 | a毛片免费观看完整 | 窝窝影院午夜色在线视频 | 精品国产视频 | 69日本人xxxxxxxx色| 欧美一级高清片免费一级 | 18hdxxxx中国 | 91青青国产在线观看免费 | mm131亚洲精品久久 | 日韩日韩日韩手机看片自拍 |