首页 > 解决方案 > 如何从 http 请求中访问客户端套接字 ID?

问题描述

最近我偶然发现了一个有趣的问题。

目标是通过 Web 套接字在浏览器客户端和我的 expressJs 服务器之间创建通信,以快速显示在另一个客户端上所做的更改。此外,我正在使用标准的 http 连接与我的数据库进行通信。

问题是我需要为每个用户生成一个单独的链接(基于我创建的他们的 cookie),但在服务器上只有最后一个是有效的。因此,每个显示无效链接的人都应该看到类似Please refresh the page. 为了实现这一点,我在linkExpired全球范围内发出了事件,该事件也将发件人的链接标记为已过期。

我无法访问客户端套接字(这将解决我的问题),因为我不想在建立连接后存储它们(例如这里提出的建议)。在我看来,这不是一个优雅的解决方案。

任何帮助,将不胜感激。

标签: javascriptnode.jsexpresscookiessocket.io

解决方案


一段时间后,我想出了一种不同的方法。也许在建立连接后创建一个存储客户端套接字 id 的 cookie 就足够了。所以我这样做了......而且我意识到socket.io已经有一个包含套接字ID的cookie。

唯一要做的就是cookie-parser与 express 一起使用:

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

之后,我可以访问传递给所有 http 请求的所有 cookie,这使我能够根据 id 过滤套接字并避免向发送者发送事件。

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

请注意我使用 areq.cookies.io作为套接字 id 的片段。我注意到socket.io正在使用名为的 cookieio来存储客户端套接字的当前 id。

在客户端,我可以实现显示关于过期的横幅,如下所示:

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'
});

我在这方面花了太多时间,所以我希望有人能从这个解释中受益。


推荐阅读