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

结果如下:

见上图内容就基本完成了,今天先讲到着,时间不早了,先休息了,后续有时间再将后面的文章补上

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Asp.NET MVC中使用SignalR实现推送功能

    一.简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请求或使用轮询技术来获取消息. 可访问其官方网站:https://github.com/SignalR/ 获取更多资讯. 二.Asp.net SignalR 是个什么东东 Asp.net SignalR是微软为实现实时通信的一个类库.一般情况下,SignalR会使用JavaScript的长轮询(lo

  • .net 通过URL推送POST数据具体实现

    由于到了一家新公司重新开始接触MVC和其他的一些东西.所以的重新拾起许多东西. 前一段时间让我写一个和第三方公司推送对接的方法.通过对方提供的URL把数据post推送出去. 我把url到了web.config里 复制代码 代码如下: <add key="urlStrings" value="urladdress"/> 在.CS文件里 复制代码 代码如下: private string postString = System.Configuration.C

  • asp.net mvc实现简单的实时消息推送

    因为项目需要,需要在网页上实现消息的推送.在百度上搜索了一下,发现实现网页上的消息推送,可以使用asp.net 中的SignalR类库,当然也可以使用H5的WebSocket  Ajax的轮回.当然此处我们使用asp.net 中的SignalR类库.因为它可以实现网页上消息的实时推送.什么是实时推送呢,我简单的说一下我个人的理解吧.实时:在同一时间类发生的事情,当然在计算机中并不是绝对的实时,因为CPU在同一时间片只能处理一个任务,那么这个时候疑问又来了? 我们平时使用电脑又上网,又听音乐是如何

  • .net平台推送ios消息的实现方法

    本文实例讲述了.net平台推送ios消息的实现方法.分享给大家供大家参考. 具体实现步骤如下: 1.ios应用程序中允许向客户推送消息 2.需要有苹果的证书以及密码(怎么获取,网上搜一下,需要交费的) 3.iphone手机一部,安装了该ios应用程序 4..net 项目中引用PushSharp.Apple.dll,PushSharp.Core.dll(这两个文件在网上搜一下,有源码的) 5.开始写代码,定义全局的对象PushBroker pusher = new PushBroker(); 6.

  • ASP.NET实现推送文件到浏览器的方法

    本文实例讲述了ASP.NET实现推送文件到浏览器的方法.分享给大家供大家参考.具体分析如下: 这里主要实现从服务器到浏览器,推送文件,提供用户下载/浏览的功能. 提示: 在AJAX UpdatePanel里面将无效.如果代码从按钮单击事件中被调用,该按钮需要在 AJAX UpdatePanel的外部. 具体代码如下: /// <summary> /// Downloads (pushes) file to the client browser. /// **** NOTE **** Canno

  • 基于SignalR的消息推送与二维码扫描登录实现代码

    1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于SinglarR消息推送机制的扫描登录.本系统涉及到以下知识点: SignalR:http://signalr.net/ 这官网,ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的

  • 使用SignalR推送服务在Android的实现 SignalA

    由于我的版本最低是2.2,所以只有把源码下下来自己改,如果你觉得太多了可自己编译成jar引用,本人不才,对java不是很熟悉,如果此版本中有错误还请大家指出来,此图显示的是安卓2.2与4.0的版本. chat_hub代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/androi

  • SignalR Self Host+MVC等多端消息推送服务(三)

    一.概述 最近项目确实太忙,而且身体也有点不舒服,慢性咽炎犯了,昨晚睡觉时喘不过气来,一直没休息好,也没什么时间写博客,今天朋友问我什么时候能出web端的消息发送的文章时,我还在忙着改项目的事,趁着中午吃饭和午休的时间,赶紧补上之前欠下的文章. 这章主要是实现多端消息相互通信的简单demo,mvc的web端发送信息到control端等. 二.创建web客户端 1.新建一个WebClient解决方案 2.在WebClient解决方案下新建一个名为Clinet mvc项目 3.根据自己实际情况选择对

  • SignalR Self Host+MVC等多端消息推送服务(二)

    一.概述 上次的文章中我们简单的实现了SignalR自托管的服务端,今天我们来实现控制台程序调用SignalR服务端来实现推送信息,由于之前我们是打算做审批消息推送,所以我们的demo方向是做指定人发送信息,至于做聊天消息和全局广播,这里就不在进行演示了. 二.创建控制台客户端 1.在SignalRProject解决方案下新建一个名为Clinet的控制台 2.在程序包管理控制台中输入以下命令 Install-Package Microsoft.AspNet.SignalR.Client 3.修改

  • SignalR Self Host+MVC等多端消息推送服务(一)

    一.概述 由于项目需要,最近公司项目里有个模块功能,需要使用到即时获得审批通知:原本的设计方案是使用ajax对服务器进行定时轮询查询,刚刚开始数据量和使用量不大的时候还好,后来使用量的增加和系统中各种业务的复杂度增加,服务器的压力也越来越大,于是我想使用消息推送的方式替换掉ajax轮询查询,当有审批提交时,调用推送方法,将消息推送到下一审批人那,这样就减低了服务器的压力. Signal 是微软支持的一个运行在.NET平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推

  • 搭建websocket消息推送服务,必须要考虑的几个问题

    近年,不论是正在快速增长的直播,远程教育以及IM聊天场景,还是在常规企业级系统中用到的系统提醒,对websocket的需求越来越大,对websocket的要求也越来越高.从早期对websocket的应用仅限于少部分功能和IM等特殊场景,逐步发展为追求支持高并发,百万.千万级每秒通讯的高可用websocket服务. 面对各种新场景对websocket功能和性能越来越高的需求,不同的团队有不同的选择,有的直接使用由专业团队开发的成熟稳定的第三方websocket服务,有些则选择自建websocket

  • react-native使用leanclound消息推送的方法

    iOS消息推送的基本流程 1.注册:为应用程序申请消息推送服务.此时你的设备会向APNs服务器发送注册请求.2. APNs服务器接受请求,并将deviceToken返给你设备上的应用程序 3.客户端应用程序将deviceToken发送给后台服务器程序,后台接收并储存. 4.后台服务器向APNs服务器发送推送消息 5.APNs服务器将消息发给deviceToken对应设备上的应用程序 使用leanclound进行消息推送 优势:文档清晰,价格便宜 接入Leanclound 1.首先需要创建一个re

  • java WebSocket实现聊天消息推送功能

    本文实例为大家分享了java WebSocket实现聊天消息推送功能的具体代码,供大家参考,具体内容如下 环境: JDK.1.7.0_51 apache-tomcat-7.0.53 java jar包:tomcat-coyote.jar.tomcat-juli.jar.websocket-api.jar ChatAnnotation消息发送类: import java.io.IOException; import java.util.HashMap; import java.util.Map;

  • java实现web实时消息推送的七种方案

    目录 引言 什么是消息推送(push) 短轮询 长轮询 iframe流 SSE (我的方式) MQTT Websocket 自定义推送 Github地址 引言 做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能. 不过他还没想好用什么方式做,这里我帮他整理了一下几种方案,并简单做了实现. 案例下载 什么是消息推送(push) 推送的场景比较多,比如有人关注我的公众号,这时我就会收到一条推送消息,以此来吸引我点击打开应用. 消息推送(push)通常是

  • flutter消息推送客户端集成方案详解

    目录 一.背景 二.第三方消息推送——个推 1.简介 2.注册开通 3.自定义消息推送——透传 三.项目集成 1.个推客户端flutter插件 2.Android和IOS配置 1)Android 2) iOS 3.通知栏插件flutter_local_notifications 4.个推消息与通知栏整合 最后 一.背景 公司一个CRM APP项目是用Flutter写的,根据业务要求,需要集成消息推送功能.所谓的消息推送就是系统会根据某些行为自动推送信息,手机的通知栏会接收到信息,点击可以打开ap

  • Django Channels 实现点对点实时聊天和消息推送功能

    简介在很多实际的项目开发中,我们需要实现很多实时功能:而在这篇文章中,我们就利用django channels简单地实现了点对点聊天和消息推送功能. 手边有一个项目需要用到后台消息推送和用户之间一对一在线聊天的功能.例如用户A评论了用户B的帖子,这时候用户B就应该收到一条通知,显示自己的帖子被评论了.这个功能可以由最基本的刷新页面后访问数据库来完成,但是这样会增加对后台服务器的压力,同时如果是手机客户端的话,也会造成流量的损失.于是,我们考虑使用websocket建立一个连接来完成这个功能. 但

  • SpringBoot整合WxJava开启消息推送的实现

    目录 1.引入 WxJava 依赖 2.申请微信小程序 3.微信小程序配置信息 4.消息推送配置 5.接收消息推送的 API 6.消息推送测试 接入微信小程序消息推送服务,可以3种方式选择其一: 1.开发者服务器接收消息推送2.云函数接收消息推送3.微信云托管服务接收消息推送 开发者服务器接收消息推送,开发者需要按照如下步骤完成: 1.填写服务器配置2.验证服务器地址的有效性3.据接口文档实现业务逻辑,接收消息和事件 1.引入 WxJava 依赖 <!-- web支持 --> <depe

随机推荐