java Netty远程编译代码(收藏学习)

16 篇文章 0 订阅
12 篇文章 0 订阅
[size=medium][color=red][b]客户端[/b][/color][/size]

[color=red][b]设置消息的长度:[/b][/color]buffer.writeInt(classByte.length);
[color=blue][b]写入消息内容:[/b][/color]buffer.writeBytes(classByte);
[color=orange][b]传输内容:[/b][/color]channel.write(buffer);


package hotswap.client;

import hotswap.JavacTool;
import hotswap.NamedThreadFactory;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

public class HotSwapClient {

// 因ChannelFactory的关闭有DirectMemory泄露,采用静态化规避
// https://issues.jboss.org/browse/NETTY-424
private static final ChannelFactory channelFactory = new NioClientSocketChannelFactory(
Executors.newSingleThreadExecutor(new NamedThreadFactory("HotSwapClient_Boss", true)),
Executors.newSingleThreadExecutor(new NamedThreadFactory("HotSwapClient_Worker", true)),
1);

public static void main(String[] args) {
send(connect());
}

public static void send(ChannelFuture future) {
if (future.isCancelled()) {
// Connection attempt cancelled by user
System.out.println("isCanncelled");
} else if (!future.isSuccess()) {
future.getCause().printStackTrace();
System.out.println("isNotSuccess");
} else {
// Connection established successfully
Channel channel = future.getChannel();
channel.setInterestOps(Channel.OP_READ_WRITE);

// 编译参数
List<String> otherArgs = Arrays.asList("-classpath", HotSwapClient.class.getProtectionDomain().getCodeSource().getLocation().toString());
// 编译
byte[] classByte = JavacTool.callJavac(otherArgs, "test.HotSwap");
ChannelBuffer buffer = ChannelBuffers.buffer(classByte.length + 4);
buffer.writeInt(classByte.length);
buffer.writeBytes(classByte);
channel.write(buffer);
}
}

public static ChannelFuture connect() {
ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {

@Override
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new SimpleChannelHandler() {

@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelConnected");
}

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
System.out.println(buffer.toString(Charset.forName("UTF-8")));
System.out.flush();
e.getChannel().close();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
System.out.println("client exceptionCaught");
e.getCause().printStackTrace();
e.getChannel().close();
}
});
}
});
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("keepAlive", true);
ChannelFuture future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 20001));
future.awaitUninterruptibly();
return future;
}
}



[size=medium][color=red][b]服务端[/b][/color][/size]

[color=red][b]读取消息长度:[/b][/color]int msgBodyLen = buffer.readInt();

[color=red][b]判断是否相等:[/b][/color]if (buffer.readableBytes() >= msgBodyLen )


package hotswap.server;

import hotswap.JavaClassExecuter;
import hotswap.NamedThreadFactory;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.Bootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelException;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The HotSwapServer represents
* @version $Id$
* @author fengjiachun
*/
public class HotSwapServer extends AbstractNettyServer {

private static final Logger LOG = LoggerFactory.getLogger(HotSwapServer.class);

static {
try {
new HotSwapServer().startServer();
} catch (Exception e) {
LOG.error("start HotSwapServer error {}", e);
}
}

@Override
public Bootstrap createServerBootstrap() {
ExecutorService boss = Executors.newSingleThreadExecutor(new NamedThreadFactory("HotSwapServer_Boss"));
ExecutorService worker = Executors.newSingleThreadExecutor(new NamedThreadFactory("HotSwapServer_Worker"));
this.serverBootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(boss, worker, 1));

return this.serverBootstrap;
}

@Override
public TRANSMISSION_PROTOCOL getTransmissionProtocol() {
return TRANSMISSION_PROTOCOL.TCP;
}

@Override
public void startServer() throws Exception {
startServer(20001);
}

@Override
public void startServer(int port) throws Exception {
InetSocketAddress socketAddress = new InetSocketAddress(port);
startServer(socketAddress);
}

@Override
public void startServer(InetSocketAddress socketAddress) throws Exception {
setPipelineFactory(new HotSwapPipelineFactory());

String[] optionsList = new String[2];
optionsList[0] = "child.tcpNoDelay"; // 关闭Nagle算法
optionsList[1] = "child.keepAlive"; // TCP定期发送心跳包,应用层不应该依赖这个选项,应用层有自己的心跳机制
configureServerBootStrap(optionsList);
try {
((ServerBootstrap) this.serverBootstrap).bind(socketAddress);
if (LOG.isInfoEnabled()) {
LOG.info("HotSwapServer start, port=" + socketAddress.getPort());
}
} catch (ChannelException e) {
LOG.error("Unable to start HotSwapServer due to error {}", e);
throw e;
}
}

class HotSwapPipelineFactory implements ChannelPipelineFactory {

private SimpleChannelHandler messageReceivedHandler = new SimpleChannelHandler() {

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
byte[] classByte = (byte[]) e.getMessage();
// 执行传过来的字节
String resultMsg = JavaClassExecuter.execute(classByte);
byte[] resultByte = resultMsg.getBytes(Charset.forName("UTF-8"));
ChannelBuffer buffer = ChannelBuffers.buffer(resultByte.length);
buffer.writeBytes(resultByte);
e.getChannel().write(buffer);
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
LOG.error("HotSwap Exception Caught: {}. Going to close channel.", e.getCause());
e.getChannel().close();
}

@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
if (LOG.isInfoEnabled()) {
LOG.info("HotSwap Connected Channel with ip: {}.", e.getChannel().getRemoteAddress());
}
}

@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
if (LOG.isInfoEnabled()) {
LOG.info("HotSwap Disconnected Channel with ip: {}.", e.getChannel().getRemoteAddress());
}
}
};

@Override
public ChannelPipeline getPipeline() throws Exception {
return addHandlers(Channels.pipeline());
}

public ChannelPipeline addHandlers(ChannelPipeline pipeline) {
if (null == pipeline) {
return null;
}
pipeline.addLast("hotSwapDecoder", new FrameDecoder() {

@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
if (buffer.readableBytes() >= 4) {
buffer.markReaderIndex(); // 标记ReaderIndex
int msgBodyLen = buffer.readInt(); // 前四个字节存放消息的长度
if (buffer.readableBytes() >= msgBodyLen) {
ChannelBuffer dst = ChannelBuffers.buffer(msgBodyLen);
buffer.readBytes(dst, msgBodyLen);
return dst.array();
} else {
buffer.resetReaderIndex();
return null;
}
}
return null;
}
});
pipeline.addLast("hotSwapHandler", messageReceivedHandler);
return pipeline;
}
}
}




转自:[url]http://budairenqin.iteye.com/blog/1788839[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值