TCP Client 示例

在上文中我们已经了解了客户端架构。现在我们将展示一个客户端实现的示例。

我们将使用 Sumup Client 作为一个参考实现。

我们将移除掉样板代码并专注于重要结构上。以下是为客户端代码:

  1. public static void main(String[] args) throws Throwable {
  2. NioSocketConnector connector = new NioSocketConnector();
  3. connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);
  4. if (USE_CUSTOM_CODEC) {
  5. connector.getFilterChain().addLast("codec",
  6. new ProtocolCodecFilter(new SumUpProtocolCodecFactory(false)));
  7. } else {
  8. connector.getFilterChain().addLast("codec",
  9. new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
  10. }
  11. connector.getFilterChain().addLast("logger", new LoggingFilter());
  12. connector.setHandler(new ClientSessionHandler(values));
  13. IoSession session;
  14. for (;;) {
  15. try {
  16. ConnectFuture future = connector.connect(new InetSocketAddress(HOSTNAME, PORT));
  17. future.awaitUninterruptibly();
  18. session = future.getSession();
  19. break;
  20. } catch (RuntimeIoException e) {
  21. System.err.println("Failed to connect.");
  22. e.printStackTrace();
  23. Thread.sleep(5000);
  24. }
  25. }
  26. // wait until the summation is done
  27. session.getCloseFuture().awaitUninterruptibly();
  28. connector.dispose();
  29. }

要构建一个客户端,我们需要做以下事情:

  • 创建一个 Connector
  • 创建一个 Filter Chain
  • 创建一个 IOHandler 并添加到 Connector
  • 绑定到服务器

下面解释每个细节

创建一个 Connector

  1. NioSocketConnector connector = new NioSocketConnector();

现在,我们已经创建了一个 NIO Socket 连接器

创建一个 Filter Chain

  1. if (USE_CUSTOM_CODEC) {
  2. connector.getFilterChain().addLast("codec",
  3. new ProtocolCodecFilter(new SumUpProtocolCodecFactory(false)));
  4. } else {
  5. connector.getFilterChain().addLast("codec",
  6. new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
  7. }

我们为 Connector 的 Filter Chain 添加了一些过滤器。这里我们添加的是一个 ProtocolCodec 到过滤器链。

创建 IOHandler

  1. connector.setHandler(new ClientSessionHandler(values));

这里我们创建了一个 ClientSessionHandler 的实例并将其设置为 Connector 的处理器。

绑定到服务器

  1. IoSession session;
  2. for (;;) {
  3. try {
  4. ConnectFuture future = connector.connect(new InetSocketAddress(HOSTNAME, PORT));
  5. future.awaitUninterruptibly();
  6. session = future.getSession();
  7. break;
  8. } catch (RuntimeIoException e) {
  9. System.err.println("Failed to connect.");
  10. e.printStackTrace();
  11. Thread.sleep(5000);
  12. }
  13. }

这是最重要的部分。我们将连接到远程服务器。因为是异步连接任务,我们使用了 ConnectFuture 来了解何时连接完成。一旦连接完成,我们将得到相关联的 IoSession。要向服务器端发送任何消息,我们都要写入 session。所有来自服务器端的响应或者消息都将穿越 Filter chain 并最终由 IoHandler 处理。

译者注:翻译版本的项目源码见 https://github.com/waylau/apache-mina-2-user-guide-demos 中的com.waylau.mina.demo.sumup包下