需求:
編寫一個WebSocket伺服器,來完成讀取用戶端的請求,并完成相應
編寫步驟:
1. 編寫伺服器端的啟動程式
package com.baidu.netty.fouthExample;
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;
public class MyServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new MyServerInitializer());
ChannelFuture future = bootstrap.bind(8899).sync();
future.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
2. 編寫伺服器端的初始化程式
package com.baidu.netty.fouthExample;
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.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.CharsetUtil;
public class MyServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
/**以塊的形式寫*/
pipeline.addLast(new ChunkedWriteHandler());
/**将塊組裝成對象(比如該處用到的文本對象)*/
pipeline.addLast(new HttpObjectAggregator(1024));
/**添加對于websocket的支援,參數配置的是通路的路徑*/
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
pipeline.addLast(new MyServerHandler());
}
}
3. 編寫伺服器的處理程式
package com.baidu.netty.fouthExample;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
public class MyServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
System.out.println("【用戶端的消息】:" + msg.text());
/**傳回的時候也必須要是TextWebSocketFrame對象而不能是普通的字元串*/
TextWebSocketFrame content = new TextWebSocketFrame("你好用戶端");
ctx.writeAndFlush(content);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
4. 編寫html5的socket請求程式
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>websocket通路netty</title>
<script>
var socket;
if(window.WebSocket)
{
//第一個ws是協定,第二個ws是我們在pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); 配置的
socket = new WebSocket("ws://localhost:8899/ws");
//當socket得到資料的時候調用,相當于channelRead0
socket.onmessage = function(event)
{
document.getElementById("content").value = event.data;
}
socket.onopen = function (ev) {
document.getElementById("content").value = "用戶端連上了伺服器";
}
socket.onclose = function (ev) {
document.getElementById("content").value = "用戶端斷開伺服器";
}
}else
{
alert("目前浏覽器不支援websocket程式");
}
function sendMsg() {
if(socket && socket.readyState == WebSocket.OPEN)
{
socket.send(document.getElementById("content").value);
}
}
</script>
</head>
<body>
<input value="發送" type="button" οnclick="sendMsg()"><br>
<textarea id="content"></textarea>
</body>
</html>