本文的業務基礎是在基於 nodejs 的 socket.io 的直播間聊天室(IM)應用來的。
項目中具體的 框架以下 express + mongodb + socket.io
在介紹 socket.io 以前,咱們有必要對 webSocket 進行根本的原理的理解。
複製代碼
一、什麼是 webSocket?
二、如何去用?
三、常用的場景?
四、須要注意的地方
好了,下面咱們就按照上面 提到的四點來進行分析。
複製代碼
官方文檔解讀: webSocketjavascript
這個是 MDN 的官方文檔。詳細的內容須要讀者本身仔細去閱讀了,筆者這裏只介紹 容易出錯的問題。
一、WebSockets 是一個能夠建立和服務器間進行雙向會話的高級技術。經過這個API你能夠向服務器發送消息並接受基於事件驅動的響應,這樣就不用向服務器輪詢獲取數據了。
固然這個只是說用來解決 不用向服務器輪詢獲取數據問題。 這麼來講的話其實仍是不太夠 ‘官方’。
非官方理解: B/S 結構的軟件項目中,客戶端經過 http、https 等方式得到服務器消息,可是默認的 http 協議只支持 請求響應模式,這種模式簡化了 web 服務器,減小服務器負擔,加快網站的響應速度。 可是不能知足 咱們實時消息推送,聊天室等功能,這個時候 websocket 這個本 做爲 unix 進程通訊機制 就被嫁接到了 應用程序間網絡通訊,從而就有了現在的 socket
複製代碼
WebSocket是HTML5開始提供的一種瀏覽器與服務器間進行全雙工通信的網絡技術。依靠這種技術能夠實現客戶端和服務器端的長鏈接,雙向實時通訊。
特色: 事件驅動、異步 使用 ws 或者 wss 協議的 socket、 實現真正意義上的 推送功能
這裏的 ws 和 wss 區別跟 http 和 https 的區別同樣(安全性)
缺點就是 兼容性(今年已經 2017年了,應該能夠不用考慮這個問題了)
複製代碼
官方文檔中回提供系列的 api 具體以下:
分類以下:
a) 鏈接類:
一、send() 向遠程服務器發送數據
二、close() 關閉該websocket連接
b) 監聽函數類:
一、onopen 當網絡鏈接創建時觸發該事件
二、onerror 當網絡發生錯誤時觸發該事件
三、onclose 當 websocket 被關閉時觸發該事件
四、onmessage 當 websocket 接收到服務器發來的消息的時觸發的事件,也是通訊中最重要的一個監聽事件。 其中 咱們能夠定義各種 onmessage 事件的 type 從而 擴展咱們的 onmessage 事件。
c) websocket還定義了一個readyState屬性:
一、CONNECTING(0) websocket正嘗試與服務器創建鏈接
二、OPEN(1) websocket與服務器已經創建鏈接
三、CLOSING(2) websocket正在關閉與服務器的鏈接
四、CLOSED(3) websocket已經關閉了與服務器的鏈接
複製代碼
服務端就像是一個分發中心, 可是首先都得經過 connect 建立鏈接 從而造成 ws 的長鏈接。
只要 長鏈接 鏈接成功,那麼接下來的事情就很好操做了, 好比在服務端 emit 觸發一個事件,那麼在 服務端就須要監聽 on 方法來監聽同一個事件,最後若是須要讓 當前房間(注: 這裏有個 單房間 和 多房間的概念,咱們在後面的介紹中會仔細的提到的)內的全部鏈接用戶都被通知到這則消息,那麼 在監聽到服務端觸發的消息的同時,再來觸發一個廣播給 客戶端, 這個時候只要是在當前 ws 鏈接線上的全部用戶都會被 emit 觸發到這個事件,從而實現了 廣播。
上面的這一長段話,可能暫時不太好理解,可是若是 親手來寫上這麼一個 demo 就會理解不少了。
複製代碼
socket.io 是這篇文章的主角,由於它對 webSocket 作了一個很是完善的封裝, 而且提出了 多房間 多命名空間的 概念,讓多聊天室同時存在再也不是一個問題,因此,下面就會詳細的來介紹下 socket.io 這個框架
複製代碼
socket.io 這個是官網php
咱們在官網中 能夠看到很是簡潔的 socket.io 的應用方法。
而且還展現了一個全世界通用的 IM (雖然這裏經常能夠看到 f**k xxx)
複製代碼
好了,下面就針對 這個 socket.io 再進行一個詳細的介紹前端
一、 Server api
二、 Client api
三、 Rooms and NameSpace
複製代碼
這要就針對這三個來進行介紹java
服務端初始化 io 對象
複製代碼
const io = require('socket.io')();
// or
const Server = require('socket.io');
const io = new Server();
複製代碼
這個時候就須要看 你的後臺 服務的語言, php java nodejs 等等
我是用的 nodejs 因此直接 使用 express or koa2 都可
而後建立 http-server 服務
複製代碼
const socket = require('socket.io');
var app = express()
var server = http.createServer(app)
io = socket(server)
io.on('connection', function(socket) {
// to do somethings
})
複製代碼
上面的這個步驟就能夠輕鬆的 經過 nodejs + express 建立了一個 socket 服務端的 服務了
複製代碼
上面的步驟中已經在 服務端進行了 一些列 的操做 ,這個時候就須要 在服務端 建立 鏈接
首先是 須要在 前端引用 這個 socket 文件
複製代碼
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io('http://localhost');
</script>
const io = require('socket.io-client');
// or with import syntax
import io from 'socket.io-client';
複製代碼
而後 建立 鏈接
複製代碼
const socket = io();
複製代碼
而後 觸發監聽 'connection'
複製代碼
io.on('connection', (socket) => {
let token = socket.handshake.query.token;
// ...
})
複製代碼
加入這個時候你在 服務端 打印 debug 若是順利 就能夠輕鬆 完成了第一個 socket 的連接啦~
複製代碼
最後這裏 介紹到的 rooms 和 namespace 的概念
在多房間 聊天室 中 佔據了很大的做用
其中 介紹下 rooms 的 概念 , 關於 namespace 相關能夠到 socket.io 官網中進行查看
複製代碼
// 廣播給當前房間除了本身之外的全部人
socket.broadcast.to(roomId).emit('msg', {
// take somethings
})
// 廣播給當前房間中本身
socket.emit('msg', {
// take somethings
})
// 廣播給當前房間的全部人
socket.to(roomId).emit('msg', {
// take somethings
})
複製代碼
而後再結合上面的 監聽 、 觸發 方法,完成一系列的需求任務。
複製代碼
恩,今天先到這裏,有什麼問題,能夠留言互相學習。 歡迎推薦~~~node
附上 github地址git