我尝试建立一个websocketconnection。但是我的websocketcontent一直因为不可读而被拒绝。现在,我使用以下处理程序堆栈建立连接:
p.addLast(ClientSslHandler),
p.addLast(new HttpClientCodec()),
p.addLast(new HttpObjectAggregator(8192)),
p.addLast(new WebSocketClientProtocolHandler(...)),
p.addlast(new myHandler);
问题是(我认为)HttpClientCodec一直将我的Websocketframes编码为Httpframes。 这就是为什么我认为我可以使用HttpClientUpgradeHandler来处理握手,然后更改为纯Websocketconnection的原因。这是可行的解决方案吗?还是有其他解决方法?
编辑:将WebSocketClientProtocolHandler更改为HttpClientUpgradeHandler
Edit2: 公共类ShipSocketClient { 静态最终字符串URL = System.getProperty(“ url”,“ wss://10.2.3.44:4712”);
public static void main(String[] args) throws Exception{
URI uri = new URI(URL);
String scheme = uri.getScheme() == null? "ws" : uri.getScheme();
final String host = uri.getHost() == null? "127.0.0.1" : uri.getHost();
final int port;
if (uri.getPort() == -1) {
if ("ws".equalsIgnoreCase(scheme)) {
port = 80;
} else if ("wss".equalsIgnoreCase(scheme)) {
port = 443;
} else {
port = -1;
}
} else {
port = uri.getPort();
}
if (!"ws".equalsIgnoreCase(scheme) && !"wss".equalsIgnoreCase(scheme)) {
System.err.println("Only WS(S) is supported.");
return;
}
final boolean ssl = "wss".equalsIgnoreCase(scheme);
final SslContext sslCtx;
if (ssl) {
List<String> CipherList = new ArrayList<String>();
CipherList.add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
//CipherList.add("TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8");
CipherList.add("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
File vidksFile = new File("C:\\Users\\LETTAU\\Videos\\key.pem");
File vidcertFile = new File("C:\\Users\\LETTAU\\Videos\\cert.pem");
//CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
sslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.ciphers(CipherList)
.protocols("TLSv1.2")
.clientAuth(ClientAuth.REQUIRE)
.keyManager(vidcertFile, vidksFile)
.build();
}
else{
sslCtx = null;
}
EventLoopGroup group = new NioEventLoopGroup();
try{
WebSocketClientHandshaker wsHandShaker = WebSocketClientHandshakerFactory.newHandshaker(
uri, WebSocketVersion.V13, "ship", false, new DefaultHttpHeaders());
WebSocketClientProtocolHandler wsPrClHandler = new WebSocketClientProtocolHandler(wsHandShaker,true);
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
SslHandler ClientSslHandler = sslCtx.newHandler(ch.alloc(), host, port);
HttpClientCodec sourceCodec = new HttpClientCodec();
//New approach with HttpClientUpgradeHandler
//ShipClientProtocolHandler is a class which extends WebSocketClientProtocolHandler implements HttpClientUpgradeHandler.UpgradeCodec
HttpClientUpgradeHandler httpToWsUpgrader = new HttpClientUpgradeHandler(sourceCodec, new ShipClientProtocolHandler(wsHandShaker,true), 8096);
if (sslCtx != null) {
p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(ClientSslHandler);
}
p.addLast(
new LoggingHandler(LogLevel.INFO),
sourceCodec,
new HttpObjectAggregator(8192),
//httpToWsUpgrader,
new LoggingHandler(LogLevel.INFO),
wsPrClHandler);
}
}
);
Channel ch = b.connect(uri.getHost(), port).sync().channel();
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String msg = console.readLine();
if (msg == null) {
break;
} else if ("ping".equals(msg.toLowerCase())) {
WebSocketFrame frame = new PingWebSocketFrame(Unpooled.wrappedBuffer(new byte[] { 8, 1, 8, 1 }));
ch.writeAndFlush(frame);
} else if ("cmi".equals(msg.toLowerCase())) {
ByteBuf bBuf = Unpooled.buffer(16);
bBuf.writeByte(0);
bBuf.writeByte(0);
BinaryWebSocketFrame bytebuffer = new BinaryWebSocketFrame(bBuf);
ch.writeAndFlush(bytebuffer);
} else if ("cdp".equals(msg.toLowerCase())) {
ByteBuf bBuf = Unpooled.buffer(1000);
//bBuf.writeByte(0);
//bBuf.writeByte(1);
ByteBufUtil.writeUtf8(bBuf,"{\"connectionHello\":[{\"phase\":\"ready\"},{\"waiting\":60000}]}");
BinaryWebSocketFrame bytebuffer = new BinaryWebSocketFrame(bBuf);
ch.writeAndFlush(bytebuffer);
} else {
WebSocketFrame frame = new TextWebSocketFrame(msg);
ch.writeAndFlush(frame);
}
}
} finally {
group.shutdownGracefully();
}
}
Edit3:关于为什么我认为HttpClientCodec是问题的一些其他信息: 这是收到的包裹的样子:
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 88 1d 11 30 53 54 41 54 45 5f 57 41 49 54 5f 43 |...0STATE_WAIT_C|
|00000010| 4c 4f 53 45 5f 43 4f 4e 4e 45 43 54 49 4f 4e |LOSE_CONNECTION |
+--------+-------------------------------------------------+----------------+
这是外发包裹的样子:
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 82 9d 12 1e 8c 5a 12 1f f7 78 71 71 e2 34 77 7d |.....Z...xqq.4w}|
|00000010| f8 33 7d 70 c4 3f 7e 72 e3 78 28 3c fe 3f 73 7a |.3}p.?~r.x(<.?sz|
|00000020| f5 78 6f |.xo |
+--------+-------------------------------------------------+----------------+
答案 0 :(得分:0)
如果要升级到WebSocket,则应使用WebSocketClientHandshaker
。
Netty本身包含一个示例: