codecamp

编写 TCP 服务器

创建 TCP 服务器

使用最简单的方法来创建一个 TCP 服务器,使用所有默认选项如下所示:

NetServer server = vertx.createNetServer();

配置 TCP 服务器

如果你不想默认值,可以将服务器配置通过传入一个NetServerOptions实例来创建它:

NetServerOptions options = new NetServerOptions().setPort(4321);
NetServer server = vertx.createNetServer(options);

启动服务器监听

使用listen告诉服务监听传入的请求

告诉要听的主机和端口作为选项中指定的服务器:

需要在选项(NetServerOptions)中指定的主机和端口:

NetServer server = vertx.createNetServer();
server.listen();

或在调用listen中指定的主机和端口,忽略NetServerOptions配置:

NetServer server = vertx.createNetServer();
server.listen(1234, "localhost");

默认主机是0.0.0.0,意味着 '监听所有可用的地址' ,默认端口是0,这是一个特殊值,告诉服务器随机找一个未使用的本地端口使用。

真实的绑定是异步的,所以服务器可能不会实际被侦听,直到有一段时间后,调用返回。

如果想要listen实际监听后通知你,可以提供listen调用处理程序。例如:

NetServer server = vertx.createNetServer();
server.listen(1234, "localhost", res -> {
  if (res.succeeded()) {
    System.out.println("Server is now listening!");
  } else {
    System.out.println("Failed to bind!");
  }
});

监听随机端口

如果0用作的监听端口,则服务器将找到一个未使用的随机端口监听。

若要找出服务器正在监听的真正端口,您可以调用actualPort.

NetServer server = vertx.createNetServer();
server.listen(0, "localhost", res -> {
  if (res.succeeded()) {
    System.out.println("Server is now listening on actual port: " + server.actualPort());
  } else {
    System.out.println("Failed to bind!");
  }
});

传入连接通知

若要连接时通知您需要设置connectHandler:

NetServer server = vertx.createNetServer();
server.connectHandler(socket -> {
  // Handle the connection in here
});

当进行连接时的处理程序将调用Netsocket实例。

这是一个类似于socket-like的接口的真实连接,并且允许你读写数据以及做其他各种类似的事情,比如关闭套接字。

从Socket读取数据

从socket读取数据要在socket上设置handler

每次在socket上接收到数据Buffer实例,将调用此处理程序。

NetServer server = vertx.createNetServer();
server.connectHandler(socket -> {
  socket.handler(buffer -> {
    System.out.println("I received some bytes: " + buffer.length());
  });
});

数据写入socket

使用write写到socket.

Buffer buffer = Buffer.buffer().appendFloat(12.34f).appendInt(123);
socket.write(buffer);

// Write a string in UTF-8 encoding
socket.write("some data");

// Write a string using the specified encoding
socket.write("some data", "UTF-16");

写操作是异步的,调用返回之后可能不会发生。

关闭的处理程序(handler)

如果你想要关闭socket时得到通知,可以设置closeHandler :

socket.closeHandler(v -> {
  System.out.println("The socket has been closed");
});

处理异常

您可以设置exceptionHandler接收socket发生的任何异常。

Event bus写handler

每个socket自动注册event bus上的handler,当这个handler接收到任何buffers时,它会将它们写入到本身。

这使您可以将数据写到socket,它可能是在完全不同的verticle或甚至在不同的 Vert.x 实例,通过将buffers发送到该处理程序的地址。

writeHandlerID给出了处理程序的地址

本地和远程地址

可以使用localAddress检索NetSocket的本地地址.

可以使用remoteAddress检索远程地址 (即地址连接的另一端) 的NetSocket.

从classpath发送文件或资源

直接使用sendFile就可以将文件写入socket。这是非常有效的发送文件的方法,因为它可以由操作系统内核直接支持。

socket.sendFile("myfile.dat");

Streaming sockets

NetSocket的实例也是ReadStream和WriteStream的实例,因此他们可以被用于泵送数据,可以从其他的读和写streams。

详细信息,请参阅Streams章。

升级到 SSL/TLS 连接

非 SSL/TLS 连接可以使用upgradeToSsl升级到 SSL/TLS。

服务器或客户端必须配置为 SSL/TLS 才能正常工作。详细信息请参阅关于 SSL/TLS 章节。

关闭一个 TCP 服务器

close来关闭服务器。关闭服务器关闭任何打开的连接,并释放所有的服务器资源。

关闭是异步的,可能无法立即返回。如果你想要关闭已完成然后通知,可以通过handler做到。

当关闭已全面完成,然后将调用此处理程序。

server.close(res -> {
  if (res.succeeded()) {
    System.out.println("Server is now closed");
  } else {
    System.out.println("close failed");
  }
});

Verticles 自动清理

如果您正在从 verticles内创建 TCP 服务器和客户端,verticle取消部署时这些服务器和客户端将被自动关闭。

Scaling - sharing TCP 服务器

任何TCP服务器的处理器总是在相同的事件循环线程执行。

这意味着,如果在多核的服务器上运行,而你只部署一个实例,那么最多使用一个核心。

为了利用你的服务器更多的核心,你将需要部署服务器的多个实例。

您可以以编程方式在代码中实例化多个实例:

for (int i = 0; i < 10; i++) {
  NetServer server = vertx.createNetServer();
  server.connectHandler(socket -> {
    socket.handler(buffer -> {
      // Just echo back the data
      socket.write(buffer);
    });
  });
  server.listen(1234, "localhost");
}

或者,如果您正在使用verticles你可以简单地通过使用命令行选项-instances部署服务器verticle的多个实例:

vertx run com.mycompany.MyVerticle -instances 10

或以编程方式部署verticle

DeploymentOptions options = new DeploymentOptions().setInstances(10);
vertx.deployVerticle("com.mycompany.MyVerticle", options);

一旦你这样做,你会发现echo服务器的功能与以前的功能相同,但可以利用您在您的服务器上的所有核心,可以处理更多的工作。

在这一点上你可能会问自己' 你怎么能有多个服务器监听同一主机和端口?尝试部署多个实例,肯定会端口冲突?'

Vert.x 确实有点神奇,如:

当你在同一个主机上部署另一个服务器,作为一个现有的服务器,它实际上并没有尝试在同一个主机/端口上创建一个新的服务器。

相反它内部维护只是一台服务器,将连接通过循环的方式分配处理程序。

因此 Vert.x TCP 服务部署可以超过可用CPU内核,每个实例是单个线程。


缓冲区
编写 TCP 客户端
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

编写 TCP 服务器和客户端

编写 HTTP 服务器和客户端

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }