Netty wss 套接字客户端断开连接
Netty wss socket client drops connection
正在尝试设置基本 wss
客户端。通道已激活,但立即断开连接,无一例外。
客户:
class WebSocketClient(val uri: String) {
lateinit var ch: Channel
fun connect() {
val bootstrap = Bootstrap()
val uri: URI = URI.create(uri)
val handler = WebSocketClientHandler(WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, false, HttpHeaders.EMPTY_HEADERS, 1280000))
bootstrap.group(NioEventLoopGroup())
.channel(NioSocketChannel::class.java)
.handler(object : ChannelInitializer<SocketChannel>() {
override fun initChannel(ch: SocketChannel) {
val pipeline = ch.pipeline()
pipeline.addLast("http-codec", HttpClientCodec())
pipeline.addLast("aggregator", HttpObjectAggregator(65536))
pipeline.addLast("ws-handler", handler)
}
})
ch = bootstrap.connect(uri.host, 443).sync().channel()
handler.channelPromise.sync()
}
}
处理程序:
class WebSocketClientHandler(val handShaker: WebSocketClientHandshaker) : SimpleChannelInboundHandler<Any>() {
lateinit var channelPromise: ChannelPromise
override fun handlerAdded(ctx: ChannelHandlerContext) {
channelPromise = ctx.newPromise()
}
override fun channelActive(ctx: ChannelHandlerContext) {
handShaker.handshake(ctx.channel())
}
override fun channelRead0(ctx: ChannelHandlerContext, msg: Any) {
val ch = ctx.channel()
if (!handShaker.isHandshakeComplete) {
handShaker.finishHandshake(ch, msg as FullHttpResponse)
channelPromise.setSuccess()
return
}
val frame = msg as WebSocketFrame
if (frame is TextWebSocketFrame) {
println("text message: $frame")
} else if (frame is PongWebSocketFrame) {
println("pont message")
} else if (frame is CloseWebSocketFrame) {
ch.close()
} else {
println("unhandled frame: $frame")
}
}
}
处理程序调用流程:
handleAdded
channelRegistered
channelActive
channelReadComplete
channelInactive
channelUnregistered
handlerRemoved
有什么想念的吗?
您忘记添加 SSLHandler
,因为您正在连接到 https 端口 (443),所以需要此处理程序,因此远程服务器希望所有流量都被加密。向 https 端口发送未加密的消息具有未定义的行为,一些服务器将关闭您的连接,其他服务器将发送重定向回 https。
您可以使用以下方式添加 sslhandler:
java:
final SslContext sslCtx = SslContextBuilder.forClient()
// .trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();
pipeline.addLast("ssl-handler", sslCtx.newHandler(ch.alloc(), url.getHost(), 443));
// Your remaining code....
pipeline.addLast("http-codec", new HttpClientCodec())
正在尝试设置基本 wss
客户端。通道已激活,但立即断开连接,无一例外。
客户:
class WebSocketClient(val uri: String) {
lateinit var ch: Channel
fun connect() {
val bootstrap = Bootstrap()
val uri: URI = URI.create(uri)
val handler = WebSocketClientHandler(WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, false, HttpHeaders.EMPTY_HEADERS, 1280000))
bootstrap.group(NioEventLoopGroup())
.channel(NioSocketChannel::class.java)
.handler(object : ChannelInitializer<SocketChannel>() {
override fun initChannel(ch: SocketChannel) {
val pipeline = ch.pipeline()
pipeline.addLast("http-codec", HttpClientCodec())
pipeline.addLast("aggregator", HttpObjectAggregator(65536))
pipeline.addLast("ws-handler", handler)
}
})
ch = bootstrap.connect(uri.host, 443).sync().channel()
handler.channelPromise.sync()
}
}
处理程序:
class WebSocketClientHandler(val handShaker: WebSocketClientHandshaker) : SimpleChannelInboundHandler<Any>() {
lateinit var channelPromise: ChannelPromise
override fun handlerAdded(ctx: ChannelHandlerContext) {
channelPromise = ctx.newPromise()
}
override fun channelActive(ctx: ChannelHandlerContext) {
handShaker.handshake(ctx.channel())
}
override fun channelRead0(ctx: ChannelHandlerContext, msg: Any) {
val ch = ctx.channel()
if (!handShaker.isHandshakeComplete) {
handShaker.finishHandshake(ch, msg as FullHttpResponse)
channelPromise.setSuccess()
return
}
val frame = msg as WebSocketFrame
if (frame is TextWebSocketFrame) {
println("text message: $frame")
} else if (frame is PongWebSocketFrame) {
println("pont message")
} else if (frame is CloseWebSocketFrame) {
ch.close()
} else {
println("unhandled frame: $frame")
}
}
}
处理程序调用流程:
handleAdded
channelRegistered
channelActive
channelReadComplete
channelInactive
channelUnregistered
handlerRemoved
有什么想念的吗?
您忘记添加 SSLHandler
,因为您正在连接到 https 端口 (443),所以需要此处理程序,因此远程服务器希望所有流量都被加密。向 https 端口发送未加密的消息具有未定义的行为,一些服务器将关闭您的连接,其他服务器将发送重定向回 https。
您可以使用以下方式添加 sslhandler:
java:
final SslContext sslCtx = SslContextBuilder.forClient()
// .trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();
pipeline.addLast("ssl-handler", sslCtx.newHandler(ch.alloc(), url.getHost(), 443));
// Your remaining code....
pipeline.addLast("http-codec", new HttpClientCodec())