基于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博客

相关推荐
Derek_Smart12 天前
基于Netty与Spring Integration的高并发工业物联网网关架构设计与实现
spring boot·物联网·netty
迢迢星万里灬13 天前
Java求职者面试指南:微服务技术与源码原理深度解析
java·spring cloud·微服务·dubbo·netty·分布式系统·面试指南
Y_3_715 天前
Netty实战:从核心组件到多协议实现(超详细注释,udp,tcp,websocket,http完整demo)
linux·运维·后端·ubuntu·netty
安徽杰杰22 天前
能源即服务:智慧移动充电桩的供给模式创新
netty
安徽杰杰23 天前
新基建浪潮下:中国新能源汽车充电桩智慧化建设与管理实践
netty
迢迢星万里灬24 天前
Java求职者面试:微服务技术与源码原理深度解析
java·spring cloud·微服务·dubbo·netty·分布式系统
触角云科技24 天前
掌上充电站:基于APP/小程序的新能源汽车智慧充电管理
netty
安徽杰杰24 天前
智慧充电:新能源汽车智慧充电桩的发展前景受哪些因素影响?
netty
漫步者TZ1 个月前
【Netty系列】解决TCP粘包和拆包:LengthFieldBasedFrameDecoder
java·网络协议·tcp/ip·netty
安徽杰杰1 个月前
智慧赋能:移动充电桩的能源供给革命与便捷服务升级
netty