我希望为Websockets和net.Sockets分配唯一标识符,因此当接收到消息时,客户端将通过附加到套接字的标识符进行标识。
以前的研究:
对于Websocket:
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:
同样,根据这的说法,需要做以下几点:
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代码将是:
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代码将是:
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 -问题:
打字本版本: 3.2.4。
发布于 2019-03-09 14:31:32
我不知道这个领域已经存在。
如果您可以像在选项2中那样将套接字id保存在局部变量中,我就会这样做。I通常倾向于避免将任意字段添加到对象中。但是,有时您希望整个应用程序能够访问附加的数据,而在这些情况下,使用局部变量的将无法工作。
添加自定义字段
您可以向项目中添加一个包含以下内容的文件,而不是对any使用类型断言:
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,该模块只导出映射套接字到字符串的映射:
import * as net from "net";
export const socketMap = new WeakMap<net.Socket, string>();然后在获得套接字时使用id存储套接字:
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:
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中的引用仍然允许垃圾收集器收集套接字。
https://stackoverflow.com/questions/55040899
复制相似问题