基於websocket的netty demo
阿新 • • 發佈:2019-02-07
前面2文
講了netty在http和socket的使用,下面講講netty如何使用websocket
websocket是html5提出來的一個東西,功能很強大,可以支援長連線,實現伺服器向客戶端的通訊,這裡不做過多的介紹,只說說netty如何使用websocket作為協議來通訊
這裡採用表單提交的時候,使用websocket的方式提交,具體請看程式碼:
ps:我這裡的程式碼架構是這樣的
伺服器程式碼:
package com.bill.websocketdemo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; public class WebSocketServer { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class). handler(new LoggingHandler(LogLevel.INFO)).childHandler(new WebSocketChannelInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
package com.bill.websocketdemo; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception { System.out.println("收到訊息:" + textWebSocketFrame.text()); channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("伺服器隨機數:" + Math.random())); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { System.out.println("handlerAdded!!!"); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { System.out.println("handlerRemoved!!!"); } }
package com.bill.websocketdemo; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.stream.ChunkedWriteHandler; public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline pipeline = socketChannel.pipeline(); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new ChunkedWriteHandler()); pipeline.addLast(new HttpObjectAggregator(8192)); pipeline.addLast(new WebSocketServerProtocolHandler("/hello")); pipeline.addLast(new WebSocketHandler()); } }
HTML程式碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>websocket</title>
</head>
<body>
<script type="text/javascript">
var socket;
if(window.WebSocket) {
socket = new WebSocket("ws://localhost:8899/hello");
socket.onmessage = function (event) {
var ta = document.getElementById("resp");
ta.value = ta.value + "\n" + event.data;
}
socket.onopen = function (event) {
var ta = document.getElementById("resp");
ta.value = "連線接開啟!";
}
socket.onclose = function (event) {
var ta = document.getElementById("resp");
ta.value = ta.value + "\n" + "連線關閉!";
}
} else {
alert("瀏覽器不支援websocket");
}
function send(msg) {
if(!window.WebSocket) {
return;
}
if(socket.readyState == WebSocket.OPEN) {
socket.send(msg);
} else {
alert("連線未開啟!")
}
}
</script>
<form onsubmit="return false;">
<textarea id="message" style="width: 400px; height: 200px"></textarea>
<input type="button" value="傳送資料" onclick="send(this.form.message.value)">
<h3> 伺服器輸出:</h3>
<textarea id="resp" style="width: 400px; height: 300px"></textarea>
<input type="button" onclick="javascript: document.getElementById('resp').value = ''" value="清空內容">
</form>
</body>
</html>
請注意:
執行的時候,先執行WebSocketServer的main方法,然後再run src/main/webapp/test.html ,這樣 idea會自動啟動一個頁面
啟動完伺服器後,會在瀏覽器上看到頁面:
伺服器出現資訊:
傳送資料:
伺服器:
完整程式碼下載: