【问题标题】:Whats the problem with the socketio connection?socketio连接有什么问题?
【发布时间】:2020-07-02 20:08:24
【问题描述】:

当我接收或发送数据到 socketio 连接时,我会在 1-3 分钟内在控制台中收到大量 http 请愿书(6k INSIDE LAGGING)。

我在后台使用node+express,在前台使用vue

后端:

app.js

mongoose.connect('mongodb://localhost/app',{useNewUrlParser:true,useFindAndModify:false})
    .then(result =>{
        const server = app.listen(3000)
        const io = require('./sockets/socket').init(server)
              io.on('connection', socket =>{
                //   console.log('client connected')
              })
        if(result){console.log('express & mongo running');
        }
    })
    .catch(error => console.log(error))

我创建了一个 io 实例以在路由上使用它

let io
module.exports = {
    init: httpServer => {
        io = require('socket.io')(httpServer)
        return io;
    },
    getIo:()=>{ 
        if(!io){
            throw new Error('socket io not initialized')
        }
        return io;
    }
}

然后,在路由上,根据逻辑,if,else选择什么类型的socket响应做

router.post('/post/voteup',checkAuthentication, async (req,res)=>{
    //some logic
    if(a.length <= 0){
     io.getIo().emit('xxx', {action:'cleanAll'})
    }
    else if(b.length <= 0){
     io.getIo().emit('xxx', {action:'cleanT',datoOne})
    }
    else{                   
     io.getIo().emit('xxx', {action:'cleanX',dataTwo,dataOne,selected})
    }
    res.json({ serverResponse:'success'})
})

在前面(组件)(用 beforeUpdate 生命周期钩子激活)

getData(){
    let socket = openSocket('http://localhost:3000')
        socket.on('xxx', data => {
        if(data.action === 'cleanX'){
            if(this.selected === data.selected){
                this.ddd = data.dataTwo
            }
            else if(!this.userTeamNickname){
                this.qqq= data.dataOne
            }
        }
        else if(data.action === 'cleanAll'){
            this.ddd= []
            this.qqq= []
        }
        else if(data.action === 'cleanT'){
            this.ddd= data.dataOne
        }
    })            
},

1.什么样的行为会产生这种错误? 2. 还有其他最有效的方法吗?

【问题讨论】:

  • 什么是客户端函数openSocket()
  • 是客户端与服务器建立的连接

标签: node.js express vue.js websocket socket.io


【解决方案1】:

看起来 socket.io 无法建立 webSocket 连接并且从未退出轮询。默认情况下,socket.io 连接以 http 轮询开始,在与服务器进行一些协商后,它会尝试建立 webSocket 连接。如果成功,它将停止轮询并仅使用 webSocket 连接。如果 webSocket 连接失败,它会继续进行轮询。

以下是一些可能发生的原因:

  1. 客户端和服务器中的 socket.io 版本不匹配。
  2. 您在客户端和服务器之间有一些基础设施(代理、防火墙、负载平衡器等)不允许 webSocket 连接通过。
  3. 您已将多个 socket.io 服务器处理程序附加到同一 Web 服务器。您不能这样做,因为当多个服务器处理程序尝试响应同一个客户端时,通信会变得非常混乱。

作为测试,您可以强制客户端仅使用 webSocket 连接(根本没有轮询启动)并查看连接是否失败:

let socket = io(yourURL, {transports: ["websocket"]})'
socket.on('connect', () => {console.log("connected"});
socket.on('connect_error', (e) => {console.log("connect error: ", e});
socket.on('connect_timeout', (e) => {console.log("connect timeout: ", e});

【讨论】:

  • hello @jfriend00 1. 两个客户端 (socksocket.io-client) - 服务器 (socket.io) 版本都是 2.3.0 2. 我没有使用像 nginx 之类的东西,只是表达注意:我会尝试{transports: ["websocket"] 注2:在路由内创建套接字是一种好习惯吗?
  • @AlexHunter - 我没有意识到您在路由内创建 socket.io 服务器。这将不起作用,因为您会将多个 socket.io 处理程序附加到同一服务器,并且会导致连接混乱。如果您这样做,那可能是您的问题的根源。
  • 您好,我添加了您刚刚告诉我的“传输 websocket”的方法,并且效果很好……但是正如我所说,这是一种好习惯吗?你能为此展示一个好的甚至是最佳实践吗?
  • @AlexHunter - 不指定 webSocket 传输的唯一原因是允许支持真正旧的浏览器。这可能意味着您在其他地方的配置有问题,但如果设置传输有效,那么您可能没问题。
  • 我想是的......但我真的需要以最好的方式创建这个组件,因为它会处理很多用户(请愿),所以在这种情况下我需要“最好的方式来code it”,你知道socketio有什么好的教程吗?
猜你喜欢
  • 2012-02-07
  • 2018-06-14
  • 1970-01-01
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
相关资源
最近更新 更多