账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    小程序API wx.connectSocket() 连接WebSocket错误
    54
    0

    console:WebSocket connection to 'wss://localhost:5757/api/tunnel' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED

    client

    this.socketTask = wx.connectSocket({
        url: 'wss://localhost:5757/api/tunnel',
    })

    server
    route

    // GET  用来响应请求信道地址的
    router.get('/tunnel', controllers.tunnel.get)
    // POST 用来处理信道传递过来的消息
    router.post('/tunnel', controllers.tunnel.post)

    controllers

    const { tunnel } = require('../qcloud')
    const debug = require('debug')('koa-weapp-demo')
    
    /**
     * 这里实现一个简单的聊天室
     * userMap 为 tunnelId 和 用户信息的映射
     * 实际使用请使用数据库存储
     */
    const userMap = {}
    
    // 保存 当前已连接的 WebSocket 信道ID列表
    const connectedTunnelIds = []
    
    /**
     * 调用 tunnel.broadcast() 进行广播
     * @param  {String} type    消息类型
     * @param  {String} content 消息内容
     */
    const $broadcast = (type, content) => {
        tunnel.broadcast(connectedTunnelIds, type, content)
            .then(result => {
                const invalidTunnelIds = result.data && result.data.invalidTunnelIds || []
    
                if (invalidTunnelIds.length) {
                    console.log('检测到无效的信道 IDs =>', invalidTunnelIds)
    
                    // 从 userMap 和 connectedTunnelIds 中将无效的信道记录移除
                    invalidTunnelIds.forEach(tunnelId => {
                        delete userMap[tunnelId]
    
                        const index = connectedTunnelIds.indexOf(tunnelId)
                        if (~index) {
                            connectedTunnelIds.splice(index, 1)
                        }
                    })
                }
            })
    }
    
    /**
     * 调用 TunnelService.closeTunnel() 关闭信道
     * @param  {String} tunnelId 信道ID
     */
    const $close = (tunnelId) => {
        tunnel.closeTunnel(tunnelId)
    }
    
    /**
     * 实现 onConnect 方法
     * 在客户端成功连接 WebSocket 信道服务之后会调用该方法,
     * 此时通知所有其它在线的用户当前总人数以及刚加入的用户是谁
     */
    function onConnect (tunnelId) {
        console.log(`[onConnect] =>`, { tunnelId })
    
        if (tunnelId in userMap) {
            connectedTunnelIds.push(tunnelId)
    
            $broadcast('people', {
                'total': connectedTunnelIds.length,
                'enter': userMap[tunnelId]
            })
        } else {
            console.log(`Unknown tunnelId(${tunnelId}) was connectd, close it`)
            $close(tunnelId)
        }
    }
    
    /**
     * 实现 onMessage 方法
     * 客户端推送消息到 WebSocket 信道服务器上后,会调用该方法,此时可以处理信道的消息。
     * 在本示例,我们处理 `speak` 类型的消息,该消息表示有用户发言。
     * 我们把这个发言的信息广播到所有在线的 WebSocket 信道上
     */
    function onMessage (tunnelId, type, content) {
        console.log(`[onMessage] =>`, { tunnelId, type, content })
    
        switch (type) {
            case 'speak':
                if (tunnelId in userMap) {
                    $broadcast('speak', {
                        'who': userMap[tunnelId],
                        'word': content.word
                    })
                } else {
                    $close(tunnelId)
                }
                break
    
            default:
                break
        }
    }
    
    /**
     * 实现 onClose 方法
     * 客户端关闭 WebSocket 信道或者被信道服务器判断为已断开后,
     * 会调用该方法,此时可以进行清理及通知操作
     */
    function onClose (tunnelId) {
        console.log(`[onClose] =>`, { tunnelId })
    
        if (!(tunnelId in userMap)) {
            console.log(`[onClose][Invalid TunnelId]=>`, tunnelId)
            $close(tunnelId)
            return
        }
    
        const leaveUser = userMap[tunnelId]
        delete userMap[tunnelId]
    
        const index = connectedTunnelIds.indexOf(tunnelId)
        if (~index) {
            connectedTunnelIds.splice(index, 1)
        }
    
        // 聊天室没有人了(即无信道ID)不再需要广播消息
        if (connectedTunnelIds.length > 0) {
            $broadcast('people', {
                'total': connectedTunnelIds.length,
                'leave': leaveUser
            })
        }
    }
    
    module.exports = {
        // 小程序请求 websocket 地址
        get: async ctx => {
            const data = await tunnel.getTunnelUrl(ctx.req)
            console.log(22222222222222222, data)
            const tunnelInfo = data.tunnel
    
            userMap[tunnelInfo.tunnelId] = data.userinfo
    
            ctx.state.data = tunnelInfo
        },
    
        // 信道将信息传输过来的时候
        post: async ctx => {
            const packet = await tunnel.onTunnelMessage(ctx.request.body)
    
            debug('Tunnel recive a package: %o', packet)
    
            switch (packet.type) {
                case 'connect':
                    onConnect(packet.tunnelId)
                    break
                case 'message':
                    onMessage(packet.tunnelId, packet.content.messageType, packet.content.messageContent)
                    break
                case 'close':
                    onClose(packet.tunnelId)
                    break
            }
        }
    
    }
    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 0
    • 孤傲何妨 普通会员 1楼
      502 Bad Gateway

      502 Bad Gateway


      nginx
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部