Как получить доступ к идентификатору клиентского сокета из HTTP-запроса? - PullRequest
0 голосов
/ 27 мая 2020

Недавно я наткнулся на интересную проблему.

Цель состояла в том, чтобы создать связь между клиентом браузера и моим expressJs сервером через веб-сокеты, чтобы быстро показать изменения, сделанные на другом клиент. Также я использую стандартное http-соединение для связи с моей базой данных.

Проблема в том, что мне нужно сгенерировать отдельную ссылку для каждого пользователя (на основе созданного мной ie Cook), но на сервер действителен только последний. Таким образом, каждый человек, показывающий недействительную ссылку, должен увидеть что-то вроде Please refresh the page. Для этого я испустил событие linkExpired глобально, которое также пометило ссылку отправителя как истекшую.

Я не могу получить доступ к клиентскому сокету (что решило бы мою проблему), потому что я не хочу хранить их после установления соединения (например, как было предложено здесь ). На мой взгляд, это не изящное решение.

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 29 мая 2020

Через некоторое время я придумал другой подход. Возможно, после установления соединения будет достаточно создания cook ie, хранящей идентификатор клиентского сокета. Итак, я сделал это ... И я понял, что socket.io уже имеет повар ie, содержащий идентификатор сокета.

Единственное, что нужно сделать, это использовать cookie-parser с express:

const cookieParser = require('cookie-parser');
require('express')().use(cookieParser());

После этого у меня был доступ ко всем файлам cookie, передаваемым всем HTTP-запросам, что позволило мне фильтровать сокеты на основе идентификатора и избегать отправки события отправителю.

const io = require("socket.io").io;
Object.keys(io.sockets.sockets).forEach((_socketId) => {
  if (req.cookies.io !== _socketId) {
    io.to(_socketId).emit('linkExpired');
  }
});

Обратите внимание на фрагмент, где я использовал req.cookies.io в качестве идентификатора сокета. Я заметил, что socket.io использует cook ie named io для хранения текущего идентификатора клиентского сокета.

А на стороне клиента я мог добиться отображения баннера об истечении срока действия следующим образом:

import socketIOClient from "socket.io-client";
const io = socketIOClient(process.env.REACT_APP_URL);
io.on('linkExpired', () => {
  setLink('Refresh the page');
});

Также мне пришлось не забыть передать параметры методу fetch для отправки файлов cookie:

fetch(`${process.env.REACT_APP_URL}/api/main`, {
  credentials: 'include'
});

Я потратил на это слишком много времени, поэтому надеюсь, что кому-то это пригодится это объяснение.

...