基于Ajax长轮询与MSMQ实现消息推送的Demo

作者:清欢

时间:2026-10-21

浏览:395

本文介绍了一个基于Ajax长轮询与MSMQ消息队列实现的消息推送Demo。通过WinForm客户端发送消息至队列,Web服务端利用长轮询机制持续监听队列变化,并将新消息实时返回给前端页面展示。该方案实现了简单的实时数据同步功能,代码结构清晰,适合初学者理解长轮询原理及MSMQ的基本用法。

文章目录

周末闲暇时尝试编写了一个简易的消息推送示例,虽然技术难度不高,但希望能抛砖引玉,欢迎大家提出批评意见。

消息推送Demo架构与交互流程

该推送Demo的核心架构采用Ajax长轮询配合MSMQ消息队列,具体的交互流程如图所示:

消息推送Demo架构与交互流程

首先解析Ajax长轮询机制,所谓“长”的时间界限其实并不固定。

与普通Ajax请求通常在毫秒级内完成处理不同,长轮询方式

在Ajax向服务器发起请求后,服务器返回数据的时间跨度难以预估。这主要取决于

何时向MSMQ队列中写入数据。先直观看看推送效果:

消息推送Demo架构与交互流程

由于条件限制,未提供动态演示图。整体功能实现如下:在WinForm程序中点击“即刻发送”按钮,网页端即可同步显示新推送的数据。

明确了具体实现流程与效果后,接下来进入编码环节。

WinForm客户端实现

消息推送WinForm程序代码


namespace SenderApp
{
  public partial class Form1 : Form
  {
    private string queueName = @".\Private$\pushQueue";
    private MessageQueue pushQueue = null;
    
    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      try
      {
        var queue = this.GetQueue();
        if (string.IsNullOrEmpty(this.textBox1.Text)) { this.label1.Text = "推送消息不能为空"; return; }
        queue.Send(this.textBox1.Text, "messagePush");
        this.label1.Text = "消息推送成功";
      }
      catch (Exception ex)
      {
        this.label1.Text = string.Format("消息推送失败:{0}",ex.Message);
      }
    }

    private MessageQueue GetQueue()
    {
      if (this.pushQueue == null)
      {
        if (!MessageQueue.Exists(queueName))
        {
          this.pushQueue = MessageQueue.Create(queueName);
        }
        else
        {
          this.pushQueue = new MessageQueue(queueName);
        }
      }
      return this.pushQueue;
    }

    private void textBox1_MouseDown(object sender, MouseEventArgs e)
    {
      this.textBox1.Text = "";
      this.label1.Text = "推送状态";
    }
  }
}

Web服务端长轮询逻辑

Web服务端代码


namespace MessagePushWeb.Controllers
{
  public class HomeController : Controller
  {
    private static string queueName = @".\Private$\pushQueue";
    private static MessageQueue pushQueue = null;

    public ActionResult Index()
    {
      return View();
    }

    public async Task<ActionResult> GetMessage()
    {
      string msg = await Task.Run(() => {
        return this.ReadMessage();
      });
      
      return Content(msg);
    }


    private MessageQueue GetQueue()
    {
      if (pushQueue == null)
      {
        if (MessageQueue.Exists(queueName))
        {
          pushQueue = new MessageQueue(queueName);
          pushQueue.Formatter = new XmlMessageFormatter(new string[] { "System.String" });
        }
      }
      return pushQueue;
    }

    private string ReadMessage()
    {
      var queue = GetQueue();
      Message message = queue.Receive();
      return message.Body.ToString();
    }
  }
}

前端页面视图代码

页面视图代码


@{
  ViewBag.Title = "Push";
}


<h2>Push</h2>

<div>接收消息列表</div>
<div id="msg"></div>

<script type="text/javascript">
  $(function () {
    getMessage();
  });


  function getMessage() {
    $.get("/home/getmessage", {}, function (data) {
      var _msg = $("#msg").html();
      $("#msg").html(_msg + "<li>" + data + "</li>");
      getMessage();
    });
   }
</script>


需要说明的是,这仅是一个初级消息推送Demo,其是否适用于生产环境仍需进一步验证。

若您有更好的实现方案或建议,欢迎留言交流。

源码下载地址:http://pan.baidu.com/s/1hsHSLTy

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

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章