SignalR Self Host + MVC and other multi-terminal message push services (1), signalrmvc
I. Overview
Due to project requirements, a module function has recently been provided in the company's project, which requires immediate approval notifications. The original design scheme was to use ajax to perform regular round robin queries on the server, at the beginning, the data volume and usage were not large. Later, the increase in usage and complexity of various services in the system increased, and the pressure on servers increased, so I want to replace the ajax round-robin query with the message push method. When an application is approved and submitted, I call the push method to push the message to the next approver, this reduces the pressure on the server.
SignalR is an html websocket framework supported by Microsoft running on the. NET platform. The main purpose of this function is to enable the server to actively push messages to the client page, so that the client does not have to resend requests or use polling technology to retrieve messages. The compatibility of SignalR is also very powerful. Now that you have selected SignalR, let's get started!
My idea is to make SignalR a self-managed service and separate it from our B/s project. The advantage is that 1. The Push Service does not depend on iis, even if iis fails, our PUSH Service can still run normally; 2. We can call this push service on multiple platforms, and multiple projects can be used at the same time;
2. Create a server
I will write my blog for the first time. After introducing the business scenarios and ideas, let's start coding.
1. Use VS to create a solution named "SignalRProject;
2. Create a console named Server under the SignalRProject Solution
3. On the Package Manager Console, enter the following command:
Install-Package Microsoft. AspNet. SignalR. SelfHostView Code
4. Enter the following command:
Install-Package Microsoft. Owin. CorsView Code
5. Add the UserInfo class on the Server console. The Code is as follows:
Using System; namespace Server {public class UserInfo {public string ConnectionId {get; set;} public string UserName {get; set;} public DateTime LastLoginTime {get; set ;}}}View Code
6. Add the ChatHub class on the Server console. The Code is as follows:
Using Microsoft. aspNet. signalR; using Microsoft. aspNet. signalR. hubs; using System. collections. generic; using System. linq; using System. threading. tasks; namespace Server {[HubName ("IMHub")] public class ChatHub: Hub {// static attribute public static List <UserInfo> OnlineUsers = new List <UserInfo> (); // online user list /// <summary> /// logon link // </summary> /// <param name = "userId"> User ID </param>/ // <param name = "UserName"> User Name </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);} // Add online staff OnlineUsers. add (new UserInfo {ConnectionId = connnectId, UserName = userName, LastLoginTime = DateTime. now});} // all Clients synchronize online user Clients. all. onConnected (connnectId, userName, OnlineUsers );} /// <summary> /// send private chat /// </summary> /// <param name = "toUserId"> receiver user connection ID </param> /// <param name = "message"> content </param> public void SendPrivat EMessage (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 ). descrieprivatemessage (fromUser. userName, message); Clients. client (toUser. connectionId ). receivePrivateMessage (message);} else {// indicates that the other party is not online Clients. caller. absentSubscriber () ;}} public void Send (string name, string message) {// Clients. all {get;} // represents All Clients // Clients. allExcept (params string [] excludeConnectionIds); // except for all Clients in the parameter, // Clients. client (string connectionId); // specific Client. This method is the key to implementing end-to-end chat. // Clients. clients (IList <string> connectionIds); // client in the parameter // Clients. group (string groupName, params string [] excludeConnectionIds); // specifies the client Group, which is also the key to implementing Group chat. // Clients. groups (IList <string> groupNames, params string [] excludeConnectionIds); client group // Clients in the parameter. user (string userId); // specific User // Clients. users (IList <string> userIds); // The user Console in the parameter. writeLine ("ConnectionId: {0}, InvokeMethod: {1}", Context. connectionId, "Send"); Clients. all. addMessage (name, message );} /// <summary> // call when connecting lines /// </summary> /// <returns> </returns> public override Task OnConnected () {Console. writeLine ("client connection, connection ID: {0}, current number of online users is {1}", Context. connectionId, OnlineUsers. count + 1); return base. onConnected ();} /// <summary> /// call when disconnection occurs /// </summary> /// <param name = "stopCalled"> </param> /// <returns> </returns> public override Task OnDisconnected (bool stopCalled) {var user = OnlineUsers. firstOrDefault (u => u. connectionId = Context. connectionId); // determines whether the user exists. if (user = null) {return base. onDisconnected (stopCalled);} Clients. all. onUserDisconnected (user. connectionId, user. userName); // call the client user offline notification // Delete the user OnlineUsers. remove (user); Console. writeLine ("client disconnected, connection ID: {0}, current number of online users is {1}", Context. connectionId, OnlineUsers. count); return base. onDisconnected (stopCalled);} public override Task OnReconnected () {return base. onReconnected ();}}}View Code
7. Add the Startup class on the Server console. The Code is as follows:
Using Microsoft. owin. cors; using Owin; namespace Server {public class Startup {public void Configuration (IAppBuilder app) {// allows CORS cross-origin apps. useCors (CorsOptions. allowAll); app. mapSignalR ();}}}View Code
8. Modify the Server console and add the Program class. The Code is as follows:
Using Microsoft. owin. hosting; using System; namespace Server {class Program {static void Main (string [] args) {string url = "http: // localhost: 10086 "; // set the interface using (WebApp. start <Startup> (url) // Start SignalR Hub Server {Console. writeLine ("Server running on {0}", url); Console. readLine ();}}}}View Code
9. Run F5
Then access http: // localhost: 10086/signalr/hubs in the browser
The result is as follows:
The content is basically complete. I will talk about it today. It's not too early. I have a rest first, and I will make up later articles.