java websocket netty_基于netty实现的websocket

一、运行效果

java websocket netty_基于netty实现的websocket_第1张图片

java websocket netty_基于netty实现的websocket_第2张图片

二、Netty使用场景

1.高性能领域

2.多线程并发领域

3.异步通信领域

三、实现过程

①、添加netty相关jar

io.netty

netty-all

5.0.0.Alpha1

②、添加netty配置类public class NettyConfig {

/**

* 存储每一个客户端接入进来时的channel对象

*/

public static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

}

③、添加websocket核心业务处理类private WebSocketServerHandshaker handshaker;

private static final String WEB_SOCKET_URL = "ws://localhost:8888/websocket";

//客户端与服务端创建连接的时候调用

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception {

NettyConfig.group.add(ctx.channel());

System.out.println("客户端与服务端连接开启...");

}

//客户端与服务端断开连接的时候调用

@Override

public void channelInactive(ChannelHandlerContext ctx) throws Exception {

NettyConfig.group.remove(ctx.channel());

System.out.println("客户端与服务端连接关闭...");

}

//服务端接收客户端发送过来的数据结束之后调用

@Override

public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

ctx.flush();

}

//工程出现异常的时候调用

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

cause.printStackTrace();

ctx.close();

}

//服务端处理客户端websocket请求的核心方法

@Override

protected void messageReceived(ChannelHandlerContext context, Object msg) throws Exception {

//处理客户端向服务端发起http握手请求的业务

if (msg instanceof FullHttpRequest) {

handHttpRequest(context,  (FullHttpRequest)msg);

}else if (msg instanceof WebSocketFrame) { //处理websocket连接业务

handWebsocketFrame(context, (WebSocketFrame)msg);

}

}

/**

* 处理客户端与服务端之前的websocket业务

* @param ctx

* @param frame

*/

private void handWebsocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame){

//判断是否是关闭websocket的指令

if (frame instanceof CloseWebSocketFrame) {

handshaker.close(ctx.channel(), (CloseWebSocketFrame)frame.retain());

}

//判断是否是ping消息

if (frame instanceof PingWebSocketFrame) {

ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));

return;

}

//判断是否是二进制消息,如果是二进制消息,抛出异常

if( ! (frame instanceof TextWebSocketFrame) ){

System.out.println("目前我们不支持二进制消息");

throw new RuntimeException("【"+this.getClass().getName()+"】不支持消息");

}

//返回应答消息

//获取客户端向服务端发送的消息

String request = ((TextWebSocketFrame) frame).text();

System.out.println("服务端收到客户端的消息====>>>" + request);

TextWebSocketFrame tws = new TextWebSocketFrame(new Date().toString()

+ ctx.channel().id()

+ " ===>>> "

+ request);

//群发,服务端向每个连接上来的客户端群发消息

NettyConfig.group.writeAndFlush(tws);

}

④、websocket初始化时各个组件的类实现public class MyWebSocketChannelHandler extends ChannelInitializer {

@Override

protected void initChannel(SocketChannel e) throws Exception {

e.pipeline().addLast("http-codec", new HttpServerCodec());

e.pipeline().addLast("aggregator", new HttpObjectAggregator(65536));

e.pipeline().addLast("http-chunked", new ChunkedWriteHandler());

e.pipeline().addLast("handler", new MyWebSocketHandler());

}

}

四、项目结构图

java websocket netty_基于netty实现的websocket_第3张图片

五、补充

java websocket netty_基于netty实现的websocket_第4张图片

你可能感兴趣的:(java,websocket,netty)