web新闻推送的种种解决办法

访客4年前黑客资讯897

摘要

在种种BS架构的应用程序中,往往都希望服务端能够自动地向客户端推送种种新闻,以到达类似于邮件、新闻、待办事项等通知。

往BS架构自己存在的问题就是,服务器一直接纳的是一问一答的机制。这就意味着若是客户端不自动地向服务器发送新闻,服务器就无法得知若何给客户端推送新闻。

随着HTML、浏览器等各项手艺、尺度的生长,依次天生了差别的手段与方式能够实现服务端自动推送新闻,它们分别是:AJAX,Comet,ServerSent以及WebSocket。

本篇文章将对上述提及到的种种手艺手段举行直白化的注释。


1.AJAX

正常的一个页面在浏览器中是这样事情的:

  1. 用户向给予浏览器一个需要接见的地址
  2. 浏览器凭据这个地址接见服务器,并与服务器之间确立一个TCP毗邻(HTTP请求)
  3. 服务器凭据这个地址和一些其它数据,组建一段HTML文本,将写入TCP毗邻,然后关闭毗邻
  4. 浏览器得到了来自服务器的HTML文本,剖析并出现了浏览器上给用户浏览

此时,用户点击了网站上任何一个<a>或触发任何一个<form>提交时:

  1. 浏览器凭据form的参数或者a的参数,作为接见的地址
  2. 与服务器确立TCP毗邻
  3. 服务器组建HTML文本,然后关闭毗邻
  4. 浏览器将当前显示的页面摧毁,并根据新的HTML文本出现一个新的页面给用户

我们不难发现的是整个历程中心,一旦确立了一个毗邻,页面就无法再维护住了。整个历程看上去有点强买强卖,也许我只要一杯新的可乐,但你非要给我一整个套餐组合。

此时我们可以领会一下XmlHttpRequest组件,这个组件提供我们手动确立一个HTTP请求,发送我们想要的数据,服务器也可以只返回我们想要的效果,更大的利益是,当我们收到服务器的响应时,原来的页面没有被摧毁。这就好比,我喊一句"我的咖啡喝完了,我要续杯",然后服务员就拿了一杯咖啡过来,而不是会把我没吃完的套餐所有倒掉。

当我们行使AJAX实现服务器推送时,实在质是客户端不停地向服务器询问"有没有给我的新闻呀?",然后服务器回覆"有"或"没有"来到达的实现效果。它的实现方式也很简朴,行使jQuery框架封装好的AJAX挪用也很利便:



function getMessage(fn) {
    $.ajax({
        url: "Handler.ashx", //一个能够提供新闻的页面
        dataType: "text",    //响应类型,可以是 *** ON,XML等其它类型
        type: "get",         //HTTP请求类型,还可以是post
        success: function (d, s) {
            fn(d);           //得到了正常的响应时,行使回调函数通知外部
        },
        complete: function (x, s) {
            setTimeout(function () {
                getMessage(fn);
            }, 5000);       //无论响应乐成或失败,在若干秒后再询问一次服务器
        }
    });
}

 通过上面的代码,可以每隔5秒询问一次服务器是否有需要处置的新闻,通过这种方式可以到达推送的效果,然则会存在一个问题:

  1. 间隔时间越快,推送的及时性越好,服务器的消费越大;
  2. 间隔时间越慢,推送的及时性越低,服务器的消费越小。

而且严格地来说,这种现实方式,并不是真正意义上的服务器自动推送新闻,但由于早期手艺手段缺乏,以是AJAX轮循成为了一种很普遍的手段。


2.Comet

我们知道HTTP请求实在是基于TCP毗邻实现的,再看看之前说的HTTP请求处置历程:

  1. 客户端与服务器确立TCP毗邻
  2. 服务器凭据客户端提交的报文处置并天生HTML文本
  3. 将HTML封锁成为HTTP协议报文并返回给客户端
  4. 关闭链接。

看到这个处置历程,我们不难联想到,若是把第4步——关闭毗邻给省掉,那不就相当于有一个长毗邻一直被维持住了么。通过对服务端的一些操作,我们可以直接将数据从这个TCP毗邻发送客户端了。

通过这种手艺,我们可以大大提高服务器推送的实时性,还可以减去服务端不停地确立、施放毗邻所形成的开销。

现在市面上有不少基于AJAX实现的Comet机制,但主要有两种方式:

  1. 确立毗邻后依然使用"询问"+"应答"的模式。虽然事情方式没变,然则由于减去了每次确立与施放毗邻的事情,以是性能上提升了许多。而且服务器对TCP毗邻可以有上下文的界说,而不像以前的AJAX完全是无状态的。
  2. 通过对Stream的写入实现服务器将数据自动发送到客户端。由于是TCP毗邻,以是通过对服务器的编程,我们可以自动的把数据从服务端发送给客户端,从模式上真正确立起了推送的观点。

 

3.Server-Sent

Server-Sent是HTML5提出一个尺度,它延用了Comet的思绪,并对其举行了一些规范。使得Comet这项手艺由原来的分支衍生手艺转成了正统的官方尺度。

它的原理与Comet相同,由客户端提议与服务器之间确立TCP毗邻,然后并维持这个毗邻,至到客户端或服务器中的做任何一放断开,ServerSent使用的是"问"+"答"的机制,毗邻确立后浏览器会周期性地发送新闻至服务器询问,是否有自己的新闻。

这项尺度不仅要求了支持的浏览器能够原生态的确立与服务器的长毗邻,更要求了对JavaScript剧本的统一性,使得兼程该功效的浏览器可以使用统一套代码完成Server-Sent的编码事情。

确立代码异常简朴:

//界说一个ServerSent工具
var s = new EventSource("Handler.ashx");
//当收到一个非自界说事宜时的回调函数
s.onmessage = function (e) {
    alert(e.data);
};
//当收到一个被服务器命名为MyEvent事宜新闻时的回调函数
s.addEventListener("MyEvent", function (e) {
    alert(e.data);
});

而服务器的代码也很简朴:



public class Handler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/event-stream";
        context.Response.Expires = -1;
        context.Response.Write("event: MyEvent\r\n");       //事宜类型,使用\r\n末端
        context.Response.Write("data: HelloWorld!\r\n");    //事宜数据,换行时使用\r\n,并在新行再加上data:
        context.Response.Write("data: I'm server!\n\n");    //事宜数据竣事,使用\n\n
        context.Response.Flush();                           //这里不能用End,否则是关闭毗邻的
    }
    public bool IsReusable
    {
        get
        {
            return true;
        }
    }
}

两小段代码,就已经具备了服务器新闻推送了。

总得来说SeverSent就是HTML5规范下的Comet,具有更好的统一性,而且简朴好用。


4.WebSocket

看名字就知道了,这是一个可以用在浏览器上的Socket毗邻。

这也是一个HTML5尺度中的一项内容,他要求浏览器可以通过JavaScript剧本手动确立一个TCP毗邻与服务端举行通讯。

WebSocket不包罗太多的分外功效,仅仅就是TCP毗邻的几项基本功效:确立,暂且以及发送。

另外WebSocket使用了ws和wss协议,需要服务器有与之握手的算法才气将毗邻打开。

以是WebSocket相对于之前几种手段来说,其编码量是更大的,但由于没有其它的约束,因此它也可以自由地实现所有可能的功效。

即可以知足"问"+"答"的响应机制,也可以实现自动推送的功效。

与ServerSent相同,HTML5也对WebSocket挪用的JavaScript举行规范,我们可以弄过很简朴的一代码构建一个WebSocket毗邻

var ws = new WebSocket("ws://192.168.0.105:10080"); //毗邻服务器        
ws.onopen = function (event) { alert("已经与服务器确立了毗邻\r\n当前毗邻状态:" + this.readyState); };
ws.onmessage = function (event) { alert("接收到服务器发送的数据:\r\n" + event.data); };
ws.onclose = function (event) { alert("已经与服务器断开毗邻\r\n当前毗邻状态:" + this.readyState); };
ws.onerror = function (event) { alert("WebSocket异常!"); };

还可以通过send的方式发送新闻



ws.send("Hello World");

WebSocket具有较为庞大的协议,需要在服务端做分外编程才气举行数据通讯。有关协议的详细内容,我会在以后的文章中举行注释。

 

5.WebSocket + MessageQueue

MessageQueue,简称MQ,也就是新闻排队。是一种经常用于Tcp服务端的手艺。通过生产和接见种种新闻类型,MQ服务器会将生产者所天生的新闻发给感兴趣的客户端。市面上有许多的MQ框架,好比:ActiveMQ。

ActiveMQ已经支持了WebSocket协议,也就意味着,WebSocket已经可以作为一个生产者或一个消费者,与MQ服务器毗邻。

开发者可以通过MQTT的 *** 剧本,毗邻上MQ服务器,同时将Web服务器也连上MQ服务器,今后可以告别了Http通讯协议,完完全全使用Socket通讯来完成数据的交流。

 

 

总结:

总得来说,在HTML5规范下,最推荐使用ServerSent和WebSocket的方式举行服务器新闻的推送。

对比这两种方式。

ServerSent的方式,可以使服务端的开发依然依用以前的方式,然则其事情方式与Comet类似。

而WebSocket的方式,则对服务端的开发有着较高的要求,但其事情方式是完全的推送。

我本人实在挺偏向WebSocket + MQ的事情方式,然则对于老项目的翻新,照样用SeverSent比较好

 


末端

本文为作者原创,转载请注明出处:http://www.cnblogs.com/ShimizuShiori/p/5464063.html

文章中的相关代码可以在 http://j.zizhusoft.com/Develop/Explorer.aspx 中的ServerSent目录中查看


思源资源网:分类流动

1.阿里云: 本站现在使用的是阿里云主机,平安/可靠/稳固。点击领取2000米代金券、领会最新阿里云产物的种种优惠流动点击进入

相关文章

捕鱼达人怎么赚钱?捕鱼达人赚钱

捕鱼达人怎么赚钱?捕鱼达人赚钱

在捕鱼达人千炮版这一款游戏中,总是能看到系统消息说谁谁谁打到了鲨鱼,恭喜获得多少多少的金币奖励,打鱼失败的你看到这种消息是不是对游戏充满失望了?其实打鱼三分靠运气,七分靠技巧,今天小编就来说怎么得高分...

森永蒙奈饼干有辐射吗 森永蒙奈饼干能不能吃

一些母亲会为小孩提前准备一些小零食,例如曲奇饼干溶豆这类的。但是选哪些好一直是妈妈们较为疑惑的一点。那麼森永蒙奈曲奇饼干如何,以前很多人都很担忧日本的食品类有辐射源,那麼森永蒙奈曲奇饼干有辐射源吗,森...

电脑证书过期怎么弄,解决电脑证书过期的有效方法

电脑证书过期怎么弄,解决电脑证书过期的有效方法

经常使用电脑的朋友应该遇到过电脑运行程序的时候老是跳出对话框提示“安全证书过期”。加载游戏或者软件的时候跳出安全证书过期,你的游戏进不去软件打不开,下载软件也是下载不成功的,这到底是什么情况导致的呢?...

一个手机可以登两个微信吗

一个手机可以登两个微信吗

很多人都钟情于微信这个社交聊天软件,因为这个软件具备强大的安全性和隐私性,并不会像其它软件一样轻而易举给别人获取聊天记录还有一些信息。想必大家对微信最大的印象就是在一个微信号不能够同时登录在两部手机上...

哪些知名品牌薯片被检出含致癌物 薯片含致癌物会怎样

薯条是大伙儿很喜欢的零嘴了,近日深圳市消委会表明好几家著名品牌的薯条上都被验出含致癌物质,这一信息造成了普遍的关心。那麼实际是什么原因呢?什么知名品牌薯条含致癌物质?下边我产生详细介绍。 好几家著名...

如何联系一名黑客(小学生如何成为一名黑客)

一、如何联系一名黑客(小学生如何成为一名黑客) 1、如何当一名黑客想要成为一名黑客至少要做到以下几点 爱折腾 黑客做的事情不像电影里那么有趣,事实上黑客很无聊。黑客需要无休止的找bug。 怎样自学成...