web 实时通信的方法总结
1、Web端即时通讯技术
即时通讯技术简单的说就是实现这样一种功能:服务器端可以即时地将数据的更新或变化反应到客户端,例如消息即时推送等功能都是通过这种技术实现的。
但是在Web中,由于浏览器的限制,实现即时通讯需要借助一些方法。这种限制出现的主要原因是,一般的Web通信都是浏览器先发送请求到服务器,服务器再进行响应完成数据的现实更新。
2、实现Web端即时通讯的方法
实现即时通讯主要有四种方式,它们分别是短轮询、长轮询(comet)、长连接(SSE)、WebSocket。
它们大体可以分为两类,一种是在HTTP基础上实现的,包括短轮询、comet和SSE;另一种不是在HTTP基础上实现是,即WebSocket。下面分别介绍一下这四种轮询方式,以及它们各自的优缺点。
(1)短轮询
短轮询的基本思路就是浏览器每隔一段时间向浏览器发送http请求,服务器端在收到请求后,不论是否有数据更新,都直接进行响应。这种方式实现的即时通信,本质上还是浏览器发送请求,服务器接受请求的一个过程,通过让客户端不断的进行请求,使得客户端能够模拟实时地收到服务器端的数据的变化。
这种方式的优点是比较简单,易于理解,实现起来也没有什么技术难点。缺点是显而易见的,这种方式由于需要不断的建立http连接,严重浪费了服务器端和客户端的资源。尤其是在客户端,距离来说,如果有数量级想对比较大的人同时位于基于短轮询的应用中,那么每一个用户的客户端都会疯狂的向服务器端发送http请求,而且不会间断。人数越多,服务器端压力越大,这是很不合理的。
因此短轮询不适用于那些同时在线用户数量比较大,并且很注重性能的Web应用。
(2)comet
comet指的是,当服务器收到客户端发来的请求后,不会直接进行响应,而是先将这个请求挂起,然后判断服务器端数据是否有更新。如果有更新,则进行响应,如果一直没有数据,则到达一定的时间限制(服务器端设置)后关闭连接。
长轮询和短轮询比起来,明显减少了很多不必要的http请求次数,相比之下节约了资源。长轮询的缺点在于,连接挂起也会导致资源的浪费。
(3)SSE
SSE是HTML5新增的功能,全称为Server-SentEvents。它可以允许服务推送数据到客户端。SSE在本质上就与之前的长轮询、短轮询不同,虽然都是基于http协议的,但是轮询需要客户端先发送请求。
而SSE最大的特点就是不需要客户端发送请求,可以实现只要服务器端数据有更新,就可以马上发送到客户端。
SSE的优势很明显,它不需要建立或保持大量的客户端发往服务器端的请求,节约了很多资源,提升应用性能。并且后面会介绍道,SSE的实现非常简单,并且不需要依赖其他插件。
(4)WebSocket
WebSocket是HTML5定义的一个新协议,与传统的http协议不同,该协议可以实现服务器与客户端之间全双工通信。
简单来说,首先需要在客户端和服务器端建立起一个连接,这部分需要http。连接一旦建立,客户端和服务器端就处于平等的地位,可以相互发送数据,不存在请求和响应的区别。
WebSocket的优点是实现了双向通信,缺点是服务器端的逻辑非常复杂。现在针对不同的后台语言有不同的插件可以使用。
3、四种Web即时通信技术比较
从兼容性角度考虑,短轮询>长轮询>长连接SSE>WebSocket
从性能方面考虑,WebSocket>长连接SSE>长轮询>短轮询
4、SSE
原理:SSE不需要依赖客户端向服务器发送请求,而是可以直接在服务器端有数据更新时进行发送到客户端,相比于轮询的“拉数据”,这种“推数据” 有着低延迟、高性能的优势。这种方法的服务器端非常简介,只要维护一个服务器和客户端之间的协议即可。前端使用EventSource对象。
服务器端需要提供的协议基本代码如下:
data:firstevent
data:secondevent
id:
event:myevent
data:thirdevent
id:
:thisisacomment
data:fourthevent
data:fourtheventcontinue
下面解释一下基本用法:
要定义各个事件,每一个事件之间使用一个换行符隔开。每个事件内部可以有多行,每一行都是type:value的形式。
type有以下几种选择:
(1)类型为空白,表示该行是注释,会在处理时被忽略。
(2)类型为data,表示该行包含的是数据。以data开头的行可以出现多次。所有这些行都是该事件的数据。
(3)类型为event,表示该行用来声明事件的类型。浏览器在收到数据时,会产生对应类型的事件。
(4)类型为id,表示该行用来声明事件的标识符。
(5)类型为retry,表示该行用来声明浏览器在连接断开之后进行再次连接之前的等待时间。
比如上面的第一个事件,只传输了一个数据,数据内容为firstevent。服务器端通过这个清单发送到客户端,就可以通过前端进行响应的处理,诸如读取新数据、更新界面等。
客户端需要在JavaScript中使用EventSource对象。
首先需要初始化一个EventSource对象,实例化的时候需要传入与其交互的服务器端的文件地址,如:
var es = new EventSource(“sse.php”);
接下来,可以对进行事件的监听。EventSource给出了三种标准事件,它们的名称和触发时机如下:
open 当成功与服务器建立连接时执行
message 当收到服务器发送的事件时执行
error 当出现错误时执行
和普通的事件一样,可以通过以下两种方法使用这些事件:
es.onmessage=function(e){};
es.addEventListener(“message”,function(e){});
实现:
服务器端代码(php):
<?php
header('Content-Type: text/event-stream'); //这是专门为sse设置的数据格式
$time = date('Y-m-d H:i:s');
//下面这些echo出来的东西就是上面说的服务器端和客户端之间的协议
echo 'retry: 3000'.PHP_EOL; //retry类型的数据,规定了浏览器在连接断开之后进行再次连接之前的等待时间
echo 'data: The server time is: '.$time.PHP_EOL.PHP_EOL;
?>
//注意必须要先设定content-type为text/event-stream,这是为SSE专门定义的数据传输格式。 //接下来通过php的echo输出协议,上面的代码输出的结果如下: //retry:3000 //data:Theservertimeis... //输出了一个事件,这个事件中分别定义了retry类型和data类型的行。
客户端代码:
<html>
<head>
<meta charset="UTF-8">
<title>basic SSE test</title>
</head>
<body>
<div id=”content”></div>
</body>
<script>
var es = new EventSource("sse.php");
es.addEventListener("message",function(e){
document.getElementById("content").innerHTML += "\n"+e.data;
});
</script>
</html>
5、WebSocket
原理:WebSocket的实现了一次连接,双方通信的功能。首先由客户端发出WebSocket请求,服务器端进行响应,实现类似TCP握手的动作。这个连接一旦建立起来,就保持在客户端和服务器之间,两者之间可以直接的进行数据的互相传送。服务器端的逻辑比较复杂,如果是java或者node开发,都有很多封装好的组件可以使用。
前端API:
(1)创建WebSocket对象
var ws = new WebSocket(“ws//localhost:8080”);
WebSocket是一个不同于HTTP的协议,其参数传递中的ws://前缀类似于http://,用于进行协议的声明。
(2)事件操作
WebSocket提供了四个事件操作,如下:
onmessage收到服务器响应时执行
onerroe 出现异常时执行
onopen 建立起连接时执行
onclose 断开连接时执行
web 实时通信的方法总结的更多相关文章
- Web实时通信之Socket.IO
前面两篇文章使用了Ajax long polling和WebSocket两种常用的Web实时通信方式构建了简单的聊天程序. 但是,由于浏览器的兼容问题,不是所有的环境都可以使用WebSocket这种比 ...
- 【转】Web实时通信之Socket.IO ,真正的兼容ie
前面两篇文章使用了Ajax long polling和WebSocket两种常用的Web实时通信方式构建了简单的聊天程序. 但是,由于浏览器的兼容问题,不是所有的环境都可以使用WebSocket这种比 ...
- 【Node/JavaScript】论一个低配版Web实时通信库是如何实现的( WebSocket篇)
引论 simple-socket是我写的一个"低配版"的Web实时通信工具(相对于Socket.io),在参考了相关源码和资料的基础上,实现了前后端实时互通的基本功能 选用了Web ...
- 【JavaScript】论一个低配版Web实时通信库是如何实现的之二( EventSource篇)
前情提要 「 话说上回说到!那WebSocket大侠,巧借http之内力,破了敌阵的双工鸳鸯锁,终于突出重围. 然而玄难未了,此时web森林中飞出一只银头红缨枪,划破夜色. "莫非!?&qu ...
- atitit. js 跨界面 页面 web cs 传值方法总结
atitit. js 跨界面 页面 web cs 传值方法总结 #--需求 js #---两个方法: 直接传跟跟间接传递... 1.直接传跟new form(param) web使用url方 ...
- OSX 10.8+下开启Web 共享 的方法
MENU Home Archives About SUBSCRIBE ☰MENU OSX 10.8+ Mountain Lion 下开启 Web Sharing(Web 共享)的方法 JUL 28, ...
- OSX 10.8+下开启Web 共享 的方法
MENU Home Archives About SUBSCRIBE ☰MENU OSX 10.8+ Mountain Lion 下开启 Web Sharing(Web 共享)的方法 JUL 28, ...
- Java Web工程搭建方法
搭建一个简单的Web工程主要是以下几步: 一.下载所需工具 ①java ②eclipse ③tomcat 注意:java与eclipse版本不匹配(32位或者64位),会导致eclipse启动时 ...
- 咏南中间件当作WEB SERVER使用方法
咏南中间件当作WEB SERVER使用方法 1)开启咏南中间件 2)浏览器打开http://localhost:5566/web?page=echo.html
随机推荐
- 不改源代码,修改服务器配置,解决全局Get中文乱码问题
- python opencv3 直线检测
git:https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 import numpy as np # 读入图像 ...
- Qt中文本编辑器实现语法高亮功能(Qscitinlla)
Scintilla是一个免费.跨平台.支持语法高亮的编辑控件.它完整支持源代码的编辑和调试,包括语法高亮.错误指示.代码完成(code completion)和调用提示(call tips).能包含标 ...
- Django配置参数可选总结
一.可选字段参数 null blank core db_index editable primary_key radio_admin unique True or False db_colum hel ...
- bzoj4399 魔法少女LJJ 线段树合并
只看题面绝对做不出系列.... 注意到\(c \leqslant 7\),因此不会有删边操作(那样例删边干嘛) 注意到\(2, 5\)操作十分的有趣,启示我们拿线段树合并来做 操作\(7\)很好处理 ...
- [BZOJ4592][SHOI2015]脑洞治疗仪(线段树)
线段树基础操作题,唯一需要思考下的是将区间的前k个0覆盖为1. 线段树上二分,先递归到左子树覆盖,回溯时返回还剩多少个0未被覆盖,在根据这个信息递归到右子树.注意特判k=0的情况. 要维护的信息有:区 ...
- [Arc079F] Namori Grundy
[Arc079F] Namori Grundy 题目大意: 一个有向弱联通环套树. 一个点的sg值等于出边连向点的sg值的mex. 试问是否有办法给每个点分配sg值? 试题分析 题目大意把一些难点跳过 ...
- bzoj 1563
对于很多决策单调性DP问题,我们很难(但不是不可以)证明其决策满足单调性,所以感觉很像时,可以打表看是否满足. 这道题的精度(?范围)很难搞,开始生怕溢出,看了hzwer的代码,才发现用long do ...
- Xcode 小技巧
1.手动添加 #warning ,在不确定的 bug.错误.待定代码处,手动添加 #warning 行,在编译时间提醒自己需要处理的地方. 2.由于 arrayWithObjects: 和 initW ...
- iOS 视频组件
公司最近要在项目里新增一个随手拍的功能,所以呢我在网上找了个比较不错的demo,顺便研究了下它的代码结构.感谢大神的分享,如有侵权,请告知哦!