>[success]总结:
1. websocket是h5独有的,是一个基于TCP协议,只需要一个握手动作,就通过js发送数据。状态码是1xx开头的,如101成功。
2. 服务端我使用的是纯php开发的框架:workerman。
3. 可参考我的“常见类库使用-》workerman”(参考之前千万要看完这篇文章,自己跑下代码试一下,这样你就会更明白)
<br />
# :-: websocket
WebSocket是HTML5开始提供的一种在<span style="color:red;">单个 TCP 连接上进行全双工通讯的协议</span>。
在WebSocket API中,浏览器和服务器<span style="color:red;">只需要做一个握手的动作</span>,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
浏览器<span style="color:red;">通过 JavaScript </span>向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
当你获取<span style="color:red;"> Web Socket 连接后</span>,你可以<span style="color:red;">通过 send() 方法来向服务器发送数据</span>,并<span style="color:red;">通过 onmessage 事件来接收服务器返回的数据</span>。
> Web套接字 - 定义
> Web套接字被定义为服务器和客户端之间的双向通信,这意味着双方同时进行通信和交换数据。
> Web套接字的<span style="color:red;">关键点</span>是真正的并发性和性能优化,从而产生更灵敏和更丰富的Web应用程序
# :-: 以下 API 用于创建 WebSocket 对象
```js
var Socket = new WebSocket(url, [protocol] ); #第一个参数,指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议。
```
### **网址(url)**
HTTP有自己的一组模式,如http和https。Web套接字协议也具有在其URL模式中定义的类似模式。
下图显示了令牌中的Web Socket URL。
![](https://box.kancloud.cn/346c460e8be82ddde70807d49f0fdadb_501x106.png)
以下是 WebSocket 对象的<span style="color:blue;">属性</span>。假定我们使用了以上代码创建了 Socket 对象:
![](https://box.kancloud.cn/740c4540b3a595a855ef3dc83893cd53_732x301.png)
以下是 WebSocket 对象的相关<span style="color:blue;">事件</span>。假定我们使用了以上代码创建了 Socket 对象:
![](https://box.kancloud.cn/63fad569ebbfc884eb15a9812ea252e7_731x199.png)
以下是 WebSocket 对象的相关<span style="color:blue;">方法</span>。假定我们使用了以上代码创建了 Socket 对象:
![](https://box.kancloud.cn/6a99d886cfc9fc577ac0479a75b2921c_731x108.png)
>[info]属性啥也不带;事件前,带on;方法后,带();
# :-: websocket的实例
WebSocket 协议本质上是一个<span style="color:red;">基于 TCP</span> 的协议。
为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,<span style="color:red;">包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端</span>,客户端和服务器端的 WebSocket <span style="color:red;">连接就建立</span>起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在<span style="color:red;">直到客户端或者服务器端的某一方主动的关闭连接</span>。
![](https://box.kancloud.cn/ba8706f73418b16a18e40283e6e69d56_1395x490.png)
## 1、代码可以参考这个卖书的网站:http://www.websocket.org/echo.html
也可以直接复制,粘贴到你自己的ide上
``` html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
<div id="output"></div>
<script>
var socket;
var url = "ws://echo.websocket.org/"; //指定连接的url。真实项目中这里填写服务器的ip或域名
var output;
//初始化
function init(){
output = document.getElementById('output');
testWebSocket();
}
function testWebSocket() {
socket = new WebSocket(url); //只需要做一个握手的动作,浏览器和服务器之间就形成了一条快速通道,就可以将数据互相传送了
//连接上服务端时触发
socket.onopen = function () {
writeToScreen('连接');
doSend("websocket rocks");
};
//服务端断开时触发
socket.onclose = function(){
writeToScreen('关闭');
};
//接收服务端发来的请求
socket.onmessage = function(evt){
writeToScreen('<span style="color: blue;">RESPONSE: '+ evt.data+'</span>');
socket.close();
};
//通信发生错误时触发
socket.onerror = function (evt) {
writeToScreen('<span style="color: red;">ERROR:</span> '+ evt.data);
};
}
//发送数据
function doSend(message){
writeToScreen('SENT:'+ message); //先显示
socket.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>
</body>
</html>
```
## 2、主要代码解释:
### 2.1、申请一个WebSocket对象
参数是需要连接的服务器端的地址,同http协议使用http://开头一样,<span style="color:red;">WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头</span>。
``` js
var wsUri ="ws://echo.websocket.org/";
websocket = new WebSocket(wsUri);
```
### 2.2、WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror
我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。
(1)当Browser和WebSocketServer连接成功后,会触发onopen消息;
``` js
websocket.onopen = function(evt) {};
```
(2)如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;
``` js
websocket.onerror = function(evt) { };
```
(3)当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;
``` js
websocket.onmessage = function(evt) { };
```
(4)当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。
``` js
websocket.onclose = function(evt) { };
```
### 2.3、通信协议
WebSocket与TCP、HTTP的关系WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。
WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,<span style="color:red;">WebSocket在建立握手连接时,数据是通过http协议传输的</span>,但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。
![](https://box.kancloud.cn/d79b568c64098a45f037c107bb214a73_536x229.png)
### 2.4、通讯协议详解
从下图可以明显的看到,分三个阶段:
1. 打开握手
2. 数据传递
3. 关闭握手
![](https://box.kancloud.cn/cb45dbabcf7cbf4264342217ebd3074d_544x524.png)
下图显示了WebSocket主要的三步 浏览器和 服务器端分别做了那些事情
![](https://box.kancloud.cn/c359d84badf60138ea72280794328c60_601x448.png)
### 2.5、WebSocket的优点
1. 服务器与客户端之间交换的标头信息很小,大概只有2字节;
2. 客户端与服务器都可以主动传送数据给对方;
3. <span style="color:red;">不用频率创建TCP请求及销毁请求</span>,减少网络带宽资源的占用,同时也节省服务器资源;
### 2.6、建立连接的握手
<span style="color:red;">当Web应用程序调用</span>new WebSocket(url)接口时,Browser就开始了与地址为url的WebServer<span style="color:red;">建立握手连接的过程</span>。
1. Browser与WebSocket服务器通过TCP三次握手建立连接,如果这个建立连接<span style="color:red;">失败</span>,那么<span style="color:red;">后面的过程就不会执行</span>,Web应用程序将收到错误消息通知。
2. 在TCP建立连接成功后,<span style="color:red;">Browser/UA通过</span>http协议<span style="color:red;">传送</span>WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。
3. WebSocket服务器<span style="color:red;">收到</span>Browser/UA发送来的握手请求后,<span style="color:red;">如果</span>数据包数据和格式<span style="color:red;">正确</span>,客户端和服务器端的协议版本号匹配等等,就<span style="color:red;">接受本次握手连接</span>,并给出相应的数据回复,同样回复的数据包也是采用http协议传输。
4. <span style="color:red;">Browser收到服务器回复的数据包</span>后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,<span style="color:red;">触发onopen消息</span>,此时Web开发者就可以在此时<span style="color:red;">通过send接口想服务器发送数据</span>。否则,握手连接失败,Web应用程序会收到onerror消息,并且能知道连接失败的原因。
这个<span style="color:red;">握手很像HTTP,但是实际上却不是</span>,它允许服务器以HTTP的方式解释一部分handshake的请求,然后切换为websocket
### 2.7、数据传输
- WebScoket协议中,数据以帧序列的形式传输。
- 考虑到数据安全性,客户端向服务器传输的数据帧必须进行掩码处理。服务器若接收到未经过掩码处理的数据帧,则必须主动关闭连接。
- 服务器向客户端传输的数据帧一定不能进行掩码处理。客户端若接收到经过掩码处理的数据帧,则必须主动关闭连接。
- 针对上情况,发现错误的一方可向对方发送close帧(<span style="color:red;">状态码是1002,表示协议错误</span>),以关闭连接。
- 关闭WebSocket(握手)
![](https://box.kancloud.cn/69ece4d8be40fc95d4363d160bb20d25_523x240.png)
- 杂谈
- 开发 & 维护的工作流程
- 新手如何看php手册 和 框架手册
- 开发 & 维护的不同点
- 从0到1,搭建新项目的工作流程
- 从1到N,维护的工作流程
- 优化流程
- 生成错误日志和慢日志的方法
- 查错思路
- 怎么快速接手一个项目
- 前端常用知识点
- javascript
- 自己封装的函数
- 处理数字
- 功能代码
- 动态添加图片
- 判断是手机端还是pc端
- javascript:;是什么意思?怎么用呢
- html & h5
- a标签中target设置为blank和_blank有什么区别?
- 乱码
- 提交方式:button标签 和 input
- 块元素
- 内联元素
- h5特有属性
- h5的localStorage【增、删、改、查】
- jquery
- 常用方法
- 功能代码
- 动态删除图片
- 一个按钮,切换2种状态
- 换肤
- 深入理解(function(){... })();
- json & xml
- json
- 语法速记
- json对象取值
- 字符串、对象、数组的区别
- xml
- [CDATA[%s]]的作用是什么
- 转义字符
- CDATA 想被xml解析的文本数据
- CDATA 不想被xml解析的文本数据
- 微信小程序
- 其他
- websocket
- 跨域
- css
- 行内 & 内连 & 外连 写法
- 优先级
- 更加精准的匹配
- 使用百分比如何生效
- php在html、js、jq中的的原生写法
- *php在html中的语法
- php在js中的语法
- php在jq中的语法
- 正则表达式
- php常用基础知识(思想为主)
- php为什么是“边编译边运行”
- 冒号、endif、endwhile、endfor使用
- 递归思想(速记法)
- cookie和session的理解
- php常用内置(系统)函数
- 常量
- 字符串
- 数组
- 日期时间
- 文件 & 目录
- 数学
- 程序执行
- 判断
- 选项和信息(修改配置文件的)
- 错误处理 & 日志记录
- 编码格式
- session
- IP相关
- 类 & 对象
- 性能
- 其他函数
- 魔术方法
- $_SERVER
- 变量处理
- php自己封装的一些函数
- 导入、导出、生成文件
- 数组
- 数字
- 字符串
- 其他
- 获取linux硬件信息
- 常见插件/类库使用
- 前端-框架/插件
- bootstrap 学习笔记
- layer 学习笔记
- layDate 学习笔记
- 百度ueditor1.4.4.3富文本编辑器
- quill富文本编辑器
- 百度ECharts图形报表
- webuploader上传图片
- 后端类库
- workerman 聊天室
- QRCODE 二维码
- redis
- seaslog 日志
- phpspider 爬虫
- Mailer 发送邮件
- simple_html_dom
- phpstorm使用
- 快捷键
- 连接mysql数据库
- 断点 + debug调试
- 运行内存不够
- wamp环境
- yii、laravel、tp、开发自己的php框架
- 看框架源码的思路
- tp5框架的使用
- 1、助手函数原理解析
- 开发自己的php框架
- 常用的开发思路 和 小功能实现代码
- 爬虫思路
- 功能点思路
- tp5判断是不是异地登录(简单版)
- 微信开发,反向代理
- 微信开发,关闭当前页面
- 消息队列的实现
- 页面静态化
- session串号
- 站内信设计思路
- web在线管理器
- 语言相关(开发有关)
- 接收json(text/xml)格式数据
- 原生文件上传(状态码)
- openssl扩展
- 打印对象 和 遍历对象
- 使用OB缓存的几个原则
- CLI模式执行php文件
- foreach时,添加元素 或 修改元素的值
- 功能点 代码实现
- 生成url目录树(没有pid)
- 多图上传(vue传base64)
- 下载文件,耗时算法
- 生成商品二维码
- 导出excel
- 搜索
- 阿里大鱼发短信
- 使用阿里云oss
- location.href跳转后,丢失用户的session
- “\r ” “\r\n” “\t”的区别
- php的配置文件详解
- 开启错误日志
- 开启慢日志
- 开启短标签
- 分析php-fpm.conf中的request_terminate_timeout参数