服务端
依赖
<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);
}
}
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!