首頁 後端開發 C#.Net教程 SignalR Self Host多端訊息推播服務實例(三)

SignalR Self Host多端訊息推播服務實例(三)

Jul 02, 2017 pm 01:19 PM
host self signalr

這篇文章主要為大家詳細介紹了SignalR Self Host+MVC等多端訊息推播服務,具有一定的參考價值,有興趣的夥伴們可以參考一下

一、概述

因為專案需要,最近公司專案裡有個模組功能,需要使用到即時取得審核通知;原本的設計方案是使用ajax對伺服器進行定時輪詢查詢 ,剛開始資料量和使用量不大的時候還好,後來使用量的增加和系統中各種業務的複雜度增加,伺服器的壓力也越來越大,於是我想使用訊息推送的方式替換掉ajax輪詢查詢,當有審核提交時,呼叫推送方法,將訊息推送到下一審批人那,這樣就減低了伺服器的壓力。

Signal 是微軟支援的一個運行在.NET平台上的 html websocket 框架。它出現的主要目的是實現伺服器主動推送訊息到客戶端頁面,這樣客戶端就不必重新發送請求或使用輪詢技術來獲取訊息。而且SignalR的相容性也是很強大的,這裡不在多言。既然選擇了SignalR,那就開始做吧!

我的想法是將SignalR做成一個自託管的服務,和我們的b/s專案分離出來,這樣的好處是,1、推送服務不依賴iis,就算iis掛了,我們的推送服務還可以正常運作;2、我們可以多平台呼叫這個推送服務,多個專案都可以同時使用;

二、建立服務端

廢話不多說了,我也是第一次寫博客,介紹完業務場景和構思,我們就開始擼碼吧。

1、用VS建立一個名為"SignalRProject" 的解決方案;

2、在SignalRProject解決方案下新建一個名為Server的控制台

3、在程式包管理器控制台,輸入如下指令


Install-Package Microsoft.AspNet.SignalR.SelfHost
登入後複製

4、輸入如下指令:


Install-Package Microsoft.Owin.Cors
登入後複製

#5、在Server控制台中新增UserInfo類,程式碼如下


using System; 
 
namespace Server 
{ 
 public class UserInfo 
 { 
  public string ConnectionId { get; set; } 
  public string UserName { get; set; } 
  public DateTime LastLoginTime { get; set; } 
 } 
}
登入後複製

6、在Server控制台中新增ChatHub類,程式碼如下


##

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Server
{
 [HubName("IMHub")]
 public class ChatHub : Hub
 {
  // 静态属性
  public static List<UserInfo> OnlineUsers = new List<UserInfo>(); // 在线用户列表

  /// <summary>
  /// 登录连线
  /// </summary>
  /// <param name="userId">用户Id</param>
  /// <param name="userName">用户名</param>
  public void Register(string userName)
  {
   var connnectId = Context.ConnectionId;

   if (OnlineUsers.Count(x => x.ConnectionId == connnectId) == 0)
   {
    if (OnlineUsers.Any(x => x.UserName == userName))
    {
     var items = OnlineUsers.Where(x => x.UserName == userName).ToList();
     foreach (var item in items)
     {
      Clients.AllExcept(connnectId).onUserDisconnected(item.ConnectionId, item.UserName);
     }
     OnlineUsers.RemoveAll(x => x.UserName == userName);
    }

    //添加在线人员
    OnlineUsers.Add(new UserInfo
    {
     ConnectionId = connnectId,
     UserName = userName,
     LastLoginTime = DateTime.Now
    });
   }

   // 所有客户端同步在线用户
   Clients.All.onConnected(connnectId, userName, OnlineUsers);
  }

  /// <summary>
  /// 发送私聊
  /// </summary>
  /// <param name="toUserId">接收方用户连接ID</param>
  /// <param name="message">内容</param>
  public void SendPrivateMessage(string toUserName, string message)
  {
   var fromConnectionId = Context.ConnectionId;

   var toUser = OnlineUsers.FirstOrDefault(x => x.UserName == toUserName);
   var fromUser = OnlineUsers.FirstOrDefault(x => x.ConnectionId == fromConnectionId);

   if (toUser != null )
   {
    Clients.Client(toUser.ConnectionId).receivePrivateMessage(fromUser.UserName, message);
    Clients.Client(toUser.ConnectionId).receivePrivateMessage(message);
   }
   else
   {
    //表示对方不在线
    Clients.Caller.absentSubscriber();
   }
  }

  public void Send(string name, string message)
  {
   //Clients.All { get; } // 代表所有客户端
   //Clients.AllExcept(params string[] excludeConnectionIds); // 除了参数中的所有客户端
   //Clients.Client(string connectionId); // 特定的客户端,这个方法也就是我们实现端对端聊天的关键
   //Clients.Clients(IList<string> connectionIds); // 参数中的客户端
   //Clients.Group(string groupName, params string[] excludeConnectionIds); // 指定客户端组,这个也是实现群聊的关键所在
   //Clients.Groups(IList<string> groupNames, params string[] excludeConnectionIds);参数中的客户端组
   //Clients.User(string userId); // 特定的用户
   //Clients.Users(IList<string> userIds); // 参数中的用户

   Console.WriteLine("ConnectionId:{0}, InvokeMethod:{1}", Context.ConnectionId, "Send");
   Clients.All.addMessage(name, message);
  }

  /// <summary>
  /// 连线时调用
  /// </summary>
  /// <returns></returns>
  public override Task OnConnected()
  {
   Console.WriteLine("客户端连接,连接ID是:{0},当前在线人数为{1}", Context.ConnectionId, OnlineUsers.Count+1);
   return base.OnConnected();
  }


  /// <summary>
  /// 断线时调用
  /// </summary>
  /// <param name="stopCalled"></param>
  /// <returns></returns>
  public override Task OnDisconnected(bool stopCalled)
  {
   var user = OnlineUsers.FirstOrDefault(u => u.ConnectionId == Context.ConnectionId);

   // 判断用户是否存在,存在则删除
   if (user == null)
   {
    return base.OnDisconnected(stopCalled);
   }

   Clients.All.onUserDisconnected(user.ConnectionId, user.UserName); //调用客户端用户离线通知
   // 删除用户
   OnlineUsers.Remove(user);
   Console.WriteLine("客户端断线,连接ID是:{0},当前在线人数为{1}", Context.ConnectionId, OnlineUsers.Count);
   return base.OnDisconnected(stopCalled);
  }

  public override Task OnReconnected()
  {
   return base.OnReconnected();
  }
 }
}
登入後複製

#7、在Server控制台中加入Startup類,程式碼如下


#

using Microsoft.Owin.Cors;
using Owin;

namespace Server
{
 public class Startup
 {
  public void Configuration(IAppBuilder app)
  {
   //允许CORS跨域
   app.UseCors(CorsOptions.AllowAll);
   app.MapSignalR();
  }
 }
}
登入後複製

8、修改Server控制台中新增Program類,程式碼如下


using Microsoft.Owin.Hosting;
using System;

namespace Server
{
 class Program
 {
  static void Main(string[] args)
  {
   string url = "http://localhost:10086";//设定 SignalR Hub Server 对外的接口
   using (WebApp.Start(url))//启动 SignalR Hub Server
   {
    Console.WriteLine("Server running on {0}", url);
    Console.ReadLine();
   }
  }
 }
}
登入後複製

#9、F5運行起來

然後瀏覽器中存取http ://localhost:10086/signalr/hubs

結果如下:

見上圖內容就基本上完成了,今天先講到,時間不早了,先休息了,後續有時間再將後面的文章補上。

以上是SignalR Self Host多端訊息推播服務實例(三)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

windows11關機提示task host window任務宿主正在執行關閉任務的解決方法 windows11關機提示task host window任務宿主正在執行關閉任務的解決方法 Feb 12, 2024 pm 12:40 PM

近期不少的win11用戶們反映關機的時候提示taskhostwindow任務宿主正在執行關閉任務,那麼這是怎麼回事?使用者可以進入到本機登錄編輯程式下的Desktop資料夾,然後在右邊的視窗中選擇AutoEndTasks來進行設定就可以了。以下就讓本站來為用戶們來仔細的介紹一下關機出現這個問題的解決方法吧。 windows11關機提示taskhostwindow任務宿主正在執行關閉任務的解決方法1、使用組合鍵win鍵+r鍵,輸入“regedit”,回車,如下圖所示。 2、尋找[HKEY

如何檢查聚合器 host.exe 在 Windows 11 中是否安全 如何檢查聚合器 host.exe 在 Windows 11 中是否安全 Apr 13, 2023 pm 04:22 PM

當我們啟動任務管理器以終止任務或停止應用程式時,我們通常會發現大量進程正在運行。這是完全正常的。但是,有時我們會看到一些程式正在使用我們完全不知道的系統資源。其中一個進程是聚合器 host.exe,它最近在用戶中引起了一些混亂。其中一些進程可能是合法的 Windows 要求,但其他進程可能是在後台運行並在用戶不知情或未經用戶同意的情況下導致問題的惡意程式。在我們看到您可以在 Windows 11 中啟動工作管理員的五種方式之後,我們將向您展示如何檢查聚合器 host.exe 是安全性還是病毒。跟上

為什麼NameResolutionError(self.host, self, e) from e,怎麼解決 為什麼NameResolutionError(self.host, self, e) from e,怎麼解決 Mar 01, 2024 pm 01:20 PM

報錯的原因NameResolutionError(self.host,self,e)frome是由urllib3函式庫中的例外類型,這個錯誤的原因是DNS解析失敗,也就是說,試圖解析的主機名稱或IP位址無法找到。這可能是由於輸入的URL位址不正確,或DNS伺服器暫時無法使用所導致的。如何解決解決此錯誤的方法可能有以下幾種:檢查輸入的URL地址是否正確,確保它是可訪問的確保DNS伺服器可用,您可以嘗試在命令行中使用"ping"命令來測試DNS伺服器是否可用嘗試使用IP位址而不是主機名稱來存取網站如果是在代理

no route to host怎麼辦 no route to host怎麼辦 Oct 07, 2023 am 10:50 AM

「no route to host」的解決方案有檢查網路連線、檢查IP位址和連接埠、檢查防火牆設定、檢查路由設定、檢查網路設備設定、檢查網路服務狀態、檢查網路設定和聯絡網路管理員等。詳細介紹:1、檢查網路連接,確保客戶端和目標主機之間的網路連接正常,可以嘗試透過ping指令或其他網路工具測試網路連通性,檢查網路線、無線網路、路由器等硬體設備是否正常運作,確保網路連線穩定等等。

master和host的差別是什麼 master和host的差別是什麼 Sep 28, 2023 pm 01:34 PM

master和host的區別有:1、host可以扮演客戶端或伺服器的角色,而master是分散式系統中負責協調和管理其他從伺服器的中央伺服器;2、host是普通的電腦設備,而master通常具有更高的處理能力和資源,用於處理和分發任務、管理資料和維護整個系統的穩定性;3、host是網路中的一個節點,而master是在分散式系統中擔任核心角色的伺服器。

host檔案在哪裡 host檔案在哪裡 Jan 04, 2021 am 11:25 AM

host檔案位於路徑「C:\Windows\System32\drivers\etc」下;host檔案是純文字的文件,用普通的文字編輯軟體,如記事本等都能開啟;host檔案的作用是包含IP位址和Host name主機名稱的映射關係。

在 Windows 11 上修復 WMI Provider Host High CPU 的 4 個快速提示 在 Windows 11 上修復 WMI Provider Host High CPU 的 4 個快速提示 Apr 18, 2023 pm 08:25 PM

WMIProviderHost進程在Windows11中扮演著至關重要的角色。它使其他應用程式可以請求有關您的電腦的資訊。與WMIProviderHost相關的進程通常在背景運行;因此,它們通常不會消耗大量系統資源。但是,據報道,該服務有時會因為其他應用程式而使用超過50%的CPU功率。令人擔憂的是,您的電腦處理器幾乎以最大容量長時間運行,因為這可能導致過熱和系統組件損壞。在今天的教學中,我們將研究為什麼WMIProviderHost在Windows11上的C

Python中的self怎麼使用 Python中的self怎麼使用 May 17, 2023 pm 10:40 PM

在介紹Python的self用法之前,先來介紹下Python中的類別和實例我們知道,物件導向最重要的概念就是類別(class)和實例(instance),類別是抽象的模板,例如學生這個抽象的事物,可以用一個Student類別來表示。而實例是根據類別創建出來的一個個具體的“物件”,每個物件都從類別中繼承有相同的方法,但各自的資料可能不同。 1.以Student類別為例,在Python中,定義類別如下:classStudent(object):pass(Object)表示該類別從哪個類別繼承下來的,Object類別是所有

See all articles