【问题标题】:Reconnecting a WebSocket without creating a new instance在不创建新实例的情况下重新连接 WebSocket
【发布时间】:2018-09-12 18:26:41
【问题描述】:

所以我创建了一个使用 WebSocket 到 Node.JS WebSocket 服务器的新 Web 应用程序。现在,Node 服务器完成了它需要做的一切并且完美地工作。我的问题在于浏览器的实现。

我查看了很多其他人在答案中给出的库,但我想看看他们是否是更好或更清洁的方法。

因此,在我的实例中,我基本上创建了一个对象,它包装了 WebSocket,然后通过调用 connect(url) 使用 setInterval 重新连接,这将创建另一个 WebSocket 实例。

我一直在研究连接和客户端,似乎如果连接关闭,比如服务器出现故障,或者发生了什么事情,看起来有时,在较长的一段时间内,WebSocket 连接会加倍,所以不是每个客户端 1 个连接,而是 2、3 或 4...?

我感觉这是因为我每次都在创建一个新的 WebSocket 实例?

代码如下:

// Main Function
function WSWrapper() {

    // Variables
    this.socket = null;
    this.enabled = false;
    this.retry = false;

    // Connect
    this.connect = function(address) {

        // Sets the address
        this.address = address;

        // Creates the websocket connection
        this.socket = new WebSocket(address);

        // On message event handler
        this.socket.onmessage = function(event) {

            // Do stuff here

        }

        this.socket.onopen = function(event) {

            // On connect, disable retry system
            window.ta.enabled = true;
            window.ta.retry = false;

        }

        this.socket.onclose = function(event) {

            // On close, enable retry system, disable bidding
            window.ta.enabled = false;
            window.ta.retry = true;
            window.ta.bidEnabled = false;

        }

        this.socket.onerror = function(event) {

            // Set variables off
            window.ta.enabled = false;
            window.ta.bidEnabled = false;
            window.ta.retry = true;

        }

        return true;
    }


    // Close Socket
    this.closeSocket = function() {

        // Shutdown websocket
        this.socket.close();
        return true;

    }

    // Send Message
    this.socketSend = function(content) {
        this.socket.send(content);
        return true;
    }

    // Retry System: Attempts to reconnect when a connection is dropped
    this.repeat = setInterval(function() {
        if (window.ta.enabled == false && window.ta.retry == true) {
            window.ta.connect(window.ta.address);
        }

    }, 2000);

}

window.ta = new WSWrapper();
window.ta.connect('wss://example.com');

我想出了一些想法和问题,任何答案都会很好。

  1. 有没有办法重新连接同一个套接字?像将重新打开连接的 .open(url) 函数?我查看了 chrome 控制台,浏览了 WebSocket 的原型,但我什么也没看到,所以我不这么认为,但很想被告知。

  2. 我可以通过使用一些获取信息的函数来解决这个问题吗,例如,我创建 WebSocket 实例,然后将所有请求传递给另一个函数来管理消息信息,然后当连接断开时,我可以以某种方式删除旧实例并重新创建一个新实例吗?

任何事情都会好的,因为我真的不确定,似乎每个人都制作了一个包装器(就像我正在做的那样),但是做的事情不同,所以最好的方法或首选的方法是什么,这不会导致多个套接字实例保持运行?如果我的代码有问题,请解释!

谢谢

【问题讨论】:

    标签: browser websocket reconnect


    【解决方案1】:

    只是对此的更新,我能够获取以下代码: https://github.com/websockets/ws/wiki/Websocket-client-implementation-for-auto-reconnect

    并修改它以在浏览器中为我工作。请看下面的代码,记住这是对上面的改编,所以我在代码中没有任何功劳。

    // Define WSClient instance
    window.WSClient = {
    
        // Default reconnect interval
        reconnectInterval: 5000,
    
        // Define whether it has ever reconnected
        reconnected: false,
    
        // Log messages
        debug: false,
    
        // Open the URL
        open: function(url) {
    
            // Define that
            var that = this;
    
            // Open the URL
            this.url = url;
    
            // Create underlying websocket instance
            this.instance = new WebSocket(this.url);
    
            // Setup the event handler for onopen
            this.instance.onopen = function (ev) {
    
                // If it has ever reconnected lets say that
                if (that.reconnected && that.debug) {
                    console.log('[WS]: Reconnected.');
                }
    
                // Run the open function
                that.onopen(ev);
            }
    
            // Setup the event handler for onmessage
            this.instance.onmessage = function(data, flags) {
                that.onmessage(data, flags);
            }
    
            // Setup the event handler for onclose
            this.instance.onclose = function(e) {
                switch (e){
    
                    // Normal closure
                    case 1000:
                        if (that.debug) {
                            console.log("[WS]: Closed");
                        }
                        break;
    
                    // Abnormal closure
                    default:
                        that.reconnect(e);
                        break;
                }
    
                // Run onclose event
                that.onclose(e);
            }
    
            // Setup the event handler for onerror
            this.instance.onerror = function(e) {
                switch (e.code){
    
                    // Try and reconnect
                    case 'ECONNREFUSED':
                        that.reconnect(e);
                        break;
    
                    // Otherwise run error
                    default:
                        that.onerror(e);
                        break;
                }
            }
        },
    
        // Setup send function
        sendRaw: function(data, option) {
            try {
                this.instance.send(data, option);
            } catch (e) {
                this.instance.emit('error', e);
            }
        },
    
        // Send the content
        send: function(content) {
            this.instance.send(content);
        },
    
        // Define the reconnection function
        reconnect: function(e) {
    
            // Define that
            var that = this;
    
            // Log reconnection
            if (that.debug) {
                console.log(`[WS]: Reconnecting in ${this.reconnectInterval / 1000} seconds.`);
            }
    
            // Set reconnect timeout
            setTimeout(function() {
    
                // Log reconnecting
                if (that.debug) {
                    console.log("[WS]: Reconnecting...");
                }
    
                // Define has reconnected
                that.reconnected = true;
    
                // Try and open the URL
                that.open(that.url);
    
            }, this.reconnectInterval);
        },
    }
    

    所以我在 Vue.JS 框架中这样使用它:

    <script type="text/javascript">
    
        // Define the websocket
        window.vm['socket_example'] = new Vue({
            el: '#socket_example',
            name: 'SocketExample',
            data: {},
            methods: {
    
                // On connection open
                socket_open: function(event) {
    
                    // Send get lots function
                    this.$socket.send('some_content_here');
    
                },
    
                // On connection close
                socket_close: function(event) {
    
                },
    
                // On connection error
                socket_error: function(error) {
    
                },
    
                // On connection message
                socket_message: function(event) {
    
                },
    
            },
    
            mounted: function() {
    
                // Setup WebSocket connection
                this.$socket = WSClient;
                this.$socket.debug = true;
                this.$socket.open('<?php echo $endpoint; ?>');
    
                // Setup websocket listeners
                this.$socket.onopen = this.socket_open;
                this.$socket.onclose = this.socket_close;
                this.$socket.onerror = this.socket_error;
                this.$socket.onmessage = this.socket_message;
    
            },
        });
    </script>
    

    无论如何,我希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2020-07-15
      • 2018-09-28
      • 1970-01-01
      • 1970-01-01
      • 2011-03-30
      • 2023-02-07
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      相关资源
      最近更新 更多