@@ -75,12 +75,13 @@ private void upgrade(Channel channel, NettyResponseFuture<?> future, WebSocketUp
75
75
// if it comes in the same frame as the HTTP Upgrade response
76
76
Channels .setAttribute (channel , future );
77
77
78
+ handler .setWebSocket (new NettyWebSocket (channel , responseHeaders .getHeaders ()));
78
79
channelManager .upgradePipelineForWebSockets (channel .pipeline ());
79
80
80
81
// We don't need to synchronize as replacing the "ws-decoder" will
81
82
// process using the same thread.
82
83
try {
83
- handler .openWebSocket ( new NettyWebSocket ( channel , responseHeaders . getHeaders ()) );
84
+ handler .onOpen ( );
84
85
} catch (Exception ex ) {
85
86
logger .warn ("onSuccess unexpected exception" , ex );
86
87
}
@@ -105,7 +106,7 @@ public void handleRead(Channel channel, NettyResponseFuture<?> future, Object e)
105
106
logger .debug ("\n \n Request {}\n \n Response {}\n " , httpRequest , response );
106
107
}
107
108
108
- WebSocketUpgradeHandler handler = WebSocketUpgradeHandler . class . cast ( future .getAsyncHandler () );
109
+ WebSocketUpgradeHandler handler = ( WebSocketUpgradeHandler ) future .getAsyncHandler ();
109
110
HttpResponseStatus status = new NettyResponseStatus (future .getUri (), response , channel );
110
111
HttpResponseHeaders responseHeaders = new HttpResponseHeaders (response .headers ());
111
112
@@ -123,15 +124,23 @@ public void handleRead(Channel channel, NettyResponseFuture<?> future, Object e)
123
124
final WebSocketFrame frame = (WebSocketFrame ) e ;
124
125
WebSocketUpgradeHandler handler = (WebSocketUpgradeHandler ) future .getAsyncHandler ();
125
126
NettyWebSocket webSocket = (NettyWebSocket ) handler .onCompleted ();
126
- handleFrame (channel , frame , handler , webSocket );
127
+ // retain because we might buffer the frame
128
+ frame .retain ();
129
+ if (handler .isOpen ()) {
130
+ handleFrame (channel , frame , handler , webSocket );
131
+ } else {
132
+ // WebSocket hasn't been open yet, but upgrading the pipeline triggered a read and a frame was sent along the HTTP upgrade response
133
+ // as we want to keep sequential order (but can't notify user of open before upgrading so he doesn't to try send immediately), we have to buffer
134
+ handler .bufferFrame (() -> handleFrame (channel , frame , handler , webSocket ));
135
+ }
127
136
128
137
} else if (!(e instanceof LastHttpContent )) {
129
138
// ignore, end of handshake response
130
139
logger .error ("Invalid message {}" , e );
131
140
}
132
141
}
133
142
134
- private void handleFrame (Channel channel , WebSocketFrame frame , WebSocketUpgradeHandler handler , NettyWebSocket webSocket ) throws Exception {
143
+ private void handleFrame (Channel channel , WebSocketFrame frame , WebSocketUpgradeHandler handler , NettyWebSocket webSocket ) {
135
144
if (frame instanceof TextWebSocketFrame ) {
136
145
webSocket .onTextFrame ((TextWebSocketFrame ) frame );
137
146
@@ -150,6 +159,8 @@ private void handleFrame(Channel channel, WebSocketFrame frame, WebSocketUpgrade
150
159
} else if (frame instanceof PongWebSocketFrame ) {
151
160
webSocket .onPong ((PongWebSocketFrame ) frame );
152
161
}
162
+ // release because we had to retain in case the frame had to be buffered
163
+ frame .release ();
153
164
}
154
165
155
166
@ Override
0 commit comments