简体   繁体   中英

How to properly close websockets

I'm building a Chrome Extension that connects to websockets and retrieve data. I'm trying to build a way that the user select an option from popup.html and it changes to which websocket the connection will be made. This is working fine.

My issue is that after selecting an option, the new connection is made to that websocket but the previous one keeps returning data. I'd like to close that previous connection before opening a new one.

popup.js (on radiobutton change stores the new value)

$(function() {
        $("input:radio[name=exc]").change(function() {
            chrome.storage.local.set({'checked':this.value}, function() {
            });
        });
    });

update.js (receive new selected radiobutton, I'm trying to close the preivous websocket)

chrome.storage.onChanged.addListener(function(changes, namespace) {
    chrome.storage.local.get("checked", function(data) {
        if(data.checked == "foo") {
            var ws = new WebSocket('wss://api.foo.com/ws');
            ws.onopen = function() {
                ws.send(JSON.stringify({"event":"test", "channel":"test"}));
            };
            ws.onmessage = function(msg) {
                var price = response[7];
                if(hb != "hb" && typeof hb != 'undefined') {
                    price = price.toString();
                    chrome.extension.sendMessage(price);
                }
            };
            ws.close();
        }
        else if(data.checked == "bar") {
            var pusher = new Pusher('xxxxxxxxxxxxx');
            var tradesChannel = pusher.subscribe('test'),
            child = null;
            tradesChannel.bind('test', function (data) {
                var price = data.price;
                if(typeof data.price != 'undefined') {
                    price = price.toString();
                    chrome.extension.sendMessage(price);
                }
            });
            pusher.disconnect();
         }
    });
});

If I leave the code the way it is, I'm getting WebSocket connection to 'wss://api.foo.com/ws' failed: WebSocket is closed before the connection is established. and no data is received.

Your code as is currently makes no sense; you immediately call close / disconnect after setting a new service up.

Besides, you lose the reference to your push service, as it's stored in a local variable only. This needs to be stored as state somewhere - global state is easy, maybe you can engineer it better though.

A simple solution would look something like this:

var ws; // We need it later, can't be a local variable

/* ... */
    if(data.checked == "foo") {
        if(ws) { ws.close(); ws = null; }
        ws = new WebSocket('wss://api.foo.com/ws');
        ws.onopen = function() {
            ws.send(JSON.stringify({"event":"test", "channel":"test"}));
        };
        ws.onmessage = function(msg) {
            var price = response[7];
            if(hb != "hb" && typeof hb != 'undefined') {
                price = price.toString();
                chrome.extension.sendMessage(price);
            }
        };
        // Don't close the new one here
    }

There's a close() method in the official WebSocket MDN docs:

close() Closes the WebSocket connection or connection attempt, if any. If the connection is already CLOSED, this method does nothing.

void close(
  in optional unsigned short code,
  in optional DOMString reason
);

Also, make sure you're on the correct port. More from this SO post .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM