基于Netty实现安全认证的WebSocket(wss)客户端

1.Netty服务端

服务端代码参考【基于Netty实现安全认证的WebSocket(wss)服务端-CSDN博客

2.Netty客户端

客户端代码参考【基于Netty实现WebSocket客户端-CSDN博客】中两种都可以;这里用的是第一种。

新增SslHandler的代码:

java 复制代码
SslContext sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
...
pipeline.addLast(sslCtx.newHandler(sc.alloc(), webSocketURL.getHost(), webSocketURL.getPort()));

服务端地址的协议头调整为wss

java 复制代码
final URI webSocketURL = new URI("wss://127.0.0.1:7070/helloWs");

完整的客户端代码如下:

java 复制代码
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.stream.ChunkedWriteHandler;
import lombok.extern.slf4j.Slf4j;

import java.net.URI;
import java.util.concurrent.CountDownLatch;

/**
 * https://blog.csdn.net/a1053765496/article/details/130701218
 * 基于Netty快速实现WebSocket客户端,不手动处理握手
 */
@Slf4j
public class SimpleWssClient {

    final CountDownLatch latch = new CountDownLatch(1);

    public static void main(String[] args) throws Exception {
        SimpleWssClient client = new SimpleWssClient();
        client.test();
    }

    public void test() throws Exception {
        Channel dest = dest();
        latch.await();
        dest.writeAndFlush(new TextWebSocketFrame("CountDownLatch完成后发送的消息"));
    }

    public Channel dest() throws Exception {
        final URI webSocketURL = new URI("wss://127.0.0.1:7070/helloWs");

        EventLoopGroup group = new NioEventLoopGroup();
        SslContext sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
        Bootstrap boot = new Bootstrap();
        boot.option(ChannelOption.SO_KEEPALIVE, true)
            .option(ChannelOption.TCP_NODELAY, true)
            .group(group)
            .handler(new LoggingHandler(LogLevel.INFO))
            .channel(NioSocketChannel.class)
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel sc) throws Exception {
                    ChannelPipeline pipeline = sc.pipeline();
                    pipeline.addLast(sslCtx.newHandler(sc.alloc(), webSocketURL.getHost(), webSocketURL.getPort()));
                    pipeline.addLast(new HttpClientCodec());
                    pipeline.addLast(new ChunkedWriteHandler());
                    pipeline.addLast(new HttpObjectAggregator(64 * 1024));
                    pipeline.addLast(new WebSocketClientProtocolHandler(WebSocketClientHandshakerFactory
                        .newHandshaker(webSocketURL, WebSocketVersion.V13, null, false, new DefaultHttpHeaders())));
                    pipeline.addLast(new SimpleChannelInboundHandler<TextWebSocketFrame>() {

                        @Override
                        protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg)
                            throws Exception {
                            System.err.println(" 客户端收到消息======== " + msg.text());
                        }

                        @Override
                        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                            if (WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_COMPLETE
                                .equals(evt)) {
                                log.info(ctx.channel().id().asShortText() + " 握手完成!");
                                latch.countDown();
                                send(ctx.channel());
                            }
                            super.userEventTriggered(ctx, evt);
                        }
                    });

                }
            });

        ChannelFuture cf = boot.connect(webSocketURL.getHost(), webSocketURL.getPort()).sync();

        return cf.channel();
    }

    public static void send(Channel channel) {
        final String textMsg = "握手完成后直接发送的消息";

        if (channel != null && channel.isActive()) {
            TextWebSocketFrame frame = new TextWebSocketFrame(textMsg);
            channel.writeAndFlush(frame).addListener((ChannelFutureListener) channelFuture -> {
                if (channelFuture.isDone() && channelFuture.isSuccess()) {
                    log.info("     ================= 发送成功.");
                } else {
                    channelFuture.channel().close();
                    log.info("     ================= 发送失败. cause = " + channelFuture.cause());
                    channelFuture.cause().printStackTrace();
                }
            });
        } else {
            log.error("消息发送失败! textMsg = " + textMsg);
        }
    }

}

参考:利用netty开发webScoketClient(支持wss协议,客户端、服务端心跳实现)_websocketclient-CSDN博客

相关推荐
daidaidaiyu3 天前
一文学习和实践 当下互联网安全的基石 - TLS 和 SSL
java·netty
enjoy编程4 天前
Spring boot 4 探究netty的关键知识点
spring boot·设计模式·reactor·netty·多线程
ps酷教程7 天前
HttpData
http·netty
ps酷教程11 天前
ChunkedWriteHandler源码浅析
java·netty·分块传输
奕辰杰14 天前
Netty私人学习笔记
笔记·学习·netty·网络通信·nio
ps酷教程17 天前
HttpObjectDecoder源码浅析
java·netty·httpaggregator
魔芋红茶21 天前
Netty 简易指南
java·开发语言·netty
ps酷教程21 天前
HttpAggregator源码浅析
netty·httpaggregator
9527出列25 天前
Netty实战--使用netty构建WebSocket服务
websocket·网络协议·netty