即时通讯Web端通信方式的演进

码影领航说
• 阅读 54

若干年前,天空一声巨响,ajax 闪亮登场。前端宝宝们如获至宝,已经表单提交神马的,真的太心累了。有了ajax之后,网页的性能可大幅提升,告别刷新,告别如水的流量。

不过,长江后浪推前浪,一代更比一代强。由于ajax被跨域问题限制着(请自行百度“JS跨域问题”),导致多服务器配置、云服务资源的存储没办法充分利用。

所以,业界想到另外一种方法:JSONP。JSONP实际上和ajax没有半点关系,唯一相同的就是都是异步执行,而且JSONP完美解决了CD(cross domain)问题。

科技就是第一生产力,web发展 so fast。以前追求就是静态网页,显示信息而已。 现在,正朝着web2.0,web app前进。 以前的单向交流已经不能满足需求了。 怎么办呢? 改呗。所以,紧接着SSE、WebSocket 诞生了。

即时通讯Web端通信方式的演进

以下是几个技术的讲解顺序:

ajax;

JSONP;

SSE;

websocket。

AJAX

相信这个应该不用过多的讲解了吧,差不多就4步:

创建xhr对象;

监听请求;

设置回调;

设置参数;

发送xhr;

获得数据执行回调。

这样差不多就完成了一个ajax的简单模型。当然,我们也可以使用jquery提供的$.ajax函数,只是他里面做了更多的兼容性和功能性。

JSONP

JSONP 就是 JSON with Padding... 我真的不知道这个名字的含义到时有什么卵用。 一开始在使用JSONP时,就是使用jquery的$.ajax函数就可以了。但这造成了一个很不好的impression。总是让我们以为,JSONP 和 ajax有什么关联似的。而事实上,他们两个是完全不同的机制。xhr原理大家已经很清楚了,就是完完全全的异步操作。但JSONP的原理是什么呢?

JSONP 其实是和< script> 标签 有很大的关系。JSONP最大的优势就是实现异步跨域的作用,他到底是怎么做到的呢? 其实,JSONP就是利用script的 src属性,实现跨域的功能。

上面的写法有点不符合前端风味。说明一下,processJSON其实就相当于一个回调函数而已。在script--src里面的内容我们来瞧一瞧。

这就是前端发送JSONP的全部.那应该怎么执行呢?或者说,返回的内容是什么呢? 很简单,根据jsoncallback里面指定的函数名:processJSON,在返回的js里面使用processJSON(data);来执行。即时通讯聊天软件app开发可以加蔚可云咨询

即时通讯Web端通信方式的演进

服务器端返回的js内容:

processJSON({

message:"I've already received"

});

然后,浏览器收到后,直接执行即可。

ok,上面基本上就可以完成一个简单的JSONP函数执行。 当然,express 4.x(express是Nodejs里著名的Web应用开发框架)里面也有相关的JSONP 操作,有兴趣的同学可以看一看。

then,我们可以模拟一下实在的JSONP请求。上面是直接将script写死在html内部,这样造成的结果可能会阻塞页面的加载。

上面就是一个精简版的JSONP了。 另外,也推荐使用jquery的getJSON和$.ajax进行请求。

先看一下jquery的getJSON:

$.getJSON("http://girls.hustonline.net?callback=?", function(result){

console.log(result);

});

这里,我们需要关注一下url里面中callback=?里的?的内涵。jquery使用自动生成数的方式,省去了我们给回调命名的困扰。 其实,最后?会被一串字符代替,比如:json23153123。这个就代表你的回到函数名。不过,还是推荐使用$.ajax,因为你一不小心就有可能忘掉最后的?。

这样,我们就可以利用jquery很简单的发送jsonp了。

SSE

ajax和JSONP 都是 client-fetch的操作。但是有时候,我们更需要服务器主动给我们发信息。比如,现在的APP应用完全可以实现服务器发送,然后Client再处理。而SSE就是帮助我们向web app靠近。SSE 全称就是 Server-Sent Events——中译 为 “服务器推送”。

他的技术并不是很难,和websocket不同,他依赖原生的HTTP,所以对于开发者来说更好理解。 比如在nodeJS,只要我不执行res.end(),并且一定时间持续发送信息的话,那么该连接就会持续打开(keep-alive)。其实通俗来说,就是一个长连接。

所以,以前我们通常使用ajax、iframe长轮询来代替他。但是这样有个缺点就是,可操控性弱、错误率高。 所以,正对于这点W3C觉得需要在客户端另外指定一个机制:能够保证服务器推送,实现连接的keep-alive,操作简单。在这样背景下SSE诞生了。

但SSE和AJAX具体的区别在什么地方呢?

数据类型不同:SSE 只能接受 type/event-stream 类型,AJAX 可以接受任意类型;

结束机制不同:虽然使用AJAX长轮询也可以实现这样的效果,但是服务器端(以nodeJS为例)必须在一定时间内执行res.end()才行。而SSE只需要执行res.write() 即可。

SSE主要就是创建一个EventSource对象,里面的参数就是发送的路由,不过目前还不支持CORS,所以也被限制在同源策略下。在返回的source里面包含了,需要处理的一切信息。SSE也是通过事件驱动的,如上面demo所述:这里SSE通常有一下几类重要的事件: |eventName|effect| |:---|:---| |open|当连接打开时触发| |message|当有数据发送时触发,在event对象内包含了相关数据| |error|当发生错误时触发|。

上面几个方法比较重要的还是message方法,message主要用来进行信息的接受,回调中的event 包含了返回的相关数据。event包含的内容 |property|effect| |:---|:---| |data|服务器端传回的数据| |origin|服务器端URL的域名部分,有protocol、hostname、port| |lastEventId| 用来指定当前数据的序号。主要用来断线重连时数据的有效性。

上面就是一个简单的demo,每一段数据我们称之为事件,每一个事件经过空行分隔。“:”前面是数据类型,后面是数据。

通常的类型有:

空类型: 表示注释,在处理是会默认被删除.比如:this is a comment.

event: 声明该事件类型,比如message.

data: 最重要的一个类型, 表示传输的数据。可以为string格式或者JSON格式. 比如:data: {"username": "bobby"}

id: 其实就是lastEventId. 用来表明该次事件在整个流中的序号

retry: 用来表明浏览器断开再次连接之前等待的事件(不常用)

其实上面最重要的两个字段就是data、id。所以,我们一般获取的话就可以使用 event.data和event.lastEventId。上文说道,每一段内容是通过换行实现的,那服务器端应该怎么实现,写入的操作呢?

同样,这里以nodeJS 为例:

res.write("id: "+ i + "\n");

res.write("data: "+ i + "\n\n");

通过使用'\n\n'进行两次换行操作,即产生空行即可。

使用自定义事件

服务器端不仅可以返回指定数据,还可以返回指定事件.不过默认情况下都是message事件, 但我们也可以指定事件. 比如

event: myevent

data: third event

id: 101

这里出发的就是 myevent事件。即这就是触发自定义事件的方式。在front-end 我们可以使用addEventListener 来进行监听。

varsource = newEventSource('/someEvents');

source.addEventListener('myevent', function(event){

//doSth

}, false);

服务端使用SSE

由于使用的是HTTP协议,所以对于服务端基本上没什么太大的改变。

Ok,这里有一个demo,大家可以打开控制台看一下。会发现:有一个连接一直处于Content-Download状态,该连接就是一个SSE。

兼容性

目前SSE,在市面上大受欢迎,不过总有一个SB,离经叛道:居然连微软的edge都不支持。偶尔去翻了一下,还在underConsideration。结果底下的评论基本都是xxxx,有空可以去看看,逼逼MS程序员。

WebSocket

websocket 不同于其他的HTTP协议,他是独立于HTTP存在的另外一种通信协议。比如,像这样的一个路径ws://websocket.example.com/,就是一个websocket 通信。通常的实时通信并不会传输大量的内容。所以,对于HTTP协议那种,进行连接时需要传递,cookie和request Headers来说,这种方式的通信协议会造成一定的时延(latency)。websocket通信协议就是在这样的背景下诞生了,他与SSE、ajax polling不同的是:支持双向通信。

可以说上面就是一个健全的websocket 通信了。和SSE一样,我们需要创建一个WebSocket对象,里面的参数指定连接的路由。而且他也是事件驱动的。常见的事件监听有:|event|effect| |:---|:---| |open|,当ws连接建立时触发| |message|当有信息到来时触发| |error|当连接发生错误时触发| |close|当连接断开时触发|。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
SSE技术详解:一种全新的HTML5服务器推送事件技术
前言一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(ServersentEvents)。关于这4种技术方式的优缺点,请参考《Web端即时通讯技术盘点:短轮询、Comet、Websocket
Wesley13 Wesley13
4年前
JAVA服务端配置允许跨域请求
CORS是一个W3C标准,全称是”跨域资源共享”(Crossoriginresourcesharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。1.加入CROS依赖的包<dependency<groupIdcom.thetransactionco
Easter79 Easter79
4年前
SpringBoot解决跨域问题
在开发前后端分离的项目时,常常会碰到跨域请求的问题。这是因为浏览器的安全性限制,不允许Ajax访问协议不同、域名不同、端口号不同的数据接口,否则会出报No'AccessControlAllowOrigin'headerispresentontherequestedresource错误。SpringBoot通过设置cors(跨源
Stella981 Stella981
4年前
Spring Web Reactive Ajax 跨域的坑
吐槽一下,在使用springcloudgateway作为网关时遇到的ajax跨域一坑爹的问题。springcloudgateway使用org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping进行路由匹配;而RoutePredicateHandler
Stella981 Stella981
4年前
Comet技术详解:基于HTTP长连接的Web端实时通信技术
前言一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(ServersentEvents)。关于这4种技术方式的优缺点,请参考《Web端即时通讯技术盘点:短轮询、Comet、Web
Wesley13 Wesley13
4年前
JavaEE从服务器端解决Ajax跨域问题
1、Ajax跨域简介  1、指的是浏览器不能执行其他网站的脚本。是浏览器施加的安全限制。js本身不跨域,使用form表单和iframe直接请求,是不会跨域的;  2、只要两个url的协议、域名、端口其中有一个不同,从其中一个url中使用ajax请求另一个url,则属于Ajax跨域;  3、ajax请求接口,只是不能进入回调函数,接口还是可以正常请
Stella981 Stella981
4年前
SpringBoot实现jsonp跨域通信
实现jsonp跨域通信实现基于jsonp的跨域通信方案原理浏览器对非同源ajax请求有限制,不允许发送跨域请求目前跨域解决方案有两种cros配置jsonp请求cros为新规范,通过一个head请求询问服务器是否允许跨域,若不允许则被拦截jso
Easter79 Easter79
4年前
SpringBoot实现jsonp跨域通信
实现jsonp跨域通信实现基于jsonp的跨域通信方案原理浏览器对非同源ajax请求有限制,不允许发送跨域请求目前跨域解决方案有两种cros配置jsonp请求cros为新规范,通过一个head请求询问服务器是否允许跨域,若不允许则被拦截jso
Wesley13 Wesley13
4年前
JSON和JSONP的区别,以及使用方法
(一)场景在拉京东城市选择的基础数据时候,遇到被服务器拒绝的情况,也就是ajax跨域问题(二)json和jsonp说的直白一点,在我们做ajax异步的一些功能的时候,一定会或多或少的遇到两个问题,(1、数据的交换。2、跨域问题)JSONP的最基本的原理是:动态添加一个<script标签,而script
Stella981 Stella981
4年前
Ajax跨域问题和解决
一般,在本地通过ajax访问其他服务器上的文件,会出现如下提示!(https://static.oschina.net/uploads/img/202006/07203858_Q9wh.png)AccesstoXMLHttpRequestat'http://courage.cqscrb.top/partTime/menu/getAllM
Wesley13 Wesley13
4年前
Java 通信
前言一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(ServersentEvents)。关于这4种技术方式的优缺点,请参考《Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE》。本文将专
码影领航说
码影领航说
Lv1
问君能有几多愁?恰似一江春水向东流。
文章
4
粉丝
0
获赞
0