Dart 的简单套接字库

一个用于处理 Dart 套接字器的简单库。

Dart 的 socket-io NodeJS 移植版 相当不错,但缺少类型定义,而且我不喜欢使用 dynamic 数据类型。此外,它相当臃肿,我不需要所有这些功能,我只想确保我有一个最小化的直观库,我可以在 Dart 套接字类之上进行工作,而无需担心内存泄漏,因为我忘记了打开的第 9 个 Stream 监听器。

当前实现的功能

  • 支持服务器端。
  • 支持客户端。
  • 通过 send API 进行消息帧处理。
  • 完全类型的 API,尽管是可选的。
  • 轻量级:代码行数少于 400 行。
  • 事件驱动的回调。
  • 自定义事件类型。

基本用法

final SimpleServerSocket server = await SimpleServerSocket.bind();

server.on<SimpleSocket>('connection', (SimpleSocket client) {
  // or: client.sendMessage('hello', 'Hi, client.');
  client.sendSignal('hello');

  client.on<void>('bye', (_) => server.destroy());
});

server.listen();

// On client-side:

final SimpleSocket socket =
    await SimpleSocket.connect('localhost', server.port);

socket.on<void>('hello', (_) => socket.replyWithSignal('bye'));

使用消息

final SimpleServerSocket server = await SimpleServerSocket.bind();

server.on<SimpleSocket>('connection', (SimpleSocket client) {
  client.sendMessage('greetings', 'Sup client!');

  client.on<List<int>>('bye', (List<int> data) {
    print(String.fromCharCodes(data)); // Bye bye...
    server.destroy();
  });
});

server.listen();

// On client-side:

final SimpleSocket socket =
    await SimpleSocket.connect('localhost', server.port);

socket.on<List<int>>('greetings', (List<int> data) {
  print(String.fromCharCodes(data)); // Sup client!
  socket.reply('bye', 'Bye bye...');
});
这就是使用原始 Dart 套接字进行工作的样子。

final ServerSocket server =
    await ServerSocket.bind(InternetAddress.anyIPv4, 0);

late final StreamSubscription<Socket> onNewClientListener;

Future<void> closeServer() async {
  await onNewClientListener.cancel();
  await server.close();
}

onNewClientListener = server.listen(
  (Socket client) {
    late final StreamSubscription<String> onNewMessageListener;

    Future<void> cancelListener() async {
      await onNewMessageListener.cancel();
    }

    client.write('Sup client!');

    onNewMessageListener = client.map(String.fromCharCodes).listen(
      // No TCP messaging-frame support!
      (String message) {
        print(message);
        if (message == 'bye') {
          client.close();
          closeServer();
        }
      },
      cancelOnError: true,
      onDone: cancelListener,
      onError: (_) => cancelListener(),
    );
  },
  cancelOnError: true,
  onDone: closeServer,
  onError: (_) => closeServer(),
);

// On client-side.

final Socket socket = await Socket.connect('localhost', server.port);

late final StreamSubscription<String> onNewServerMessageListener;

Future<void> cancelListener() async {
  socket.destroy();
  await socket.close();
  await onNewServerMessageListener.cancel();
}

onNewServerMessageListener = socket.map(String.fromCharCodes).listen(
  // No TCP messaging-frame support!
  (String message) {
    if (message.startsWith('Sup')) {
      print(message);
      socket.write('bye');
    }
  },
  cancelOnError: true,
  onDone: cancelListener,
  onError: (_) => cancelListener(),
);

进一步阅读

开源

版权所有 © 2023-present, Alex Rintt。

Simple Socket 是 MIT 许可吗?

GitHub

查看 Github