>[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。

以下是 WebSocket 對象的<span style="color:blue;">屬性</span>。假定我們使用了以上代碼創建了 Socket 對象:

以下是 WebSocket 對象的相關<span style="color:blue;">事件</span>。假定我們使用了以上代碼創建了 Socket 對象:

以下是 WebSocket 對象的相關<span style="color:blue;">方法</span>。假定我們使用了以上代碼創建了 Socket 對象:

>[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>。

## 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協議參與的。

### 2.4、通訊協議詳解
從下圖可以明顯的看到,分三個階段:
1. 打開握手
2. 數據傳遞
3. 關閉握手

下圖顯示了WebSocket主要的三步 瀏覽器和 服務器端分別做了那些事情

### 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(握手)

- 雜談
- 開發 & 維護的工作流程
- 新手如何看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參數