被 Apple_Sa 的栗子坑的不行,决定自己写个教程以供未来的自己参考
证书
从阿里云申请证书得到如下几个文件
需要先用 openssl
将.pfx
转成 .key
openssl pkcs12 -in server.pfx -nocerts -nodes -out server.key
提示需要输入密码,密码在 pfx-password.txt
文件里。
最终需要 2149826361xxxx.pem
文件和 server.key
文件
netty服务器
Server.java
File file = new File("2149826361xxxx.pem");
File key = new File("server.key");
try {
SslContext sslCtx = SslContextBuilder.forServer(file, key).build();
open(sslCtx);
} catch (SSLException e) {
e.printStackTrace();
}
private void open(SslContext sslCtx) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new Initializer(sslCtx))
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture ch = b.bind(port).sync();
ch.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
Initializer.java
public class Initializer extends ChannelInitializer<NioSocketChannel> {
private final SslContext sslCtx;
public Initializer (SslContext sslCtx) {
this.sslCtx = sslCtx;
}
protected void initChannel(NioSocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new ChunkedWriteHandler());
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler("/chat", null, true, 1024 * 10));
pipeline.addLast(new MessageToMessageDecoder<WebSocketFrame>() {
@Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> objs) throws Exception {
ByteBuf buf = frame.content();
objs.add(buf);
buf.retain();
}
});
pipeline.addLast(new MessageToMessageEncoder<MessageLiteOrBuilder>() {
@Override
protected void encode(ChannelHandlerContext ctx, MessageLiteOrBuilder msg, List<Object> out) throws Exception {
ByteBuf result = null;
if (msg instanceof MessageLite) {
result = wrappedBuffer(((MessageLite) msg).toByteArray());
}
if (msg instanceof MessageLite.Builder) {
result = wrappedBuffer(((MessageLite.Builder) msg).build().toByteArray());
}
WebSocketFrame frame = new BinaryWebSocketFrame(result);
out.add(frame);
}
});
pipeline.addLast(new ProtobufDecoder(ReqPB.PBdata.getDefaultInstance()));
pipeline.addLast(new ProtoHandler());
}
}
ProtoHandler.java
public class ProtoHandler extends SimpleChannelInboundHandler<ReqPB.PBdata> {
private static Logger log = Logger.getLogger(ProtoHandler.class);
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ReqPB.PBdata msg) {
log.info("收到消息:" + msg);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
log.info("断开链接");
super.channelInactive(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.info("链接异常");
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。