2017-08-15 481 views
0

尝试设置基本的wss客户端。频道已启动,但立即断开连接,无任何例外。Netty 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 

有什么我错过?

+0

你如何让你的组变量? – Ferrybig

+0

@Ferrybig更新了代码。没有什么特别的关于'group',只是创建'NioEventLoopGroup'的新实例。 – eleven

回答

1

您忘了添加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()) 
+0

很好的解释!确实需要'ssl-handler'。谢谢。 – eleven