前面2文
讲了netty在http和socket的使用,下面讲讲netty如何使用websocket
websocket是html5提出来的一个东西,功能很强大,可以支持长连接,实现服务器向客户端的通信,这里不做过多的介绍,只说说netty如何使用websocket作为协议来通信
这里采用表单提交的时候,使用websocket的方式提交,具体请看代码:
ps:我这里的代码架构是这样的
服务器代码:
1 package com.bill.websocketdemo; 2 3 4 import io.netty.bootstrap.ServerBootstrap; 5 import io.netty.channel.ChannelFuture; 6 import io.netty.channel.EventLoopGroup; 7 import io.netty.channel.nio.NioEventLoopGroup; 8 import io.netty.channel.socket.nio.NioServerSocketChannel; 9 import io.netty.handler.logging.LogLevel; 10 import io.netty.handler.logging.LoggingHandler; 11 12 public class WebSocketServer { 13 14 public static void main(String[] args) throws Exception { 15 EventLoopGroup bossGroup = new NioEventLoopGroup(); 16 EventLoopGroup workerGroup = new NioEventLoopGroup(); 17 18 try{ 19 ServerBootstrap serverBootstrap = new ServerBootstrap(); 20 serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class). 21 handler(new LoggingHandler(LogLevel.INFO)).childHandler(new WebSocketChannelInitializer()); 22 23 ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); 24 channelFuture.channel().closeFuture().sync(); 25 } finally { 26 bossGroup.shutdownGracefully(); 27 workerGroup.shutdownGracefully(); 28 } 29 } 30 } 31 32 package com.bill.websocketdemo; 33 34 35 import io.netty.channel.ChannelHandlerContext; 36 import io.netty.channel.SimpleChannelInboundHandler; 37 import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; 38 39 public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { 40 41 @Override 42 protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception { 43 System.out.println("收到消息:" + textWebSocketFrame.text()); 44 channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("服务器随机数:" + Math.random())); 45 } 46 47 @Override 48 public void handlerAdded(ChannelHandlerContext ctx) throws Exception { 49 System.out.println("handlerAdded!!!"); 50 } 51 52 @Override 53 public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { 54 System.out.println("handlerRemoved!!!"); 55 } 56 } 57 58 package com.bill.websocketdemo; 59 60 61 import io.netty.channel.ChannelInitializer; 62 import io.netty.channel.ChannelPipeline; 63 import io.netty.channel.socket.SocketChannel; 64 import io.netty.handler.codec.http.HttpObjectAggregator; 65 import io.netty.handler.codec.http.HttpServerCodec; 66 import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; 67 import io.netty.handler.stream.ChunkedWriteHandler; 68 69 public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel> { 70 71 @Override 72 protected void initChannel(SocketChannel socketChannel) throws Exception { 73 74 ChannelPipeline pipeline = socketChannel.pipeline(); 75 76 pipeline.addLast(new HttpServerCodec()); 77 pipeline.addLast(new ChunkedWriteHandler()); 78 pipeline.addLast(new HttpObjectAggregator(8192)); 79 pipeline.addLast(new WebSocketServerProtocolHandler("/hello")); 80 81 pipeline.addLast(new WebSocketHandler()); 82 83 } 84 }
HTML代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>websocket</title> 6 </head> 7 <body> 8 9 <script type="text/javascript"> 10 var socket; 11 if(window.WebSocket) { 12 socket = new WebSocket("ws://localhost:8899/hello"); 13 socket.onmessage = function (event) { 14 var ta = document.getElementById("resp"); 15 ta.value = ta.value + " " + event.data; 16 } 17 18 socket.onopen = function (event) { 19 var ta = document.getElementById("resp"); 20 ta.value = "连接接开启!"; 21 } 22 23 socket.onclose = function (event) { 24 var ta = document.getElementById("resp"); 25 ta.value = ta.value + " " + "连接关闭!"; 26 } 27 } else { 28 alert("浏览器不支持websocket"); 29 } 30 31 function send(msg) { 32 if(!window.WebSocket) { 33 return; 34 } 35 36 if(socket.readyState == WebSocket.OPEN) { 37 socket.send(msg); 38 } else { 39 alert("连接未开启!") 40 } 41 } 42 43 </script> 44 45 <form onsubmit="return false;"> 46 47 <textarea id="message" style=" 400px; height: 200px"></textarea> 48 <input type="button" value="发送数据" onclick="send(this.form.message.value)"> 49 50 <h3> 服务器输出:</h3> 51 52 <textarea id="resp" style=" 400px; height: 300px"></textarea> 53 <input type="button" onclick="javascript: document.getElementById('resp').value = ''" value="清空内容"> 54 </form> 55 56 57 </body> 58 </html>
请注意:
运行的时候,先执行WebSocketServer的main方法,然后再run src/main/webapp/test.html ,这样 idea会自动启动一个页面
启动完服务器后,会在浏览器上看到页面:
服务器出现信息:
发送数据:
服务器:
完整代码下载: