在客户端和服务器之间发送,接收和转换对象的正确习惯是什么?我从一个简单的例子开始,我只想在客户端和服务器之间发送特定类型。
服务器输出:
BUILD SUCCESSFUL
Total time: 3 seconds
Jul 26, 2014 3:36:22 AM io.netty.handler.logging.LoggingHandler channelRegistered
INFO: [id: 0xefbb5b05] REGISTERED
Jul 26, 2014 3:36:22 AM io.netty.handler.logging.LoggingHandler bind
INFO: [id: 0xefbb5b05] BIND(0.0.0.0/0.0.0.0:4454)
Jul 26, 2014 3:36:22 AM io.netty.handler.logging.LoggingHandler channelActive
INFO: [id: 0xefbb5b05, /0:0:0:0:0:0:0:0:4454] ACTIVE
Jul 26, 2014 3:36:32 AM io.netty.handler.logging.LoggingHandler logMessage
INFO: [id: 0xefbb5b05, /0:0:0:0:0:0:0:0:4454] RECEIVED: [id: 0xabdeec06, /127.0.0.1:59934 => /127.0.0.1:4454]
Jul 26, 2014 3:36:32 AM net.bounceme.dur.netty.ServerHandler exceptionCaught
SEVERE: io.netty.handler.codec.DecoderException: java.io.InvalidClassException: failed to read class descriptor
Jul 26, 2014 3:36:32 AM net.bounceme.dur.netty.ServerHandler channelReadComplete
INFO: finished reading..?
^Cthufir@dur:~/NetBeansProjects/AgentServer$
thufir@dur:~/NetBeansProjects/AgentServer$
客户输出:
BUILD SUCCESSFUL
Total time: 3 seconds
Jul 26, 2014 3:36:32 AM net.bounceme.dur.client.netty.ClientHandler channelActive
INFO:
id 0
phone 0
title null
state undefined
thufir@dur:~/NetBeansProjects/AgentClient$
ServerHandler:
package net.bounceme.dur.netty;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.logging.Logger;
import net.bounceme.dur.jdbc.Title;
/**
* Handles both client-side and server-side handler depending on which
* constructor was called.
*/
public class ServerHandler extends ChannelInboundHandlerAdapter {
private static final Logger log = Logger.getLogger(ServerHandler.class.getName());
private RecordsQueueWrapper q = null;
public ServerHandler(RecordsQueueWrapper q) {
this.q = q;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object obj) {
Title receivedTitle = (Title) obj;
log.info(receivedTitle.toString());
Title nextTitle = q.pop();
ctx.write(nextTitle);
log.info("..channelRead");
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
log.info("finished reading..?");
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.severe(cause.toString());
ctx.close();
}
}
ClientHandler的:
package net.bounceme.dur.client.netty;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.logging.Logger;
import net.bounceme.dur.client.jdbc.Title;
public class ClientHandler extends ChannelInboundHandlerAdapter {
private static final Logger log = Logger.getLogger(ClientHandler.class.getName());
public ClientHandler() {
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
Title firstTitle = new Title();
log.info(firstTitle.toString());
ctx.writeAndFlush(firstTitle);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
Title t = (Title) msg;
log.info(msg.toString());
ctx.write(t);
} catch (ClassCastException cce) { //????
log.warning(cce.toString());
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx
) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause
) {
log.severe(cause.toString());
ctx.close();
}
}
服务器:
package net.bounceme.dur.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import java.security.cert.CertificateException;
import java.util.logging.Logger;
import javax.net.ssl.SSLException;
import net.bounceme.dur.jdbc.Title;
public final class Server {
private static final Logger log = Logger.getLogger(Server.class.getName());
public static void main(String[] args) throws Exception {
MyProps p = new MyProps();
int port = p.getServerPort();
RecordsQueueWrapper q = new RecordsQueueWrapper();
q.init(99);
new Server().startServer(port, false, q);
}
private void startServer(int port, boolean ssl, final RecordsQueueWrapper q) throws CertificateException, SSLException, InterruptedException {
final SslContext sslCtx;
if (ssl) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());
} else {
sslCtx = null;
}
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
p.addLast(
new ObjectEncoder(),
new ObjectDecoder(ClassResolvers.weakCachingConcurrentResolver(Title.class.getClassLoader())),
//new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
new ServerHandler(q)
);
}
});
b.bind(port).sync().channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
客户端:
package net.bounceme.dur.client.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
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 io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import java.util.logging.Logger;
import javax.net.ssl.SSLException;
import net.bounceme.dur.client.jdbc.Title;
/**
* Modification of {@link EchoClient} which utilizes Java object serialization.
*/
public final class Client {
private static final Logger log = Logger.getLogger(Client.class.getName());
static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
public Client() {
}
public void init() throws InterruptedException, SSLException {
MyProps p = new MyProps();
String host = p.getHost();
int port = p.getServerPort();
startClient(host, port, false);
}
private void startClient(final String host, final int port, final boolean SSL) throws SSLException, InterruptedException {
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE);
} else {
sslCtx = null;
}
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc(), host, port));
}
p.addLast(
new ObjectEncoder(),
//new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
new ObjectDecoder(ClassResolvers.weakCachingConcurrentResolver(Title.class.getClassLoader())),
new ClientHandler());
}
});
// Start the connection attempt.
b.connect(host, port).sync().channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
另见:
答案 0 :(得分:0)
请检查Title对象的包,在服务器和客户端中没有必须有不同的包名!例如:在服务器com.server.dto和客户端com.server.dto!
中