Как читать/писать с Netty, когда другая сторона использует readutf/writeutf?
Вопрос
Я пытаюсь общаться с сервером, который использует DataInputStream.Readutf и DataOutputStream.WriteUtf.
Я сделал обычный код начальной загрузки для настройки моего клиента, и установил следующий PipelineFactory
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(
new LengthFieldBasedFrameDecoder(65536, 0, 2),
new StringDecoder(CharsetUtil.UTF_8),
new StringEncoder(CharsetUtil.UTF_8),
new MyClientHandler());
}
});
В MyClientHandler, который расширяет SimpleChannelupstreamHandler, у меня есть следующее:
boolean sent = false; //is this thread safe?
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
logger.log(Level.INFO, e.getMessage().toString());
e.getChannel().write("Hello over there!");
if(!sent){
//do something and set sent
}
}
Мне удалось успешно получить сообщения с сервера, но сервер не получает мое сообщение «Привет там». Не уверен, что я мог упустить из виду.
Кроме того, обратите внимание на отправленную логин, могу ли я добавить такие поля и работать с ними без проблем с потоком?
Решение
- Мне удалось успешно получить сообщения с сервера, но сервер не получает мое сообщение «Привет там». Не уверен, что я мог упустить из виду.
Поскольку сообщение с сервера было получено с помощью LengthFieldBasedFrameDecoder, сообщение имеет поле длины.
+--------+----------+
| Length | Message |
+--------+----------+
Поэтому существует вероятность того, что сервер будет ожидать, что полученное сообщение имеет поле длины. Как, если поле длины написано следующим образом?
+--------+---------------------+
| 0x0011 | "Hello over there!" |
+--------+---------------------+
образец
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
logger.log(Level.INFO, e.getMessage().toString());
byte[] message = "Hello over there!".getBytes("UTF-8");
ChannelBuffer buf = ChannelBuffers.buffer(message.length + 2);
buf.clear();
short len = (short)message.length;
buf.writeShort(len);
buf.writeBytes(message);
e.getChannel().write(buf);
if(!sent){
//do something and set sent
}
}
- Кроме того, обратите внимание на отправленную логин, могу ли я добавить такие поля и работать с ними без проблем с потоком?
Да, вы можете добавить поля для хранения некоторого состояния. И вам не нужно рассматривать синхронизацию потока.