Я хочу показать удаленный рабочий стол на клиенте в режиме реального времени. Это значит, что сервер постоянно посылает скриншот, а клиент рисует изображение на панели одновременно. Сначала он работает хорошо, но через несколько минут клиент блокируется, а сервер работает нормально.
Класс CaptureImage, определенный для скриншота. У этого есть два атрибута, длина и содержание.
private int length;// The length of attribute content
private byte[] content;// The BufferedImage convert to bytearray
Основной код сервера:
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
BufferedImage image;
Robot robot = new Robot();
Toolkit toolkit = Toolkit.getDefaultToolkit();
Rectangle rect = new Rectangle(0, 0, toolkit.getScreenSize().width, toolkit.getScreenSize().height);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CaptureImage captureImage = new CaptureImage();
while (true) {
image = robot.createScreenCapture(rect);
ImageIO.write(image, "jpg", baos);
captureImage.setLength(baos.toByteArray().length);
captureImage.setContent(baos.toByteArray());
ctx.writeAndFlush(captureImage);// Deliver to ImageEncoder before writing
Thread.sleep(100);
baos.reset();
// Always print if add System.out.println() here...
}
}
}
public class ImageEncoder extends MessageToByteEncoder<CaptureImage> {
@Override
protected void encode(ChannelHandlerContext ctx, CaptureImage msg, ByteBuf out) throws Exception {
out.writeInt(msg.getLength());
out.writeBytes(msg.getContent());
}
}
Основной код клиента:
public class ClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// Accept msg from ImageDecoder
CaptureImage captureImage = (CaptureImage) msg;
RemoteDesktop.panel.display(captureImage.getContent());// Paint the image on the panel
}
}
public class ImageDecoder extends ReplayingDecoder<Void> {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
int length = in.readInt();
byte[] content = new byte[length];
in.readBytes(content);
CaptureImage captureImage = new CaptureImage();
captureImage.setLength(length);
captureImage.setContent(content);
out.add(captureImage);
// The print will stop after a few minutes if add System.out.println() here...
}
}
Печать в ServerHandler всегда продолжается, но печать в ImageDecoder может остановиться через несколько минут.
Проблема, с которой я столкнулся, выглядит как OutOfMemoryError. Но нет СООБЩЕНИЯ ОШИБКИ, даже если я переопределяю метод exceptionCaught в каждом ChannelHandler. Я также попробовал Memory Analyzer, но, похоже, ничего не помогло.
Пожалуйста, помогите мне найти основную причину.
Здесь запущен проект https://github.com/leisuredong/RemoteDesktop