從阿里雲申請證書獲得以下幾個文件java
須要先用 openssl
將.pfx
轉成 .key
node
openssl pkcs12 -in server.pfx -nocerts -nodes -out server.key
提示須要輸入密碼,密碼在 pfx-password.txt
文件裏。
最終須要 2149826361xxxx.pem
文件和 server.key
文件服務器
Server.javaapp
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.javaide
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.javaoop
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("連接異常"); } }