耐帝-如何测试的客户/服务器的数字版本
-
29-10-2019 - |
题
作为我的一部分协议,我喜欢的客户发送的版本数量时,一个新建立连接。我想这样做在一个单独的处理程序的管道,因此请原谅我这可能是一个相当基本的问题,但我不知道该如何做到这一点。其他的事情是,我想再能够发送功的来回通过连接(管道)。此外,我想添加一个认证的处理程序。不管怎么说,我现在得到某种错误而且我很肯定这是因为该版本检查是不正确的消化从管道。
基本上代码我有如下设置发送"hello World",其服务器上打印出后的版本已经检查时的连接已经建立。至少在理论上,在现实中,这并不是工作;)
目前我有:
Client.java
public static void main(String[] args)
{
...
// Set up the pipeline factory.
bootstrap.setPipelineFactory(new ChannelPipelineFactory()
{
@Override
public ChannelPipeline getPipeline() throws Exception
{
return Channels.pipeline(
new ObjectEncoder(),
new ObjectDecoder(),
new VersionClientHandler(),
new BusinessLogicClientHandler());
}
});
...
// The idea is that it will all be request and response. Much like http but with pojo's.
ChannelFuture lastWriteFuture = channel.write("Hello world".getBytes());
if (lastWriteFuture != null)
{
System.out.println("waiting for message to be sent");
lastWriteFuture.awaitUninterruptibly();
}
...
}
VersionClientHandler.java
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
{
ChannelBuffer versionBuffer = ChannelBuffers.buffer(VERSION_STRING_LENGTH);
versionBuffer.writeBytes("v123.45a".getBytes());
// If I understand correctly, the next line says use the rest of the stream to do what you need to the next Handler in the pipeline?
Channels.write(ctx, e.getFuture(), versionBuffer);
}
BusinessLogicClientHandler.java
Not really doing anything at this point. Should it?
Server.java
public static void main(String[] args)
{
...
public ChannelPipeline getPipeline() throws Exception
{
return Channels.pipeline(
new ObjectEncoder(),
new ObjectDecoder(),
new VersionServerHandler(),
new BusinessLogicServerHandler());
}
...
}
VersionServerHandler.java
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
{
ChannelBuffer versionBuffer = ChannelBuffers.buffer(VERSION_NUMBER_MAX_SIZE);
System.out.println("isReadable - messageReceived: " + versionBuffer.readable()); // returns false???
// Basically I want to read it and confirm the client and server versions match.
// And if the match fails either send a message or throw an exception
// How do I also pass on the stream to the next Handler?
}
BusinessLogicServerHandler.java
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
{
e.getMessage();
byte[] message = (byte[])e.getMessage(); // "Hello World" in byte[] from Client.java
}
所以基本上我希望是这个版本的数量传递和验证当的通道连接的一部分通信协议。所有自动完成的。同样,我想通过认证机构,这种方式。
我没有看到一些代码看起来有点像我想要做什么与安全聊天的例子,但我真的不能。任何帮助就如何设置这个代码会是真正的赞赏。我知道我可以做这一切在一个大规模的处理程序,但是这一点的管道,以打破它单位,使逻辑意义。
解决方案
我找到了解决方案!
有很多问题。
在VersionClientHandler上,新代码为: 通用标签
注意最后一行,用e.getChannel().write(version);
代替Channels.write(ctx, e.getFuture(), versionBuffer);
,我不确定为什么。 实际上,我将开始研究为什么在那里有ChannelBuffers代码,因为它似乎没有任何作用...
在VersionServerHandler.java上,我现在拥有: 通用标签
注意,我不再读取缓冲区,我只是执行了e.getMessage()
并转换为正确的对象类型。在此之上,我添加了ctx.getPipeline().remove(VersionServerHandler.class);
,可以从任何进一步处理中删除该处理程序。初始连接后不再需要。感谢丹尼斯的提示。
结论
其余的与我预期的一样。关键是我没有正确理解如何读取缓冲区并传递信息。错误消息和示例还不清楚。一旦将Netty中的POJO通道添加到管道中,就需要开始为所有处理程序仅处理对象。我想念那个。这些概念是正确的,这就是我试图从错误的通道读取数据的方式。
另一个重要提示是,如果在初始连接后不需要处理程序,则将它们从管道中删除。我假设身份验证处理程序也是如此。在这里得到确认会很棒,但是稍后我必须弄清楚。
其他提示
您没有提到看到的错误是什么。
无论如何,我都不建议使用单独的通道处理程序来进行版本检查。主要是因为第一次建立连接时,版本检查只需要执行一次。同样是因为我认为最好让通道处理程序处理传输层问题,例如将字节转换为pojos。
我创建了一个简单的例子: https://github.com/boldt/netty-examples/
它返回的版本数量时,一个新建立连接。它是在一个单独的处理程序,这将被删除从管道之后的版本上写道。之后它回声例从耐帝的教程。
一个 telnet localhost 1234
到服务器显示了该版本。
这样你可以添加一个认证的处理程序的管道后面版本的处理程序。
我认为您可以通过添加一些自定义处理程序轻松地存档您想要做的事情。因此,对于版本检查,您可以添加一个覆盖channelConnected(....)的处理程序,并在那里进行检查。对于auth,只需在版本检查后添加另一个处理程序即可,该处理程序将覆盖messageRecieved(....)方法。身份验证完成后,您可以从管道中删除处理程序,并在再次需要时将其重新添加。
BusinessLogic处理程序应作为最后一个进入管道。请注意,您的任何处理程序都会执行某些阻止操作,您应该考虑在其前面添加一个ExecutionHandler来确保ioworker线程将被阻止,从而使Netty服务器不负责任。