一步一步学WebSocket (一) 初识WebSocket
众所周知,Http协议是无状态的,并且是基于Request/Response的方式与服务器进行交互,也就是我们常说的单工模式。但是随着互联网的发展,浏览器与服务端进行双向通信需求的增加,长轮询向服务器以获取最新数据并实现推送效果的方式已经越来越不能满足我们。Html5标准的制定,也为我们提供了浏览器与服务端的双工通信协议WebSocket。
WebSocket协议的格式为 "ws://IP:Port" 或者“wss://IP:Port"。其中wss表示进行加密传输的websocket协议。
WebSocket协议与传统的Socket协议一样,都需要进行“握手”。但是WebSocket的“握手”阶段是通过Http协议进行的,“握手”行为通过Request/Response的Header完成,只需要交换很少的数据,便可以创建基于TCP/IP协议的双工通道。下面我们来看一下Fiddler截取到的WebSocket握手请求
通过Fiddler我们可以看到,在握手请求时,客户端向服务端发送了一个Get请求,并且在请求的头中增加了这么几个Key
Origin:http://IP:Port 表示客户端的地址
Connection:Upgrade / Upgrade:WebSocket 表示本次请求是要进行WebSocket的握手动作
Sec-WebSocket-Version: 13 表示浏览器支持的WebSocket版本信息
Sec-WebSocket-Key: 这是一个由客户端随机生成的字符串
在服务器响应的握手信息中Sec-WebSocket-Accept:的值为服务器通过客户端Header的Sec-WebSocket-Key的值进行计算并加密的结果。
并且服务器的响应状态为101 表示服务器端已经理解了客户端的需求,并且客户端需要根据Upgrade中的协议类型,切换为新的协议来完成后续的通信。
这时候我们的TCP/IP双工通道就已经建立了,WebSocket协议就这么简单。
说完理论知识了,我们来看如何在浏览器中使用WebSocket协议。
最新的FireFox、Chrome、IE10及以上版本都已经支持了WebSocket协议。但是在使用它时,我们需要先检测浏览器是否支持WebSocket协议
WebSocket对象位于 window对象下。我们可以通过以下代码检测浏览器对WebSocket的支持
if("WebSocket" in window) if(window.WebSocket) if("MozWebSocket" in window) if(window.MozWebSocket)
如果我们的浏览器支持WebSocket 那么我们就可以创建WebSocket的实例了。
var ws=new WebSocket("ws://localhost:2012"); var ws=new MozWebSocket("ws://localhost:2012);
这里需要注意一下,当我们创建WebSocket的实例时,这个WebSocket实例就已经开始向服务器发起握手请求了,不需要我们手动打开连接。
WebSocket对象也很简单,我们会常用到它的4个回调方法 onopen onclose onerror onmessage。他们触发的实际分别为 握手完成并创建TCP/IP通道后,断开连接后,发生错误时,接收到服务端消息时。
另外我们还常常用到一个属性 readyState 用以检查连接状态,和一个函数 send() 向服务端发送数据。
下面我们来完成一个完整的浏览器使用WebSocket的例子,这里需要服务端也支持WebSocket协议
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WebSocket示例</title>
<script type="text/javascript">
var ws;//WebSocket对象
var wsUrl = "ws://localhost:2012";//支持WebSocket协议的服务器端地址 function connection() {
//判断该使用哪种WebSocket对象
if ("WebSocket" in window) {
ws = new WebSocket(wsUrl);
}
else if ("MozWebSocket" in window) {
ws = new MozWebSocket(wsUrl);
} else {
alert("当前浏览器不支持WebSocket"); } //注册各类回调
ws.onopen = function () {
alert("连接服务器成功");
} ws.onclose = function () {
alert("与服务器断开连接");
}
ws.onerror = function () {
alert("数据传输发生错误");
}
ws.onmessage = function (receiveMsg) {
alert(receiveMsg.data);
}
}
function sendMessage() {
//尝试向服务端发送消息 ws.send("Hello World"); } </script>
</head>
<body>
<input type="button" value="Connection" onclick="connection()" />
<input type="button" value="Send" onclick="sendMessage()" />
</body>
</html>
完整示例代码在这里下载 示例代码的服务端是基于.Net Framework 4.5用VS2012开发的 因为服务器WebSocket框架的.NET 4.0版本有问题……
下一篇文章我们会讲如何使用SuperWebSocket框架搭建我们自己的WebSocket服务器
一步一步学WebSocket (一) 初识WebSocket的更多相关文章
- 一步一步学ROP之linux_x64篇
一步一步学ROP之linux_x64篇 一.序 **ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防 ...
- 一步一步学ROP之linux_x86篇
一步一步学ROP之linux_x86篇 作者:蒸米@阿里聚安全 一.序 ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过 ...
- (转载)一步一步学Linq to sql系列文章
现在Linq to sql的资料还不是很多,本人水平有限,如果有错或者误导请指出,谢谢. 一步一步学Linq to sql(一):预备知识 一步一步学Linq to sql(二):DataContex ...
- 一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计
本帖最后由 xinxincaijq 于 2013-1-9 10:27 编辑 一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计 转自博客:http:// ...
- 一步一步学android控件(之十五) —— DegitalClock & AnalogClock
原本计划DigitalClock和AnalogClock单独各一篇来写,但是想想,两个控件的作用都一样,就和在一起写一篇了. DegitalClock和AnalogClock控件主要用于显示当前时间信 ...
- 一步一步学Remoting系列文章
转自:http://www.cnblogs.com/lovecherry/archive/2005/05/24/161437.html (原创)一步一步学Remoting之一:从简单开始(原创)一步一 ...
- 一步一步学android控件(之十六)—— CheckBox
根据使用场景不同,有时候使用系统默认的CheckBox样式就可以了,但是有时候就需要自定义CheckBox的样式.今天主要学习如何自定义CheckBox样式.在CheckBox状态改变时有时需要做一些 ...
- 一步一步学Python(2) 连接多台主机执行脚本
最近在客户现场,每日都需要巡检大量主机系统的备库信息.如果一台台执行,时间浪费的就太冤枉了. 参考同事之前写的一个python脚本,配合各主机上写好的shell检查脚本,实现一次操作得到所有巡检结果. ...
- 【DG】[三思笔记]一步一步学DataGuard
[DG][三思笔记]一步一步学DataGuard 它有无数个名字,有人叫它dg,有人叫它数据卫士,有人叫它data guard,在oracle的各项特性中它有着举足轻理的地位,它就是(掌声)..... ...
随机推荐
- mysql临时表的产生
sql执行会生成一个巨大的临时表,当内存放不下时,要全部copy 到磁盘,导致IO飙升,时间开销增大. 额外收获知识收藏如下: 临时表存储 MySQL临时表分为"内存临时表"和&q ...
- 自己写的基于bootstrap风格的弹框插件
自己写的一款基于bootstrap风格的弹框插件,暂时只有确认框.提示框.后续功能扩展.bug修改再更新. ;(function($){ //默认参数 var PARAMS; var DEFAULTP ...
- 解决Android SDK下载和更新失败的方法(Win系统) 和离线安装
http://jingyan.baidu.com/article/a3a3f811f370558da2eb8a94.html http://jingyan.baidu.com/article/636f ...
- Linux分区和挂载硬盘
分区: [root@code-svn ~]# fdisk /dev/sdb WARNING: DOS-compatible mode is deprecated. It's strongly reco ...
- cocos2dx day 1
原文:http://www.cocos2d-x.org/programmersguide/2/index.html 一.Basic Concepts 1.director 2.scene 2.1 sc ...
- APP开发和web开发的区别
1.web开发: 1.浏览器直接访问,协议是http,基本都是PC访问,也就是在家和办公场合,网络比较好. 2.web如果多个服务集成的话使用的是ESB来统一集成 2.APP开发 1.手机app客户端 ...
- openlayers
很久没有写东西了,最近突然想看看地图,就翻看了下,用了2-3周时间看看网页,学习做了下:先看做的效果:
- window7下使用vagrant打造lamp开发环境(二)
上一节我们基本把软件跟系统环境,以及连接虚拟机给配置好了,下面我们将要进行开发环境的搭建(lamp) 这里安装其实很简单,因为我们用的centos,所以很大一部分安装都是通过yum安装 关于yum的详 ...
- 学习总结——Selenium元素定位
读一本好书,不能读读就算了,做一下总结,变成自己的,以备查阅. 1. driver.findElement(By.id(<element ID>)) ID是独一无二的,使用 ...
- More Effective c++
指针和引用 引用对象必须存在,即不能引用空值,指针可以指向空值,引用必须初始化指向一个对象 指针可以改变指向的对象,引用不能改变所引用的对象 不改变指向对象使用引用,改变指向对象使用指针 重载[]时必 ...