gpt4 book ai didi

java - Netty - 如何测试客户端/服务器版本号

转载 作者:行者123 更新时间:2023-11-30 04:54:46 28 4
gpt4 key购买 nike

作为我的协议(protocol)的一部分,我希望客户端在建立新连接时发送其版本号。我希望在管道中的单独处理程序中完成此操作,因此请耐心等待,因为这可能是一个相当基本的问题,但我不确定如何做到这一点。另一件事是我希望能够通过连接(管道)来回发送 POJO。我还想添加一个身份验证处理程序。不管怎样,现在我遇到了某种错误,我很确定这是因为版本检查没有从管道中正确消化。

基本上,我下面的代码设置为发送“Hello World”,服务器在建立连接后检查版本后打印出该“Hello World”。至少在理论上,实际上这不太有效;)

目前我有:

客户端.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?

服务器.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
}

所以基本上我想要的是当 channel 作为通信协议(protocol)的一部分连接时传递并验证版本号。一切都在幕后自动完成。同样,我很想通过这种方式通过身份验证机制。

我确实看到了一些代码,看起来有点像我想要在安全聊天示例中执行的操作,但我无法真正弄清楚它。任何有关如何设置此代码的帮助将不胜感激。我知道我可以在一个大型处理程序中完成这一切,但这就是管道的重点,将其分解为具有逻辑意义的单元。

最佳答案

我找到了解决方案!!!

存在很多问题。

在 VersionClientHandler 上,新代码为:

public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
{
String verison = "v123.45a";

ChannelBuffer versionBuffer = ChannelBuffers.buffer(VERSION_STRING_LENGTH);
versionBuffer.writeBytes(version.getBytes());
e.getChannel().write(version);
}

注意最后一行,e.getChannel().write(version); 而不是 Channels.write(ctx, e.getFuture(), versionBuffer);我不确定为什么。 事实上,我即将开始研究为什么我在那里有 ChannelBuffers 代码,因为它似乎没有做任何事情......

在 VersionServerHandler.java 上我现在有:

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) 
{
String versionCheck = (String)e.getMessage();
System.out.println("VersionServerHandler - " + versionCheck);
ctx.getPipeline().remove(VersionServerHandler.class);
}

请注意,我不再读取缓冲区,我只是执行 e.getMessage() 并强制转换为正确的对象类型。在此之上,我添加了 ctx.getPipeline().remove(VersionServerHandler.class); ,用于从任何进一步的处理中删除该处理程序。初始连接后不再需要它。感谢丹尼斯的提示。

结论

剩下的就和我预想的差不多了。关键是我没有正确理解如何读取缓冲区并传递信息。并且错误消息和示例不是很清楚。一旦将 Netty 中的 POJO channel 添加到管道中,您就需要开始仅处理所有处理程序的对象。我错过了那个。这些概念是正确的,只是我尝试从错误的 channel 读取数据的方式。

另一个重要提示是,如果在初始连接后不需要处理程序,请从管道中删除它们。我认为身份验证处理程序也是如此。如果能在这里得到确认就太好了,但我必须稍后再解决这个问题。

关于java - Netty - 如何测试客户端/服务器版本号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8883413/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com