這篇文章更加深入的給大家介紹了socket.io的相關資料,之前已經介紹了socket.io的基本教程和應用,本文更為深入的來介紹下socket.io的使用,需要的朋友可以參考借鑒,下面來一起看看吧。
前言
socket.io提供了基於事件的即時雙向通訊,本文深入的介紹了socket.io,下面來看看詳細的內容吧。
靜態檔案
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: 實例化時傳入控制參數serveClient值false
let io = require('socket.io')(app, { serveClient: false })
方法2: 呼叫函數serverClient
let app = require('http').createServer() let io = require('socket.io')() io.serveClient(false) io.listen(app) // 或者io.attach(app)
如果在呼叫函數前服務已綁定http.Server
,該方法將不起作用
停用後再次訪問將提示{" code":0,"message":"Transport unknown"}
#修改靜態檔案路徑
socket. io.js路徑可以改變,其預設路徑為/socket.io。
實例化時傳參
let io = require('socket.io')(app, { path: '/io' })
呼叫函數path
let app = require('http').createServer() let io = require('socket.io')() io.path('/io') io.listen(app)
如果在呼叫函數前服務已綁定http.Server
,該方法將不起作用
安全性原則
socket.io提供了兩個安全性原則
# allowRequest
函數allowRequest有兩個參數,第一個參數為收到的握手包(http.request
)對象,作為判斷依據, 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根據token判斷是否繼續
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函數設定來源
#origins函數有兩種形式
origins(string)
: 設定運行的來源
##origins(string, fn (err, success)) : 透過函數判斷來源是否允許
io.origins('http://localhost:*') io.origins((origin, cb) => { if (origin === 'http://localhost:3000/') return cb(null, true) cb(null, false) })
#名稱空間
1、完全獨立: 協同編輯有一個獨立服務
edit.socket.test ,訊息系統一個獨立服務
message.socket.test
let editSocket = io('edit.socket.test') let messageSocket = io('message.socket.test')
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')
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 => { }) }
預設名稱空間
let app = require('http').createServer() let io = require('socket.io')(app) io.sockets // io.of('/').sockets io.emit // 代理io.of('/').emit, 类似函数有'to', 'in', 'use', 'send', 'write', 'clients', 'compress'
中間件
io.use((socket, next) => { if (socket.request.headers.cookie) return next() next(new Error('Authentication error')) })
io.use((socket, next) => { getInfo(socket.request .query.id, (err, data) => { if (err) return next(err) socket.custom = data next() }) })<br/>
與allowRequest對比
#與connection事件對比
中间件成功后到connection事件发送成功前,socket.io还做了一些工作,比如把socket实例添加到connected对象中,加入聊天室等。如果因为权限中断连接,在中间件中处理更省资源.
聊天室
聊天室是对当前连接的socket集合根据特定规则进行归组,方便群发消息。可以类比QQ群的概率.
socket.join('room name') //进入 socket.leave('room name') //退出
io.to('some room').emit('some event') // io.to与io.in同义,向某个聊天室的所有成员发送消息
默认聊天室
每个socket在连接成功后会自动创建一个默认个聊天室,这个聊天室的名字是当前socket的id,可以通过默认聊天室实现向特定用户发送消息
socket.on('say to someone', (id, msg) => { socket.broadcast.to(id).emit('my message', msg) })
消息发送
应答消息
普通消息不需要回应,而应答消息提供了应答机制
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)
启用压缩,调用后当前连接的所有数据在传递给客户端前都会进行压缩
volatile标志
socket.io在正常情况下对发送的消息进行追踪,确保消息发送成功,而设置volatile后发送消息,socket.io不会对消息追踪,消息可能丢失
分类
// 客户端发送消息 socket.emit('hello', 'can you hear me?', 1, 2, 'abc'); // 向所有连接的客户端(除了自己)发送消息 socket.broadcast.emit('broadcast', 'hello friends!'); // 向game聊天室发送消息,自己不算 socket.to('game').emit('nice game', "let's play a game"); // 同时向game1和game2聊天室发送消息,自己不算 socket.to('game1').to('game2').emit('nice game', "let's play a game (too)"); // 向game聊天室的所有人发送消息 io.in('game').emit('big-announcement', 'the game will start soon'); // 发送消息到<socketid>客户端 socket.to(<socketid>).emit('hey', 'I just met you'); // 发送应答消息 socket.emit('question', 'do you think so?', function (answer) {});
以上是node.js中socket.io學習教學介紹(三)的詳細內容。更多資訊請關注PHP中文網其他相關文章!