zoukankan      html  css  js  c++  java
  • 使用 SignalR与SSE(Sever sent event)向客户端推送提示信息

    最近有个项目想把c/s的代码转成mvc的,这听起来并不困难。
    如果UI和业务逻辑良好分离了的话,不会花太多的功夫,应该多数的内容都能重复利用。

    但在实际的操作过程中,发现业务逻辑代码和UI提示全是混在一起的,尤其里面有这样的代码很多:

    public class MyLogic
    {
        public int DoPress(string bin)
        {
            if (string.IsNullOrEmpty(bin))
            {
                System.Windows.Forms.MessageBox.Show("数据为空,请登录后使用");
                return -1;
            }
    
            return 0;
        }
    }
    

    这是一段伪代码,不是真实的代码内容。这段代码背后有这样的信息:

    • MyLogic类是底层的代码,有很多系统都在调用它,关系错综复杂
    • 代码内需要有合法性的检验,如果合法性校验失败,那函数会被return,错误信息需要让用户看到

    现在的问题是,这个MessageBox.Show()的内容我怎么才能显示用户这一端来呢?

    首先,b/s的程序,这些代码是运行在服务器端的,原来的MessageBox.Show()不会有任何的效果。

    如果我们修改原先的函数签名,将 数据为空,请登录后使用 这句话传输到浏览器,再用javascript的alert来提示。技术上是可以实现的。

    就像这样:

    public class MyLogic
    {
        public Tuple<int, string> DoPress(string bin)
        {
            if (string.IsNullOrEmpty(bin))
            {
                //System.Windows.Forms.MessageBox.Show("数据为空,请登录后使用");
                return new Tuple<int, string>(-1, "数据为空,请登录后使用");
            }
    
            return new Tuple<int, string>(-1, null);
        }
    }
    

    这个Tuple会被返回出去,最后传输到浏览器。

    然而,这会修改原先的函数签名,所有使用DoPress的函数都要修改,并且,有的地方还是使用反射来调用的,要这样修改,会带来巨大的工作量,

    根据这个具体的情况,我不得不去想如何在有限的时间内来完成这件事。

    问题的核心是:如何不修改函数的签名,并将相关的信息输出到浏览器?

    我首先浮现了第一个解决方案是SSE(Server sent event),它是HTML5里服务器向客户端推送事件的一种方式。很快我写了一个小的demo来进行测试,确实可以用,但是有问题:非常的慢,Server产生了消息之后,最长需要等待4秒才能看到提示消息。

    我google了这个问题,也看到其他人的讨论:https://stackoverflow.com/questions/12297740/server-sent-events-work-but-with-a-massive-time-delay

    但最后这个问题还是没有解决。

    于是我转向了SignalR,很快写了另外的一个demo,这次工作良好,消息瞬时到达。

    那么,之前的项目修改成什么样子呢?

    public class MyLogic
    {
        public int DoPress(string bin)
        {
            if (string.IsNullOrEmpty(bin))
            {
                MessagePushHelper.PushSignalR("数据为空,请登录后使用");
                return -1;
            }
    
            return 0;
        }
    }
    

    可以看到,之前的MessageBox.Show()改成了我自己写的MessagePushHelper.PushSignalR(),其他位置不变,这样应该是最小改动的解决方案了。

    只不过有一点需要注意的是:要注意多个用户同时使用时的情况(你不能对外广播出错消息)

    最后,简单的记录一下步骤:

    若要使用SSE

    • 将输出内容标记为 text/event-stream
    • 输出你想要的内容

    若要使用SignalR

    • nuget包 install-package Microsoft.AspNet.SignalR
    • 创建hub
    • 创建startup类,打上OwinStartup标记
    • 在页面引用 jquery.signalR-2.2.2.min.js和signalr/hubs
    • 启动hub并接收数据

    文中提到的解决方案,可在github上查看:https://github.com/syler/Fun/tree/master/SSE-SignalR

    本文地址:http://www.cnblogs.com/asis/p/signalr-sse.html

    我的博客地址:https://1few.com/SSE-SignalR

  • 相关阅读:
    HDU 1800 Flying to the Mars 字典树,STL中的map ,哈希树
    字典树 HDU 1075 What Are You Talking About
    字典树 HDU 1251 统计难题
    最小生成树prim算法 POJ2031
    POJ 1287 Networking 最小生成树
    次小生成树 POJ 2728
    最短路N题Tram SPFA
    poj2236 并查集
    POJ 1611并查集
    Number Sequence
  • 原文地址:https://www.cnblogs.com/asis/p/signalr-sse.html
Copyright © 2011-2022 走看看