1 webSocket可以了理解成http的升级协议本质是先发一个http协议在信息头中有特定的字段告诉http要升级成webSocket协议简历长连接。
之前http协议是无状态的请求响应的方式,其特点没有状态必须是客户端请求->服务器响应的这种方式,不能服务器主动推送大都解决是用轮询的方式来性准及时响应来解决没有长连接的方式。
public class TestWebSocketServer {
public static void main(String[] args) {
//接受的事件循环组
EventLoopGroup boosGrop = new NioEventLoopGroup();
//处理的的事件循环组
EventLoopGroup workGrop = new NioEventLoopGroup();
//服务器启动
ServerBootstrap serverBootstrap = new ServerBootstrap();
try {
//childHandler对应的是workGrop handler对应bossGrop
serverBootstrap.group(boosGrop, workGrop).channel(NioServerSocketChannel.class).
childHandler(new WebSocketInitializer()).handler(new LoggingHandler(LogLevel.INFO));
//sync等待
ChannelFuture channelFuture = serverBootstrap.bind(8993).sync();
ChannelFuture channelFuture1 = channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
boosGrop.shutdownGracefully();
workGrop.shutdownGracefully();
}
}
}
public class WebSocketInitializer extends ChannelInitializer <SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//用于处理http的状态
pipeline.addLast(new HttpServerCodec());
//主要作用是支持异步发送大的码流(例如大文件传输),但不占用过多的内存,防止JAVA内存溢出 可以实现零拷贝zero-copy
pipeline.addLast(new ChunkedWriteHandler());
// 聚合处理 因为http是分段处理这个处理器的作用就是把段聚合在一起如何超过字节数handleOversizedMessage方法就会被调用
pipeline.addLast(new HttpObjectAggregator(Short.MAX_VALUE));
// 处理ping pong test ...
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
pipeline.addLast(new TestWebSocketHandler());
}
}
public class WebSocketInitializer extends ChannelInitializer <SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//用于处理http的状态
pipeline.addLast(new HttpServerCodec());
//主要作用是支持异步发送大的码流(例如大文件传输),但不占用过多的内存,防止JAVA内存溢出 可以实现零拷贝zero-copy
pipeline.addLast(new ChunkedWriteHandler());
// 聚合处理 因为http是分段处理这个处理器的作用就是把段聚合在一起如何超过字节数handleOversizedMessage方法就会被调用
pipeline.addLast(new HttpObjectAggregator(Short.MAX_VALUE));
// 处理ping pong test ...
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
pipeline.addLast(new TestWebSocketHandler());
}
}
<!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:8993/ws");
socket.onmessage = function (event) {
var ta = document.getElementById("responseText");
ta.value = ta.value = "\n" + event.data;
};
socket.onopen = function (event) {
var ta = document.getElementById("responseText");
ta.value = "连接开启";
};
socket.onclose = function (event) {
var ta = document.getElementById("responseText");
ta.value = ta.value = "\n" + "连接关闭";
}
} else {
alert("游览器不支持webSocket 卸载了吧");
}
function send(message) {
if (!window.WebSocket) {
return;
}
if (socket.readyState = WebSocket.OPEN) {
socket.send(message);
}
}
</script>
<form onsubmit="return false;">
<textarea name="message" style="width: 400px;height: 200px;"></textarea>
<input type="button" value="发送数据" onclick="send(this.form.message.value)">
<h3>服务器输出:</h3>
<textarea id="responseText" style="width: 400px; height: 300px;"></textarea>
<input type="button" onclick="javascript: document.getElementById('responseText').value=''" value="清空内容">
</form>
</body>
</html>
启动main方法后简历链接status code:101由http协议升级成webSocket,变成长连接,但是如果手机等移动端的设备开了飞行模式此时服务器并不能知道客户端已经断开所以一般用心跳检查来解决这种问题。
https://mp.weixin.qq.com/s/BDBhXBHbIxAf6lJNNb8xnA