forked from lets-blade/blade
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request lets-blade#309 from ydq/dev
fixed lets-blade#308
- Loading branch information
Showing
3 changed files
with
69 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 64 additions & 35 deletions
99
src/main/java/com/blade/server/netty/WebSocketHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,95 @@ | ||
package com.blade.server.netty; | ||
|
||
import com.blade.Blade; | ||
import com.blade.mvc.handler.ExceptionHandler; | ||
import com.blade.mvc.websocket.WebSocketContext; | ||
import io.netty.channel.ChannelHandler; | ||
import io.netty.channel.ChannelHandlerContext; | ||
import io.netty.channel.SimpleChannelInboundHandler; | ||
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; | ||
import io.netty.handler.codec.http.websocketx.WebSocketFrame; | ||
import io.netty.handler.codec.http.HttpRequest; | ||
import io.netty.handler.codec.http.websocketx.*; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import java.util.Objects; | ||
|
||
/** | ||
* Http Server Handler | ||
* | ||
* @author biezhi | ||
* 2017/5/31 | ||
* @author biezhi,darren | ||
* 2017/5/31, | ||
*/ | ||
@Slf4j | ||
@ChannelHandler.Sharable | ||
public class WebSocketHandler extends SimpleChannelInboundHandler<WebSocketFrame> { | ||
public class WebSocketHandler extends SimpleChannelInboundHandler<Object> { | ||
|
||
private WebSocketServerHandshaker handshaker; | ||
private Blade blade; | ||
|
||
private com.blade.mvc.handler.WebSocketHandler webSocketHandler; | ||
private ExceptionHandler exceptionHandler; | ||
|
||
WebSocketHandler(Blade blade) { | ||
this.webSocketHandler = blade.webSocketHandler(); | ||
public WebSocketHandler(Blade blade) { | ||
this.blade = blade; | ||
} | ||
|
||
@Override | ||
public void channelActive(ChannelHandlerContext ctx) throws Exception { | ||
WebSocketContext webSocketContext = new WebSocketContext(ctx); | ||
webSocketHandler.onConnect(webSocketContext); | ||
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { | ||
if (msg instanceof HttpRequest) { | ||
handleHttpRequest(ctx, (HttpRequest) msg); | ||
} else if (msg instanceof WebSocketFrame) { | ||
handleWebSocketFrame(ctx, (WebSocketFrame) msg); | ||
} else { | ||
ctx.fireChannelRead(msg); | ||
} | ||
} | ||
|
||
@Override | ||
public void channelInactive(ChannelHandlerContext ctx) throws Exception { | ||
WebSocketContext webSocketContext = new WebSocketContext(ctx); | ||
webSocketHandler.onDisConnect(webSocketContext); | ||
public void channelReadComplete(ChannelHandlerContext ctx) { | ||
ctx.flush(); | ||
} | ||
|
||
@Override | ||
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) { | ||
WebSocketContext webSocketContext = new WebSocketContext(ctx); | ||
if (frame instanceof TextWebSocketFrame) { | ||
// Send the uppercase string back. | ||
String request = ((TextWebSocketFrame) frame).text(); | ||
webSocketContext.setReqText(request); | ||
webSocketHandler.onText(webSocketContext); | ||
private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) { | ||
if (isWebSocketPath(req)) { | ||
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(req.uri(), null, true); | ||
this.handshaker = wsFactory.newHandshaker(req); | ||
if (this.handshaker == null) { | ||
//Return that we need cannot not support the web socket version | ||
WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); | ||
} else { | ||
this.handshaker.handshake(ctx.channel(), req); | ||
this.blade.webSocketHandler().onConnect(new WebSocketContext(ctx)); | ||
} | ||
} else { | ||
String message = "unsupported frame type: " + frame.getClass().getName(); | ||
throw new UnsupportedOperationException(message); | ||
ctx.fireChannelRead(req); | ||
} | ||
} | ||
|
||
@Override | ||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { | ||
if (null != exceptionHandler) { | ||
exceptionHandler.handle((Exception) cause); | ||
} else { | ||
log.error("Blade Invoke Error", cause); | ||
/** | ||
* Only supported TextWebSocketFrame | ||
* | ||
* @param ctx | ||
* @param frame | ||
*/ | ||
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { | ||
if (frame instanceof CloseWebSocketFrame) { | ||
this.blade.webSocketHandler().onDisConnect(new WebSocketContext(ctx)); | ||
this.handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain()); | ||
return; | ||
} | ||
ctx.close(); | ||
if (frame instanceof PingWebSocketFrame) { | ||
ctx.channel().write(new PongWebSocketFrame(frame.content().retain())); | ||
return; | ||
} | ||
|
||
if (!(frame instanceof TextWebSocketFrame)) { | ||
throw new UnsupportedOperationException("unsupported frame type: " + frame.getClass().getName()); | ||
} | ||
WebSocketContext wsCtx = new WebSocketContext(ctx); | ||
wsCtx.setReqText(((TextWebSocketFrame) frame).text()); | ||
this.blade.webSocketHandler().onText(wsCtx); | ||
} | ||
|
||
|
||
private boolean isWebSocketPath(HttpRequest req){ | ||
return req != null | ||
&& Objects.equals(req.uri(),blade.webSocketPath()) | ||
&& req.decoderResult().isSuccess() | ||
&& "websocket".equals(req.headers().get("Upgrade")); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters