一个html5 WebSocket + JS的简单Echo例子,例子代码演示效果猛戳链接:websocket例子(打开页面,稍等一会)

使用一个文本编辑器,把下面代码复制保存在一个 websocket.html 文件中,然后只要在浏览器中打开它,页面就会使用 websocket 自动连接,发送一个消息,显示接受到的服务器响应,然后关闭连接。

<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript"type="text/javascript">
var wsUri ="ws://echo.websocket.org/";
var output; function init() {
output = document.getElementById("output");
testWebSocket();
} function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onclose = function(evt) {
onClose(evt)
};
websocket.onmessage = function(evt) {
onMessage(evt)
};
websocket.onerror = function(evt) {
onError(evt)
};
} function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
} function onClose(evt) {
writeToScreen("DISCONNECTED");
} function onMessage(evt) {
writeToScreen('<span style="color: blue;">RESPONSE: '+ evt.data+'</span>');
websocket.close();
} function onError(evt) {
writeToScreen('<span style="color: red;">ERROR:</span> '+ evt.data);
} function doSend(message) {
writeToScreen("SENT: " + message);
websocket.send(message);
} function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
} window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
</html>

主要代码解读:

申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。。

var wsUri ="ws://echo.websocket.org/";
websocket = new WebSocket(wsUri);

WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror,

我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。

当Browser和WebSocketServer连接成功后,会触发onopen消息;

websocket.onopen = function(evt) {
};

如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;

websocket.onerror = function(evt) {
};

当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;

websocket.onmessage = function(evt) {
};

当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。

websocket.onclose = function(evt) {
};

WebSocket与TCP、HTTP的关系WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。

WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,WebSocket在建立握手连接时,数据是通过http协议传输的,但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。

推荐另外一篇node.js+websocket文章

WebSocket通讯详细解读:

从下图可以明显的看到,分三个阶段:

  1. 打开握手
  2. 数据传递
  3. 关闭握手

下图显示了WebSocket主要的三步 浏览器和 服务器端分别做了那些事情。

    

WebSocket的优点

a)、服务器与客户端之间交换的标头信息很小,大概只有2字节;

b)、客户端与服务器都可以主动传送数据给对方;

c)、不用频率创建TCP请求及销毁请求,减少网络带宽资源的占用,同时也节省服务器资源;

建立连接的握手

当Web应用程序调用new WebSocket(url)接口时,Browser就开始了与地址为url的WebServer建立握手连接的过程。

1. Browser与WebSocket服务器通过TCP三次握手建立连接,如果这个建立连接失败,那么后面的过程就不会执行,Web应用程序将收到错误消息通知。

2. 在TCP建立连接成功后,Browser/UA通过http协议传送WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。

3. WebSocket服务器收到Browser/UA发送来的握手请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手连接,并给出相应的数据回复,同样回复的数据包也是采用http协议传输。

4. Browser收到服务器回复的数据包后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,触发onopen消息,此时Web开发者就可以在此时通过send接口想服务器发送数据。否则,握手连接失败,Web应用程序会收到onerror消息,并且能知道连接失败的原因。

这个握手很像HTTP,但是实际上却不是,它允许服务器以HTTP的方式解释一部分handshake的请求,然后切换为websocket

数据传输

WebScoket协议中,数据以帧序列的形式传输。

考虑到数据安全性,客户端向服务器传输的数据帧必须进行掩码处理。服务器若接收到未经过掩码处理的数据帧,则必须主动关闭连接。

服务器向客户端传输的数据帧一定不能进行掩码处理。客户端若接收到经过掩码处理的数据帧,则必须主动关闭连接。

针对上情况,发现错误的一方可向对方发送close帧(状态码是1002,表示协议错误),以关闭连接。

关闭WebSocket(握手)


使用Wireshark监控到的上面WebSocket例子的数据。

GET / HTTP/1.1

  Upgrade: websocket

  Connection: Upgrade

  Host: echo.websocket.org

  Origin: null

  Pragma: no-cache

  Cache-Control: no-cache

  Sec-WebSocket-Key: Qcgtb1RJ6HceeTRLPFux/A==

  Sec-WebSocket-Version: 13

  Sec-WebSocket-Extensions: x-webkit-deflate-frame

  Cookie: __utma=9925811.951031439.1365242028.1365980711.1366068689.5; __utmc=9925811; __utmz=9925811.1365242028.1.1.utmcsr=websocket.org|utmccn=(referral)|utmcmd=referral|utmcct=/

  HTTP/1.1 101 Web Socket Protocol Handshake

  Upgrade: WebSocket

  Connection: Upgrade

  Sec-WebSocket-Accept: 84Qpane33QhxOmcz8bGkFdE1AHk=

  Server: Kaazing Gateway

  Date: Tue, 16 Apr 2013 09:51:25 GMT

  Access-Control-Allow-Origin: null

  Access-Control-Allow-Credentials: true

  Access-Control-Allow-Headers: content-type

  Access-Control-Allow-Headers: authorization

  Access-Control-Allow-Headers: x-websocket-extensions

  Access-Control-Allow-Headers: x-websocket-version

  Access-Control-Allow-Headers: x-websocket-protocol

  ..a[

  J6>h..8a/.{x%.0y..WebSocket rocks..i.....

Websocket -- JS的前端页面的更多相关文章

  1. 一个基于React整套技术栈+Node.js的前端页面制作工具

    pagemaker是一个前端页面制作工具,方便产品,运营和视觉的同学迅速开发简单的前端页面,从而可以解放前端同学的工作量.此项目创意来自网易乐得内部项目nfop中的pagemaker项目.原来项目的前 ...

  2. 使用pdf.js实现前端页面预览pdf文档,解决了跨域请求

    pdf.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,,一个负责API解析,一个负责核心解析 官网地址:http://mozilla.github.io/pdf.js/ 下 ...

  3. Python之路-(js正则表达式、前端页面的模板套用、Django基础)

    js正则表达式 前端页面的模板套用 Django基础 js正则表达式: 1.定义正则表达式 /.../  用于定义正则表达式 /.../g 表示全局匹配 /.../i 表示不区分大小写 /.../m ...

  4. websocket实现数据库更新时前端页面实时刷新

    websocket实现数据库更新时前端页面实时刷新 javaweb 目录(?)[+] userjsp ManagerServletjava 如题,实现以上功能,我知道主要有两大种思路: 轮询:轮询的原 ...

  5. base64编码后的pdf文件前端页面展示--pdf.js的应用

    最近在整理项目中用到的插件或者使用心得,感觉还是写成博客,能加深新一层的理解. 我先说一下我的需求:由于java后台编译的文件流在手机端加载速度太慢,所以想着可以在前端解析,放在页面展示给用户. 所以 ...

  6. 前端页面js与flash交互——js获取flash对象,并传递参数

    背景介绍: 最近在搞一个项目,涉及到图片选取,裁剪,上传等,由于浏览器安全性问题,js无法获取到<input type="file">中选取的文件路径,而且对照片的裁剪 ...

  7. js实现前端分页页码管理

    用JS实现前端分页页码管理,可以很美观的区分页码显示(这也是参考大多数网站的分页页码展示),能够有很好的用户体验,这也是有业务需要就写了一下,还是新手,经验不足,欢迎指出批评! 首先先看效果图: 这是 ...

  8. web前端页面性能优化

    影响用户访问的最大部分是前端的页面.网站的划分一般为二:前端和后台.我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发表评论等等.而前端呢?其实应该是属于功能的表现. 而我 ...

  9. 使用JS实现前端缓存

    在前端浏览器中,有些数据(比如数据字典中的数据),可以在第一次请求的时候全部拿过来保存在js对象中,以后需要的时候就不用每次都去请求服务器了.对于那些大量使用数据字典来填充下拉框的页面,这种方法可以极 ...

随机推荐

  1. Noip2018 考前准备

    目录 基础算法 二分 模拟(未补) 高精(未学习) 搜索(未补) 排序 图论 树的直径 树的重心 最短路算法 Spfa Dijkstra Floyd 最小生成树 kruskal 数论 线性筛 线性筛素 ...

  2. sql server存储过程修改,存储到mysql笔记

    由于有些项目要迁移到mysql上,数据迁移用MySQLWorkbench就能很好的迁移,最难的是存储过程之类的. 下面是sql server存储过程和mysql存储过程的转化: SQL SERVER: ...

  3. (52)zabbix_sender提交item数据

    zabbix_sender是什么?有什么作用 zabbix获取key值有超时时间,如果自定义的key脚本一般需要执行很长时间,这根本没法去做监控,那怎么办呢?使用zabbix监控类型zabbix tr ...

  4. sql 表连接的3种类型

    内连接  inner join (join) 交叉连接  cross join  笛卡尔积 效率低 外连接  outer join  (left join ,right join ,full join ...

  5. HashMap图解

    HashMap的数据结构和put.get.resize等操作的图解,看图轻松掌握HashMap (目前还不包括红黑树相关的部分) HashMap数据结构如下图 HashMap之put操作如下图 Has ...

  6. STM32中如何对printf函数重定向

    通过USART1向计算机的串口调试助手打印数据,或者接收计算机串口调试助手的数据,接下来我们现STM32工程上的printf()函数,方便用于程序开发中调试信息的打印. 方法一:使用MicroLIB库 ...

  7. unittest断言方法的使用

    unittest框架的TestCase类提供以下方法用于测试结果的判断 方法 检查 版本 assertEqual(a, b) a ==b   assertNotEqual(a, b) a !=b   ...

  8. Android DialogFragment全屏

     在onCreate里面写入代码: @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(saved ...

  9. shit layui & bugs

    shit layui & bugs use is not useful at all! http://www.layui.com/demo/form.html layui.use([" ...

  10. Mahout0.9安装与配置(完全分布式模式下运行)

    安装Mahout之前,一定要把hadoop装好,hadoop的安装方法可以参考我的前一篇随笔,我安装的是hadoop2.7.0,具体方法在此不做介绍. 1.首先下载相应版本的Mahout: axel ...