У меня есть 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, но это работает только при переходе на другой маршрут.