最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

socket.io學(xué)習(xí)教程之深入學(xué)習(xí)篇(三)

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

前言

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

靜態(tài)文件

socket.io默認(rèn)情況下會(huì)通過(guò)socket.io-client包提供socket.io.min.js和socket.io.js.map下載

運(yùn)行實(shí)例app.js

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

app.listen(3000); 

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

我們可以改變這種行為

禁用socket.io.js下載

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

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

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

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

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

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

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

socket.io.js路徑可以改變,其默認(rèn)路徑為/socket.io。

實(shí)例化時(shí)傳參

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

調(diào)用函數(shù)path

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

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

安全策略

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

allowRequest

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

前端請(qǐng)求帶上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

可以對(duì)源進(jìn)行限制

1、實(shí)例化時(shí)限制源

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

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

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

origins(string) : 設(shè)置運(yùn)行的源

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

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

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

名稱空間

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

我們需要實(shí)現(xiàn)一個(gè)協(xié)同應(yīng)用,這個(gè)應(yīng)用有兩個(gè)功能:

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

用socket.io實(shí)現(xiàn)這個(gè)應(yīng)用,有如下幾種形式

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

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

2、名稱空間: 只運(yùn)行一個(gè)獨(dú)立服務(wù),通過(guò)名稱空間進(jìn)行隔離

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 => { 
 //編輯相關(guān)
})
messsageServer.on('connection', socket => { 
 /消息相關(guān)
})
let editSocket = io('socket.test/edit') 
let messageSocket = io('socket.test/message') 

3、事件名約定: 通過(guò)為事件名添加進(jìn)行隔離

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

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

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

 })
}

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

默認(rèn)名稱空間

socket.io實(shí)例化時(shí)自動(dòng)綁定路徑為/的名稱空間

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的名空間通過(guò)use注冊(cè)中間件,中間件在客戶端與服務(wù)端建立連接成功后,connet事件派發(fā)前調(diào)用一次。

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

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

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

與allowRequest對(duì)比

allowRequest可以進(jìn)行一些校驗(yàn),提取,為什么還要需要中間件?

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

與connection事件對(duì)比

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

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

聊天室

聊天室是對(duì)當(dāng)前連接的socket集合根據(jù)特定規(guī)則進(jìn)行歸組,方便群發(fā)消息??梢灶惐萉Q群的概率.

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

默認(rèn)聊天室

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

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

消息發(fā)送

應(yīng)答消息

普通消息不需要回應(yīng),而應(yīng)答消息提供了應(yīng)答機(jī)制

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

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

壓縮

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

volatile標(biāo)志

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

分類

// 客戶端發(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");

// 同時(shí)向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ā)送應(yīng)答消息
socket.emit('question', 'do you think so?', function (answer) {}); 

總結(jié)

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

相關(guān)文章

  • Cli Todo命令行todo工具使用演示

    Cli Todo命令行todo工具使用演示

    這篇文章主要為大家介紹了Cli Todo命令行todo工具使用演示示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Node.js數(shù)據(jù)流Stream之Duplex流和Transform流用法

    Node.js數(shù)據(jù)流Stream之Duplex流和Transform流用法

    這篇文章介紹了Node.js數(shù)據(jù)流Stream之Duplex流和Transform流的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Node.js實(shí)現(xiàn)文件上傳

    Node.js實(shí)現(xiàn)文件上傳

    這篇文章主要介紹了Node.js實(shí)現(xiàn)文件上傳的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Node.js包管理器Yarn的入門介紹與安裝

    Node.js包管理器Yarn的入門介紹與安裝

    大家都知道在yarn發(fā)布之前,所有Nodejs開(kāi)發(fā)者用的都是npm包管理工具,而npm工具存在挺多難以忍受的詬病,包括安裝速度慢、每次都要在線重新安裝等問(wèn)題,而yarn也是為了解決npm當(dāng)前所存在的問(wèn)題而出現(xiàn)的。本文給大家介紹了包管理器Yarn,以及安裝方法。下面來(lái)一起看看。
    2016-10-10
  • PHP和NodeJs開(kāi)發(fā)的應(yīng)用如何共用Session

    PHP和NodeJs開(kāi)發(fā)的應(yīng)用如何共用Session

    這篇文章主要介紹了PHP和NodeJs開(kāi)發(fā)的應(yīng)用如何共用Session的相關(guān)資料及思路,需要的朋友可以參考下
    2015-04-04
  • Node.js中的npm單獨(dú)與批量升級(jí)依賴包的方式超詳細(xì)講解

    Node.js中的npm單獨(dú)與批量升級(jí)依賴包的方式超詳細(xì)講解

    npm outdated僅檢查所有已安裝包的依賴關(guān)系,并將當(dāng)前版本遠(yuǎn)程倉(cāng)庫(kù)中的最新版本進(jìn)行對(duì)比,不會(huì)升級(jí),這篇文章主要介紹了Node.js中的npm單獨(dú)與批量升級(jí)依賴包的方式超詳細(xì)講解,需要的朋友可以參考下
    2024-02-02
  • nodejs微信開(kāi)發(fā)之自動(dòng)回復(fù)的實(shí)現(xiàn)

    nodejs微信開(kāi)發(fā)之自動(dòng)回復(fù)的實(shí)現(xiàn)

    這篇文章主要介紹了nodejs微信開(kāi)發(fā)之自動(dòng)回復(fù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Ubuntu安裝Node.js的2種方式

    Ubuntu安裝Node.js的2種方式

    這篇文章主要給大家介紹了關(guān)于Ubuntu安裝Node.js的2種方式,在Ubuntu系統(tǒng)上安裝Node.js和npm非常簡(jiǎn)單,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • 使用Nodejs獲取bing每日?qǐng)D片

    使用Nodejs獲取bing每日?qǐng)D片

    這篇文章主要為大家詳細(xì)介紹了如何使用Nodejs獲取bing每日?qǐng)D片,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有興趣的小伙伴可以學(xué)習(xí)一下
    2023-12-12
  • node.js中格式化數(shù)字增加千位符的幾種方法

    node.js中格式化數(shù)字增加千位符的幾種方法

    這篇文章主要介紹了node.js中格式化數(shù)字增加千位符的幾種方法,本文給出3種實(shí)現(xiàn)方法,并分別給出實(shí)例代碼,需要的朋友可以參考下
    2015-07-07

最新評(píng)論

玉田县| 二连浩特市| 梁平县| 丰县| 临泉县| 莱西市| 喀喇沁旗| 皮山县| 永嘉县| 泽库县| 资中县| 托克托县| 南靖县| 囊谦县| 奎屯市| 赞皇县| 汝州市| 崇州市| 武胜县| 乐昌市| 绵竹市| 通山县| 通山县| 田阳县| 沾化县| 惠水县| 化隆| 攀枝花市| 双峰县| 红桥区| 和林格尔县| 灵石县| 合山市| 高雄市| 开封县| 民勤县| 巴林左旗| 浮梁县| 开阳县| 寿宁县| 云浮市|