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