VueJs разъем подключения не отключается и накапливается при каждом обновлении - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть express сервер с сервером socker -

const debug               = require("debug")("api:server");
const http                = require("http");
const {format, promisify} = require("util"),
      sockio              = require("socket.io");

const config = require("../config");
const server = require("../server");
const pjson  = require("../package.json");

const host   = config.get("host");
const port   = config.get("port");
const wsport = config.get("wsport");
const app    = http.createServer(server);

app.listen(port, host, () => {
    process.title = pjson.name + " " + pjson.version;
    process.title = format("%s %s listening on %s:%s", pjson.name, pjson.version, host, port);
});

let io = sockio.listen(app, {log: false});

io.on('connection', async function(socket) {
    debug('a user connected');

    const blocksChannel = "blockUpdated";

    config.subscriber.on('message', (channel, message) => {
        let blockWithTime = {
            latestBlockTime: new Date(),
            block: JSON.parse(message)
        };
        io.emit('block updated', blockWithTime);
    });

    config.subscriber.subscribe(blocksChannel, (error, count) => {
        if (error) {
            throw new Error(error);
        }
    });

    socket.on('disconnect', function() {
        debug('user disconnected');
    });
});

let stop = async function(msg) {
    process.exit();
};

process.on("uncaughtException", function(err) {
    debug(err.stack);
    debug("uncaughtException", err);
}).on("SIGINT", function() {
    stop("Received SIGINT Ctrl+C signal. Borlaug API service shutdown.");
}).on("SIGTERM", function() {
    stop("Received SIGTERM signal. Borlaug API service shutdown.");
}).on("exit", function() {
    stop("Borlaug API service shutdown.");
});

Приведенный выше код прослушивает издателя redis, и всякий раз, когда приходит новое сообщение, мы отправляем событие сокета для клиентов.

В моем приложении vue: -

<script>
    import io from 'socket.io-client';

    export default {
        name: "Home",
        data() {
            return {
                blocks: [],
                socket: io(process.env.VUE_APP_API_URL),
                latestBlockTime: ''
            };
        },
        mounted() {
            this.getLatestBlocks();
        },
        methods: {
            async getLatestBlocks() {
                this.socket.on('block updated', (data) => {
                    console.log("New Block Number : ", data.block.blockNumber);
                    this.blocks.unshift(data.block);
                    this.latestBlockTime = data['latestBlockTime'];
                })
            }
        }
    }
</script>

Приложение отлично работает при запуске. После каждого refre sh соединение не разрывается. В результате после n refre sh я добавляю n копий тех же данных в список.

Эти множественные соединения остаются открытыми, даже когда я открываю приложение из другой вкладки или другого браузера. Но в консоли сервера express я вижу, как клиент подключается и отключается.

api: сервер, к которому подключен пользователь + 8m
api: пользователь сервера отключен + 12s
api: к серверу, подключенный пользователь + 31s
api: пользователь сервера отключен + 22s

Я не понимаю, в чем причина проблемы. Какой правильный способ элегантно отсоединить сокетное соединение в браузере refre sh или закрыть? Я могу отключить сокетное соединение на хуке жизненного цикла beforeDestroy Vue, но это работает только при переходе на другой маршрут.

...