欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

socket.io學習教程之深入學習篇(三)

 更新時間:2017年04月29日 17:22:36   作者:sigoden  
這篇文章更加深入的給大家介紹了socket.io的相關資料,之前已經(jīng)介紹了socket.io的基本教程和應用,本文更為深入的來介紹下socket.io的使用,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

socket.io提供了基于事件的實時雙向通訊,本文深入的介紹了socket.io,下面來看看詳細的內(nèi)容吧。

靜態(tài)文件

socket.io默認情況下會通過socket.io-client包提供socket.io.min.js和socket.io.js.map下載

運行實例app.js

let app = require('http').createServer() 
let io = require('socket.io')(app)

app.listen(3000); 

瀏覽器訪問http://localhost:3000/socket.io/socket.io.js可以加載壓縮的源碼,訪問http://localhost:3000/socket.io/socket.io.js.map加載sourcemap

我們可以改變這種行為

禁用socket.io.js下載

方法1: 實例化時傳入控制參數(shù)serveClient值false

let io = require('socket.io')(app, { 
 serveClient: false
})

方法2: 調用函數(shù)serverClient

let app = require('http').createServer() 
let io = require('socket.io')() 
io.serveClient(false) 
io.listen(app) // 或者io.attach(app) 

如果在調用函數(shù)前服務已綁定http.Server,該方法將不起作用

禁用后再次訪問將提示{"code":0,"message":"Transport unknown"}

修改靜態(tài)文件路徑

socket.io.js路徑可以改變,其默認路徑為/socket.io。

實例化時傳參

let io = require('socket.io')(app, { 
 path: '/io'
})

調用函數(shù)path

let app = require('http').createServer() 
let io = require('socket.io')() 
io.path('/io') 
io.listen(app) 

如果在調用函數(shù)前服務已綁定http.Server,該方法將不起作用

安全策略

socket.io提供了兩種安全策略

allowRequest

函數(shù)allowRequest有兩個參數(shù),第一個參數(shù)為收到的握手包(http.request)對象,作為判斷依據(jù), success), err是錯誤對象,success為boolean, false表示阻止建立連接

前端請求帶上token

let socket = io('http://localhost:3000?token=abc') 
socket.on('connect', () => { 
 console.log('connect')
})
socket.on('connect_error', err => { 
 socket.disconnect()
 console.log('connect_error', err)
})

后端allowRequest根據(jù)token判斷是否繼續(xù)

let app = require('http').createServer() 
let io = require('socket.io')(app, { 
 allowRequest: (req, cb) => {
 if (req._query && req._query.token === 'abc') return cb(null, true)
 cb(null, false)
 }
});

origins

可以對源進行限制

1、實例化時限制源

let app = require('http').createServer() 
let io = require('socket.io')(app, { 
 origins: 'http://localhost:3000'
})

2、origins函數(shù)設置源

origins函數(shù)有兩種形式

origins(string) : 設置運行的源

origins(string, fn(err, success)) : 通過函數(shù)判斷源是否允許

io.origins('http://localhost:*')

io.origins((origin, cb) => { 
 if (origin === 'http://localhost:3000/') return cb(null, true)
 cb(null, false)
})

名稱空間

名稱空間用來對服務端/客戶端的連接隔離,有些地方,也稱呼名稱空間(namespace)為通道(channel)。下面舉例對其意義進行說明

我們需要實現(xiàn)一個協(xié)同應用,這個應用有兩個功能:

  • 協(xié)同編輯: 多個用戶可以同時編輯一個文檔
  • 消息: 用戶間可以發(fā)送消息

用socket.io實現(xiàn)這個應用,有如下幾種形式

1、完全獨立: 協(xié)同編輯有一個獨立服務edit.socket.test ,消息系統(tǒng)一個獨立服務message.socket.test

let editSocket = io('edit.socket.test') 
let messageSocket = io('message.socket.test') 

2、名稱空間: 只運行一個獨立服務,通過名稱空間進行隔離

let app = require('http').createServer() 
let io = require('socket.io')(app) 
let editServer = io.of('/edit') 
let messsageServer = io.of('/message') 
editServer.on('connection', socket => { 
 //編輯相關
})
messsageServer.on('connection', socket => { 
 /消息相關
})
let editSocket = io('socket.test/edit') 
let messageSocket = io('socket.test/message') 

3、事件名約定: 通過為事件名添加進行隔離

let app = require('http').createServer() 
let io = require('socket.io')(app)

io.on('connection', socket => { 
 //編輯相關
 io.emit('edit:test')
 io.on('edit:test', data => {

 })
 //消息相關
 io.emit('message:test')
 io.on('message:test', data => {

 })
}

通過事件名約定程序的侵入性太大,不利于拆分和重組,不推薦。 而完全獨立的模式需要使用兩個socket連接,即浪費瀏覽器允許的并發(fā)連接數(shù),又更多消耗服務器資源。使用名稱空間即能實現(xiàn)很好的隔離,又不會對資源造成浪費。

默認名稱空間

socket.io實例化時自動綁定路徑為/的名稱空間

let app = require('http').createServer() 
let io = require('socket.io')(app)

io.sockets // io.of('/').sockets 
io.emit // 代理io.of('/').emit, 類似函數(shù)有'to', 'in', 'use', 'send', 'write', 'clients', 'compress' 

中間件

socket.io的名空間通過use注冊中間件,中間件在客戶端與服務端建立連接成功后,connet事件派發(fā)前調用一次。

利用中間件數(shù)據(jù)校驗

io.use((socket, next) => { 
 if (socket.request.headers.cookie) return next()
 next(new Error('Authentication error'))
})

利用中間件提取或轉換數(shù)據(jù) io.use((socket, next) => {
getInfo(socket.request.query.id, (err, data) => { if (err) return next(err) socket.custom = data next() }) })

與allowRequest對比

allowRequest可以進行一些校驗,提取,為什么還要需要中間件?

  • allowRequest傳入的http.request實例,而中間件出入數(shù)據(jù)socket實例,socket實例包含request實例,且有更多信息
  • 中間件直接支持多個異步流程嵌套,而allowRequest需要自己實現(xiàn)

與connection事件對比

connection事件也傳入socket,也可以進行數(shù)驗,提取,為什么還要需要中間件?

  • 中間件直接支持多個異步流程嵌套,而allowRequest需要自己實現(xiàn)
  • 中間件成功后到connection事件發(fā)送成功前,socket.io還做了一些工作,比如把socket實例添加到connected對象中,加入聊天室等。如果因為權限中斷連接,在中間件中處理更省資源.

聊天室

聊天室是對當前連接的socket集合根據(jù)特定規(guī)則進行歸組,方便群發(fā)消息。可以類比QQ群的概率.

socket.join('room name') //進入 
socket.leave('room name') //退出 
io.to('some room').emit('some event') // io.to與io.in同義,向某個聊天室的所有成員發(fā)送消息

默認聊天室

每個socket在連接成功后會自動創(chuàng)建一個默認個聊天室,這個聊天室的名字是當前socket的id,可以通過默認聊天室實現(xiàn)向特定用戶發(fā)送消息

socket.on('say to someone', (id, msg) => { 
 socket.broadcast.to(id).emit('my message', msg)
})

消息發(fā)送

應答消息

普通消息不需要回應,而應答消息提供了應答機制

io.on('connection', socket => { 
 socket.emit('an event', { some: 'data' }) //普通消息

 socket.emit('ferret', 'tobi', function (data) { //應答消息
 console.log(data); // data will be 'woot'
 })
})
socket.on('ferret', (name, fn) => { 
 fn('woot')
})

壓縮

socket.compress(true)啟用壓縮,調用后當前連接的所有數(shù)據(jù)在傳遞給客戶端前都會進行壓縮

volatile標志

socket.io在正常情況下對發(fā)送的消息進行追蹤,確保消息發(fā)送成功,而設置volatile后發(fā)送消息,socket.io不會對消息追蹤,消息可能丟失

分類

// 客戶端發(fā)送消息
socket.emit('hello', 'can you hear me?', 1, 2, 'abc');

// 向所有連接的客戶端(除了自己)發(fā)送消息
socket.broadcast.emit('broadcast', 'hello friends!');

// 向game聊天室發(fā)送消息,自己不算
socket.to('game').emit('nice game', "let's play a game");

// 同時向game1和game2聊天室發(fā)送消息,自己不算
socket.to('game1').to('game2').emit('nice game', "let's play a game (too)");

// 向game聊天室的所有人發(fā)送消息
io.in('game').emit('big-announcement', 'the game will start soon');

// 發(fā)送消息到<socketid>客戶端
socket.to(<socketid>).emit('hey', 'I just met you');

// 發(fā)送應答消息
socket.emit('question', 'do you think so?', function (answer) {}); 

總結

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • Node.js完整實現(xiàn)博客系統(tǒng)詳解

    Node.js完整實現(xiàn)博客系統(tǒng)詳解

    這篇文章主要介紹了Node.js完整實現(xiàn)一個博客系統(tǒng)的流程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • 更新Node.js的四種方法小結

    更新Node.js的四種方法小結

    Node.js是一個開放源代碼的跨平臺JavaScript運行環(huán)境,它在不同的平臺上都得到了廣泛使用和支持,強大的生態(tài)系統(tǒng)、持續(xù)的更新和不斷改進的性能使得Node.js非常受歡迎,然而,更新Node.js仍然是一個必要的過程,本文給大家介紹一些有關如何更新Node.js的方法
    2023-11-11
  • Node.js創(chuàng)建Web、TCP服務器

    Node.js創(chuàng)建Web、TCP服務器

    這篇文章主要介紹了用Node.js創(chuàng)建Web服務器和TCP服務器的方法和處理技巧,需要的讀者們學習一下吧。
    2017-12-12
  • 基于promise.js實現(xiàn)nodejs的promises庫

    基于promise.js實現(xiàn)nodejs的promises庫

    promise是JavaScript實現(xiàn)優(yōu)雅編程的一個非常不錯的輕量級框架。該框架可以讓你從雜亂的多重異步回調代碼中解脫出來,并把精力集中到你的業(yè)務邏輯上。
    2014-07-07
  • 你一定會收藏的Nodejs代碼片段

    你一定會收藏的Nodejs代碼片段

    Nodejs值得收集的代碼片段,大家可以收藏起來,運用到之后的工作中,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 基于nodejs使用express創(chuàng)建web服務器的操作步驟

    基于nodejs使用express創(chuàng)建web服務器的操作步驟

    express實際上是對nodejs內(nèi)置http進行封裝后的第三方包,其中提供了快捷創(chuàng)建web服務器以及處理請求路由的方法,使我們可以更加方便快捷的實現(xiàn)一個web服務器項目,本文件給大家詳細介紹基于nodejs使用express?創(chuàng)建web服務器的操作步驟
    2023-07-07
  • node.js使用zlib模塊進行數(shù)據(jù)壓縮和解壓操作示例

    node.js使用zlib模塊進行數(shù)據(jù)壓縮和解壓操作示例

    這篇文章主要介紹了node.js使用zlib模塊進行數(shù)據(jù)壓縮和解壓操作,結合實例形式詳細分析了node.js基于zlib模塊創(chuàng)建數(shù)據(jù)流以及壓縮和解壓縮等相關操作技巧,需要的朋友可以參考下
    2020-02-02
  • 深入Node TCP模塊的理解

    深入Node TCP模塊的理解

    這篇文章主要介紹了深入Node TCP模塊的理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • koa2使用ejs和nunjucks作為模板引擎的使用

    koa2使用ejs和nunjucks作為模板引擎的使用

    這篇文章主要介紹了koa2使用ejs和nunjucks作為模板引擎的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • window系統(tǒng) nodejs安裝opencv環(huán)境配置圖文詳解

    window系統(tǒng) nodejs安裝opencv環(huán)境配置圖文詳解

    這篇文章主要介紹了window系統(tǒng) nodejs安裝opencv環(huán)境配置,結合圖文形式詳細分析了window環(huán)境下 nodejs安裝opencv的具體步驟、注意事項
    2023-04-04

最新評論