이 글에서는 SignalR Self Host+MVC 등의 멀티 터미널 메시지 푸시 서비스를 주로 소개합니다. 관심 있는 친구들은 참고하시면 됩니다.
1. 프로젝트 요구로 인해 최근에는 회사 프로젝트에서 즉시 승인 알림을 받아야 하는 모듈 기능, 원래 계획은 ajax를 사용하여 서버 쿼리
를 정기적으로 폴링하는 것이었고, 데이터 양과 사용량이 크지 않으면 괜찮았습니다. 처음에는 사용이 증가하고 시스템 내 다양한 비즈니스가 복잡해지면서 서버에 대한 부담도 커지고 있으므로 Ajax 폴링 쿼리를 대체하기 위해 메시지 푸시를 사용하고 싶습니다. 승인 제출 시 push 메소드가 호출되어 메시지를 푸시하므로 서버에 대한 부담이 줄어듭니다. 내 생각은 SignalR을 자체 호스팅 서비스로 만들고 이를 b/s 프로젝트와 분리하는 것입니다. 이것의 장점은 다음과 같습니다. 1. 푸시 서비스는 iis에 의존하지 않습니다. 2. 이 푸시 서비스를 여러 플랫폼에서 호출할 수 있으며 여러 프로젝트를 동시에 사용할 수 있습니다.2. 서버 만들기
말도 안 돼요. 블로그를 처음 작성하는 단계, 소개를 마치고 비즈니스 시나리오 및 아이디어, 코딩을 시작하겠습니다.
1. VS를 사용하여 "SignalRProject"라는 솔루션을 만듭니다.2. SignalRProject 솔루션 아래에 Server라는 새 콘솔을 만듭니다. 3. 패키지 관리자 데스크에서 다음 명령을 입력합니다.
Install-Package Microsoft.AspNet.SignalR.SelfHost
4. 다음 명령을 입력합니다.
Install-Package Microsoft.Owin.Cors
5. 서버 콘솔에 UserInfo 클래스를 추가합니다. 코드는 다음과 같습니다.
using System; namespace Server { public class UserInfo { public string ConnectionId { get; set; } public string UserName { get; set; } public DateTime LastLoginTime { get; set; } } }
6. 서버 콘솔에 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. 서버 콘솔에 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. 프로그램 클래스를 추가하도록 서버 콘솔을 수정합니다. 코드는 다음과 같습니다
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 다중 단말 메시지 푸시 서비스 예시(3)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!