代码之家  ›  专栏  ›  技术社区  ›  eleven

Netty wss socket客户端断开连接

  •  0
  • eleven  · 技术社区  · 9 年前

    正在尝试设置basic 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
    

    有什么我错过的吗?

    1 回复  |  直到 9 年前
        1
  •  1
  •   Ferrybig    9 年前

    您忘记添加 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())
    
    推荐文章