1

被 Apple_Sa 的栗子坑的不行,决定自己写个教程以供未来的自己参考

证书

从阿里云申请证书得到如下几个文件

clipboard.png

需要先用 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("链接异常");
    }
}

远程智力英雄
239 声望30 粉丝

等我以后写不了程序了就去做木匠