首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用唯一id分配WebSocket和net.Socket

用唯一id分配WebSocket和net.Socket
EN

Stack Overflow用户
提问于 2019-03-07 09:59:56
回答 1查看 3.2K关注 0票数 4

我希望为Websockets和net.Sockets分配唯一标识符,因此当接收到消息时,客户端将通过附加到套接字的标识符进行标识。

以前的研究:

对于Websocket:

根据的要求,需要:

代码语言:javascript
复制
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws) => {
   ws.id = uuid.v4(); // This is the relevant line of code
   ws.on('message', (msg: string) => {
   ...
   }
});

对于net.Socket:

同样,根据的说法,需要做以下几点:

代码语言:javascript
复制
var server = net.createServer();

server.on('connection', function(conn) {
    conn.id = uuid.v4(); // This is the relevant line of code
    conn.on('data', function(data) {
    ...
    });
});

问题

在编译过程中,类型'WebSocket‘或'Socket’上不存在“属性'id‘”错误。解释了原因。

可选解决方案#1:强制转换为任意

更新的net.Socket代码将是:

代码语言:javascript
复制
var server = net.createServer();

server.on('connection', function(conn) {
    (conn as any).id = uuid.v4();
    conn.on('data', function(data) {
        console.log('Session id:' + (conn as any).id);
    });
});

问题是:在我看来,这似乎不是很好的练习。除了目前的预感之外,我没有其他的理由参考。

可选解决方案#2:使用局部变量似乎是更好的选项

更新的net.Socket代码将是:

代码语言:javascript
复制
var server = net.createServer();

server.on('connection', function(conn) {
    const id: string = uuid.v4();
    conn.on('data', function(data) {
        console.log('Session id:' + id);
    });
});

经过一些经历,它似乎运转正常。

So -问题:

  1. 可选解决方案#2中的:它是否保证id变量在此范围内总是可用的?换句话说:这个解决方案有效吗?对于net.Socket和Websocket?还是我错过了什么?
  2. 一般情况下的():是否有可以替代的附加标识符(可能内置于WebSocket和net.Socket中的标识符)?

打字本版本: 3.2.4。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-09 14:31:32

我不知道这个领域已经存在。

如果您可以像在选项2中那样将套接字id保存在局部变量中,我就会这样做。I通常倾向于避免将任意字段添加到对象中。但是,有时您希望整个应用程序能够访问附加的数据,而在这些情况下,使用局部变量的将无法工作。

添加自定义字段

您可以向项目中添加一个包含以下内容的文件,而不是对any使用类型断言:

代码语言:javascript
复制
declare module "net" {
    interface Socket {
        id: string;
    }
}

这将增强net.Socket接口,以添加一个id字段,该字段是一个字符串。这比类型断言要整洁一些,因为类型断言将允许输入(例如,(conn as any).ids**).** 使用您的代码,删除类型断言,并将上述内容添加到包含代码的.ts文件旁边的一个名为externals.d.ts的文件中。tsc停止了对球场的抱怨。请注意,您不需要导入此文件或以任何方式引用它。您必须有一个tsconfig.json,它与您的其他源代码一起收集它。默认情况下,由于.d.ts扩展,它将被选中。

在过去,我使用类型断言和接口增强将任意字段添加到DOM节点中,并且工作得很好。但是,当我这样做时,我使用了非常单数的字段名,这意味着与其他想要添加自己字段的库发生冲突的可能性很低。您的字段名是id。我担心与其他库的名称冲突,这些库决定要跟踪套接字,并将自己的id 字段添加到套接字.中。

使用WeakMap

还有另一种方法你可以用。您可以设置一个将套接字与id关联的WeakMap。这是一个例子。您可以有一个模块socket-map,该模块只导出映射套接字到字符串的映射:

代码语言:javascript
复制
import * as net from "net";

export const socketMap = new WeakMap<net.Socket, string>();

然后在获得套接字时使用id存储套接字:

代码语言:javascript
复制
import * as net from "net";
import * as uuid from "uuid";
import { socketMap } from "./socket-map";

var server = net.createServer();

server.on('connection', function(conn) {
    const id = uuid.v4();
    socketMap.set(conn, id); // You store the socket into the map.
    conn.on('data', function(data) {
        console.log('Session id:' + (conn as any).id);
    });
});

然后,在另一个模块中,您可以通过以下方式获得id:

代码语言:javascript
复制
import * as net from "net";
import { socketMap } from "./socket-map";

export function foo(conn: net.Socket) {
  const id = socketMap.get(conn);
}

在这里,我刚刚将套接字与id字符串关联起来,但是您可以在WeakMap的值中使用任何您想要的结构。它可以是一个除了id之外包含大量信息的对象。

使用WeakMap的原因是,虽然WeakMap对象的键包含对对象的引用,但这些引用并不包括垃圾收集。因此,如果您的应用程序是用套接字完成的,并且不再引用WeakMap以外的任何地方,那么WeakMap中的引用仍然允许垃圾收集器收集套接字。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55040899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档