服务端

依赖


        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.36.Final</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.13</version>
        </dependency>

BaseService.java

package com.cares.fidsremoteserver.service;

import io.netty.channel.ChannelHandlerContext;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 19:32
 **/
public interface BaseService {
    /**
     * 测试接口
     */
    void sendImage(ChannelHandlerContext ctx);

    void stopSend();
}

BaseServiceImpl.java

package com.cares.fidsremoteserver.service.impl;

import com.cares.fidsremoteserver.service.BaseService;
import com.cares.fidsremoteserver.service.SendImgRunner;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.stereotype.Service;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 19:32
 **/
@Service
public class BaseServiceImpl implements BaseService {
    Thread sendThread = null;

    @Override
    public void sendImage(ChannelHandlerContext ctx) {
        System.out.println("调用service服务");

        SendImgRunner sendImgRunner = new SendImgRunner(ctx);
        sendThread = new Thread(sendImgRunner);
        sendThread.start();

    }

    @Override
    public void stopSend() {
        if (null != sendThread) {
            sendThread.interrupt();
        }
    }
}

FidsServer.java

package com.cares.fidsremoteserver.service;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 19:38
 **/
@Component
public class FidsServer {
    @Resource
    private FidsServerChannelInit childChannelHandler;

    @PostConstruct
    public void startServer() {
        try {
            run(8081);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void run(int port) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        System.out.println("准备运行端口:" + port);
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childHandler(childChannelHandler);
            //绑定端口,同步等待成功
            ChannelFuture f = bootstrap.bind(port).sync();
            //等待服务监听端口关闭
            f.channel().closeFuture().sync();
        } finally {
            //退出,释放线程资源
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

FidsServerChannelInit.java

package com.cares.fidsremoteserver.service;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;


/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 19:25
 **/
@Component
public class FidsServerChannelInit extends ChannelInitializer<SocketChannel> {

    @Resource
    private FidsServerHandler fidsServerHandler;

    public void initChannel(SocketChannel socketChannel) throws Exception {
        socketChannel.pipeline().addLast("frameDecoder",
                new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
        socketChannel.pipeline().addLast("bytesDecoder",
                new ByteArrayDecoder());
        socketChannel.pipeline().addLast("frameEncoder", new LengthFieldPrepender(4));
        socketChannel.pipeline().addLast("bytesEncoder", new ByteArrayEncoder());
        socketChannel.pipeline().addLast(fidsServerHandler);
    }
}

FidsServerHandler.java

package com.cares.fidsremoteserver.service;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 19:31
 **/
@Slf4j
@Component
@ChannelHandler.Sharable
public class FidsServerHandler extends ChannelInboundHandlerAdapter {

    @Resource
    private BaseService baseService;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            ByteBuf in = (ByteBuf) msg;
            System.out.println("传输内容是");
            System.out.println(in.toString(CharsetUtil.UTF_8));
            //这里调用service服务
        }  finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        log.info("channelRegistered");
    }


    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.info("channelUnregistered");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("channelActive");
        baseService.sendImage(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("channelInactive");
        baseService.stopSend();
    }



    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("读完");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("异常");
    }
}

SendImgRunner.java

package com.cares.fidsremoteserver.service;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 20:34
 **/
@Slf4j
public class SendImgRunner implements Runnable{

    private ChannelHandlerContext ctx;
    private Robot robot;

    public SendImgRunner(ChannelHandlerContext ctx) {
        this.ctx = ctx;
        try {
            robot = new Robot();
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        while (true) {
            try {

                Rectangle rect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
                BufferedImage bm = robot.createScreenCapture(rect);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                Thumbnails.of(bm).size(800,600).outputFormat("JPG").toOutputStream(bos);
                ctx.channel().writeAndFlush(Unpooled.buffer().writeBytes(bos.toByteArray()));
                // 视觉停留极限
                Thread.sleep(100);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
                break;
            }

        }
    }
}

客户端

依赖

和服务端相同

ShowImgService.java

package com.cares.fidsremoteclient.service;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 20:16
 **/
public interface ShowImgService {
    void show(byte[] bytes);
}

ShowImgServiceImpl.java

package com.cares.fidsremoteclient.service.impl;

import com.cares.fidsremoteclient.service.FidsClientWnd;
import com.cares.fidsremoteclient.service.ShowImgService;
import org.springframework.stereotype.Service;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 20:17
 **/
@Service
public class ShowImgServiceImpl implements ShowImgService {

    private FidsClientWnd fidsClientWnd = null;

    @Override
    public void show(byte[] bytes) {
        if (null == fidsClientWnd) {
            fidsClientWnd = new FidsClientWnd();
        }
        fidsClientWnd.setImage(bytes);
    }
}

FidsClient.java

package com.cares.fidsremoteclient.service;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 20:12
 **/
@Slf4j
@Component
public class FidsClient {

    @Resource
    FidsClientChannelInit fidsClientChannelInit;

    @Resource
    private ReConnectListener reConnectListener;

    @Value("${fids.server.host}")
    private String host;

    @Value("${fids.server.port}")
    private Integer port;
    private ChannelFuture future = null;
    EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

    @PostConstruct
    public void start() {

        Bootstrap bootstrap = new Bootstrap();
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.group(eventLoopGroup);
        bootstrap.remoteAddress(host, port);
        bootstrap.handler(fidsClientChannelInit);

        try {
            future = bootstrap.connect(host, port).sync();
            future.addListener(reConnectListener);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @PreDestroy
    public void cancel() {
        log.info("关闭连接");
        try {
            eventLoopGroup.shutdownGracefully().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

FidsClientChannelInit.java

package com.cares.fidsremoteclient.service;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/20 1:58
 **/
@Component
public class FidsClientChannelInit extends ChannelInitializer<SocketChannel> {

    @Resource
    FidsClientHandler fidsClientHandler;

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        socketChannel.pipeline().addLast(new IdleStateHandler(20, 10, 0));
        socketChannel.pipeline().addLast("frameDecoder",
                new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
        socketChannel.pipeline().addLast("bytesDecoder",
                new ByteArrayDecoder());
        socketChannel.pipeline().addLast("frameEncoder", new LengthFieldPrepender(4));
        socketChannel.pipeline().addLast("bytesEncoder", new ByteArrayEncoder());
        socketChannel.pipeline().addLast(fidsClientHandler);
    }
}

FidsClientHandler.java

package com.cares.fidsremoteclient.service;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 20:14
 **/
@Slf4j
@Component
public class FidsClientHandler implements ChannelInboundHandler {

    @Resource
    ShowImgService showImgService;


    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {

        log.info("channelRegistered");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.info("channelUnregistered");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("channelActive");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("channelInactive");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        byte[] bytes = (byte[]) msg;
        showImgService.show(bytes);
        log.info("channelRead");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("channelReadComplete");
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.info("userEventTriggered");
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        log.info("channelWritabilityChanged");
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info("handlerAdded");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        log.info("handlerRemoved");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("exceptionCaught");
        cause.printStackTrace();
    }
}

FidsClientWnd.java

package com.cares.fidsremoteclient.service;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;

/**
 * @author wangcj
 * @desc
 * @date 2020/12/19 20:39
 **/
public class FidsClientWnd extends JFrame {

    private static BufferedImage imageIcon;

    public FidsClientWnd() {
        Dimension size = new Dimension(800, 600);
        this.setSize(size);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new BorderLayout());
        PaintPanel paintPanel = new PaintPanel();
        this.add(paintPanel);
        //   this.pack();
        setUndecorated(true);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }


    public void setImage(byte[] bytes) {
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        try {
            imageIcon = ImageIO.read(bis);
        } catch (IOException e) {
            e.printStackTrace();
        }
        repaint();
    }


    private static class PaintPanel extends JPanel {

        private Image buffer = null;

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            buffer = imageIcon;
            if (buffer != null) {
                Graphics g1 = buffer.getGraphics();
                g1.drawImage(imageIcon, 0, 0, this);
                g.drawImage(buffer, 0, 0, getWidth(), getHeight(), this);
            }
        }
    }
}



JAVA      netty

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!