我正在Angular 7 webapp中使用一个websocket。这个想法是让网络应用由“节点”提供-例如在地址
上http://localhost:4200/
和websocket在Netty / Java应用提供服务的另一个地址和端口上。
在网络应用程序上,我导航到网络套接字的页面。有一个文本框用于输入websocket的地址和按钮:'Connect'-将我们连接到web-socket服务器。例如,对此地址进行测试可以正常工作:
ws://echo.websocket.org // works - we get a response
or
ws://echo.websocket.org:80 // works - we get a response
相反,我想让Netty服务器来服务websocket。我启动服务器-在以下地址提供服务:
http://localhost:8081/
,运行正常。 (我可以从单独的浏览器窗口和服务器在此地址和端口上提供的websocket页面进行连接。
但是现在我想从我的Web应用程序在localhost:4200 /上连接到Netty服务器。因此,我将此地址提供给套接字连接;
ws://localhost:8081/
然后单击“连接”。
Netty服务器对此日志做出反应(所有行同时显示):
Feb 16, 2019 7:26:20 AM io.netty.handler.logging.LoggingHandler channelRead
INFO: [id: 0xfd77a1f7, L:/0:0:0:0:0:0:0:0:8081] READ: [id: 0x24ad1bc1, L:/127.0.0.1:8081 - R:/127.0.0.1:51928]
Feb 16, 2019 7:26:20 AM io.netty.handler.logging.LoggingHandler channelReadComplete
INFO: [id: 0xfd77a1f7, L:/0:0:0:0:0:0:0:0:8081] READ COMPLETE
Websocke channel Active:[id: 0x24ad1bc1, L:/127.0.0.1:8081 - R:/127.0.0.1:51928]
Websocke channel Inactive:[id: 0x24ad1bc1, L:/127.0.0.1:8081 ! R:/127.0.0.1:51928]
Websocke channel Unregistered:[id: 0x24ad1bc1, L:/127.0.0.1:8081 ! R:/127.0.0.1:51928]
这可能意味着通信正常,但是Netty不接受并且正在关闭websocket。
这些是我在Netty管道中的处理程序:
new HttpServerCodec());
new HttpObjectAggregator(65536));
new WebSocketServerCompressionHandler());
new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
// Next handler serves index.html page
// ... extends SimpleChannelInboundHandler<FullHttpRequest>
// @Override
// protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
new WebSocketIndexPageHandlerA1(WEBSOCKET_PATH));
// Next handler handles websocket communication
// ... extends SimpleChannelInboundHandler<WebSocketFrame>
// @Override
// protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
new WebSocketFrameHandlerA1());
我们如何让Netty接受此websocket请求并将流向下传递到我的最后一个处理程序-Web套接字消息处理程序-WebSocketFrameHandlerA1,以便它可以答复Websocket客户端-无论它们来自何处?>
答案 0 :(得分:0)
这个问题有一个相当简单和合理的答案。我们只需要为Netty的管道机智处理程序配备对应于来自客户端的预期流量(HTTP / Websocket等)。
因此,如果我们尝试使用以下方式连接到Netty:
ws://localhost:8081/
服务器将收到初始HTTP请求-如下所示:
GET / HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://localhost:4200
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: XVXVXS%GDDD+lDfDS==
Connection: keep-alive, Upgrade
Cookie: _ga=GA1.1.1146780314.5634479786
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Connection : keep-alive, Upgrade
Upgrade : websocket
我们必须确保管道中有适当的处理程序,以处理初始HTTP请求,然后升级/切换到websocket处理程序。在这种情况下,初始管道可以像这样简单:
pipeline.addLast("httpServerCodec", new HttpServerCodec());
pipeline.addLast("httpHandler", new HttpServerHandler());
HttpServerHandler中的其他内容包括:
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof HttpRequest) {
HttpRequest httpRequest = (HttpRequest) msg;
HttpHeaders headers = httpRequest.headers();
if (headers.get(HttpHeaderNames.CONNECTION).toUpperCase().contains("UPGRADE") &&
headers.get(HttpHeaderNames.UPGRADE).toUpperCase().contains("WEBSOCKET")) {
// Replace the HTTP handler with a websocket handler
// in the existing pipeline to handle WebSocket Messages
ctx.pipeline().replace(this, "websocketHandler", new WebSocketHandler());
//Do the Handshake to upgrade connection from HTTP to WebSocket protocol
handleHandshake(ctx, httpRequest);
}
...
}
在您的websocket处理程序中,插入客户端和服务器之间的数据交换逻辑。