Heim  >  Artikel  >  Backend-Entwicklung  >  Beispiel für den SignalR Self Host-Nachrichten-Push-Dienst mit mehreren Terminals (3)

Beispiel für den SignalR Self Host-Nachrichten-Push-Dienst mit mehreren Terminals (3)

零下一度
零下一度Original
2017-07-02 13:19:402152Durchsuche

In diesem Artikel werden hauptsächlich Multi-Terminal-Nachrichten-Push-Dienste wie SignalR Self Host+MVC vorgestellt. Interessierte Freunde können darauf verweisen

1. Übersicht

Aufgrund der Projektanforderungen gibt es kürzlich eine Modulfunktion im Projekt des Unternehmens, die verwendet werden muss, um eine sofortige Genehmigungsbenachrichtigung zu erhalten. Der ursprüngliche Entwurfsplan sah vor, den Server regelmäßig mit Ajax abzufragen Abfrage Als die Datenmenge und die Nutzung zu Beginn nicht groß waren, war es in Ordnung. Später, als die Nutzung zunahm und die Komplexität verschiedener Unternehmen im System zunahm, nahm auch der Druck auf den Server zu, also wollte ich Verwenden Sie Message Push, um die Ajax-Abfrage zu ersetzen. Wenn eine Genehmigung vorliegt, wird die Push-Methode aufgerufen, um die Nachricht an den nächsten Genehmiger zu senden und so den Druck auf den Server zu verringern.

Signal ist ein von Microsoft unterstütztes HTML-Websocket-Framework, das auf der .NET-Plattform läuft. Der Hauptzweck seines Erscheinens besteht darin, dem Server zu ermöglichen, Nachrichten aktiv an die Clientseite zu senden, sodass der Client die Anfrage nicht erneut senden oder Polling-Technologie verwenden muss, um die Nachricht zu erhalten. Und auch die Kompatibilität von SignalR ist sehr leistungsfähig, sodass ich hier nicht auf Details eingehen werde. Nachdem Sie sich nun für SignalR entschieden haben, können wir loslegen!

Meine Idee ist, SignalR zu einem selbstgehosteten Dienst zu machen und ihn von unserem B/S-Projekt zu trennen. Die Vorteile davon sind: 1. Der Push-Dienst ist nicht von iis abhängig, wir Der Push-Dienst kann weiterhin normal ausgeführt werden. 2. Wir können diesen Push-Dienst auf mehreren Plattformen aufrufen und mehrere Projekte gleichzeitig verwenden

2. Erstellen Sie den Server

Dies ist ohne weiteres das erste Mal, dass ich einen Blog schreibe. Nachdem wir die Geschäftsszenarien und -ideen vorgestellt haben, beginnen wir mit dem Codieren.

1. Verwenden Sie VS, um eine Lösung mit dem Namen „SignalRProject“ zu erstellen;

2. Erstellen Sie ein neues Steuerelement mit dem Namen „Server“ unter der SignalRProject-Lösung Taiwan

3. Geben Sie in der Paketmanagerkonsole den folgenden Befehl ein:


Install-Package Microsoft.AspNet.SignalR.SelfHost

4. Geben Sie den folgenden Befehl ein:


Install-Package Microsoft.Owin.Cors

5. Fügen Sie die UserInfo-Klasse wie folgt hinzu


using System; 
 
namespace Server 
{ 
 public class UserInfo 
 { 
  public string ConnectionId { get; set; } 
  public string UserName { get; set; } 
  public DateTime LastLoginTime { get; set; } 
 } 
}

6. Fügen Sie die ChatHub-Klasse in der Serverkonsole hinzu. Der Code lautet wie folgt


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. Fügen Sie die Startup-Klasse in der Serverkonsole hinzu. Der Code lautet wie folgt:


using Microsoft.Owin.Cors;
using Owin;

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

8. Ändern Sie die Serverkonsole, um die Programmklasse hinzuzufügen. Der Code lautet wie folgt:


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. Führen Sie F5 aus

Dann greifen Sie auf http://localhost:10086/signalr/hubs zu

Das Ergebnis ist wie folgt:

Siehe das Bild oben. Es ist im Grunde fertig. Es ist schon spät, also werde ich die folgenden Artikel nachholen, wenn ich Zeit habe.

Das obige ist der detaillierte Inhalt vonBeispiel für den SignalR Self Host-Nachrichten-Push-Dienst mit mehreren Terminals (3). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn