避坑指南——微信小程序 socket 请求 onOpen 事件监听不触发,报错只说"操作未完成"

895 阅读1分钟

问题表现

创建链接成功,但是 onOpen 不触发,打开链接失败,未给出具体报错信息

3.png

代码背景

  • 客户端代码

    // socket 简单封装
    class Socket {
      task = null
      socketReady = false
      messageQueue = []
    
      constructor(config) {
        if (config) {
          this.init(config)
        }
        return this
      }
    
      init(config) {
        this.createTask(config)
      }
    
      createTask({url, header}) {
        if (!url) {
          this.task = null
          return
        }
    
        this.task = wx.connectSocket({
          url: url,
          success(res) {
            console.log('Socket 创建成功')
          },
        })
    
        this.task.onOpen(result => {
          console.log('Socket 链接已打开')
          this.socketReady = true
          this.sendQueue()
        })
    
        this.task.onError(err => {
          console.log('Socket 链接报错', err)
          this.socketReady = false
        })
        this.task.onClose(err => {
          console.log('Socket 已关闭', err)
          this.socketReady = false
        })
      }
    
      sendQueue() {
        if (this.messageQueue.length > 0) {
          this.messageQueue.forEach(data => {
            this.send(data)
          })
          this.messageQueue = []
        }
      }
    
      send(data) {
        if (!this.socketReady || !this.task) {
          this.messageQueue.push(data)
          return
        }
    
        this.task.send({
          data: JSON.stringify(data),
          success: () => {
            console.log('socket send success')
          },
          fail: err => {
            console.log('socket send fail', err)
          },
        })
      }
    }
    
    export default Socket
    
    // 调用
    import Socket from "./utils/socket"    
    const socketTask = new Socket({
        url: 'wss://test.xxx.com/'
    });
    
    
  • nginx服务端配置

    nginx 服务器通过代理直接转发了 socket 请求

    配置参考 socket.io/zh-CN/docs/…

    # 节选
        location /socket.io/ {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
    
            proxy_pass http://localhost:3003/;
    
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    
    
  • socket 服务器

    直接使用 socket.io 启动独立服务器,监听在3003端口

    
    const {Server} = require('socket.io');
    const io = new Server( 3003, {
        transports: ['websocket'],
        cors: {
            origin: '*',
        },
    });
    
    io.on('connection', (socket) => {
    
    });
    
    

排查过程

  1. socket 服务器错误监听不触发,排查失败
  2. 微信小程序开发者工具未提供有价值报错信息,只提示 "操作未完成" ,太扯
  3. 使用socket.io客户端进行链接,功能正常,排除服务器配置问题
  4. 面向百度编程,类似问题内外网搜索,无
  5. 查阅微信小程序文档,吐槽下,相关内容太少
  6. 查阅 socket.io 文档,发现 nginx 配置的默认路径为 /socket.io/, 在小程序 socket 请求地址后加入该路径,终于恢复正常

总结

  1. 微信小程序内 socket url 不能省略默认路径 /socket.io/