- Handler:
package com.jay.websocket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.CharsetUtil;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger logger=Logger.getLogger(WebSocketServerHandler.class.getName());
private WebSocketServerHandshaker webSocketServerHandshaker;
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
//若是http接入
if(msg instanceof FullHttpRequest)
handleHttpRequest(ctx,(FullHttpRequest)msg);
//如果是WebSocket接入
else if(msg instanceof WebSocketFrame)
handleWebSocketFrame(ctx,(WebSocketFrame)msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
private void handleHttpRequest(ChannelHandlerContext ctx,FullHttpRequest req) throws Exception{
//如果连接失败或者不是socket连接
if(!req.getDecoderResult().isSuccess()||(!"websocket".equals(req.headers().get("Upgrade")))){
sendHttpResponse(ctx,req,new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
return;
}
//握手工厂
WebSocketServerHandshakerFactory wsFactory=new WebSocketServerHandshakerFactory(
"ws://localhost:8080/websocket",null,false
);
//握手连接
webSocketServerHandshaker=wsFactory.newHandshaker(req);
if(webSocketServerHandshaker!=null){
WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
}else{
webSocketServerHandshaker.handshake(ctx.channel(),req);
}
}
private void handleWebSocketFrame(ChannelHandlerContext ctx,WebSocketFrame frame){
if(frame instanceof CloseWebSocketFrame){
webSocketServerHandshaker.close(ctx.channel(),(CloseWebSocketFrame)frame.retain());
return;
}
if(frame instanceof PingWebSocketFrame){
ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
return;
}
if(!(frame instanceof TextWebSocketFrame)){
throw new UnsupportedOperationException(String.format("%s frame types not supported",frame.getClass().getName()));
}
//获取内容
String request=((TextWebSocketFrame)frame).text();
if(logger.isLoggable((Level.FINE))){
logger.fine(String.format("%s receive %s",ctx.channel(),request));
ctx.channel().write(
new TextWebSocketFrame(request+
",欢迎使用Netty WebSocket服务,现在时间是:"
+new Date().toString())
);
}
}
private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res){
if(res.getStatus().code()!=200){
ByteBuf byteBuf= Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8);
res.content().writeBytes(byteBuf);
byteBuf.release();
}
ChannelFuture f=ctx.channel().writeAndFlush(res);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
- Server:
package com.jay.websocket;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;
public class WebSocketServer {
public void run(int port)throws Exception{
EventLoopGroup boss=new NioEventLoopGroup();
EventLoopGroup worker=new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap=new ServerBootstrap();
serverBootstrap.group(boss,worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//将请求和应答信息编码或者解码成HTTP消息
socketChannel.pipeline().addLast("http-codec",new HttpServerCodec());
//将HTTP消息的多个部分组合成一条完整的HTTP消息
socketChannel.pipeline().addLast("aggregator",new HttpObjectAggregator(65536));
//向客户端发送HTML5文件。
socketChannel.pipeline().addLast("http-chunked",new ChunkedWriteHandler());
socketChannel.pipeline().addLast("handler",new WebSocketServerHandler());
}
});
Channel channel=serverBootstrap.bind(port).sync().channel();
System.out.println("WebSocket启动,端口为:"+ port );
channel.closeFuture().sync();
}finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception{
new WebSocketServer().run(8081);
}
}
再配合html来测试就可以了