[socket.io中文文档]socket.io学习教程――深入了解

时间:2021-06-29  来源:redis  阅读:

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')returncb(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/')returncb(null,true)

 cb(null,false)

})

 

名称空间

名称空间用来对服务端/客户端的连接隔离,有些地方,也称呼名称空间(namespace)为通道(channel)。下面举例对其意义进行说明

我们需要实现一个协同应用,这个应用有两个功能:


    协同编辑: 多个用户可以同时编辑一个文档


    用socket.io实现这个应用,有如下几种形式

    1、完全独立: 协同编辑有一个独立服务edit.socket.test,消息系统一个独立服务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连接,即浪费浏览器允许的并发连接数,又更多消耗服务器资源。使用名称空间即能实现很好的隔离,又不会对资源造成浪费。

    默认名称空间

    socket.io实例化时自动绑定路径为/的名称空间

     

     代码如下

    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'

     

    中间件

    socket.io的名空间通过use注册中间件,中间件在客户端与服务端建立连接成功后,connet事件派发前调用一次。

    利用中间件数据校验

    io.use((socket, next) => { 

     if(socket.request.headers.cookie)returnnext()

     next(newError('Authentication error'))

    })

    利用中间件提取或转换数据io.use((socket, next) => { 
    getInfo(socket.request.query.id, (err, data) => { if (err) return next(err) socket.custom = data next() }) })

    与allowRequest对比

    allowRequest可以进行一些校验,提取,为什么还要需要中间件?

    与connection事件对比

    connection事件也传入socket,也可以进行数验,提取,为什么还要需要中间件?

      中间件直接支持多个异步流程嵌套,而allowRequest需要自己实现

      中间件成功后到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');

        

      // 发送消息到客户端

      socket.to().emit('hey','I just met you');

        

      // 发送应答消息

      socket.emit('question','do you think so?',function(answer) {});

      总结

      以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助


        消息: 用户间可以发送消息

        allowRequest传入的http.request实例,而中间件出入数据socket实例,socket实例包含request实例,且有更多信息

        中间件直接支持多个异步流程嵌套,而allowRequest需要自己实现

        >>>socket.io学习教程――基本应用

        >>>socket.io学习教程――基础部分

        [socket.io中文文档]socket.io学习教程――深入了解

        http://m.bbyears.com/shujuku/126755.html

        推荐访问:
相关阅读 猜你喜欢
本类排行 本类最新