index.html
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/jquery.js"></script>
<script>
let socket;
$(function() {
init();
})
function init() {
if (window.WebSocket) {
socket = new WebSocket("ws://127.0.0.1:8080/")
socket.onopen = function() {
$("#showMsg").append("<span style='color:green'>客户端连接成功</span><br>")
//发送心态
sendHead()
//同时触发关闭连接
closeConn()
}
socket.onmessage = function(res) {
if (res.data == "head") {
//5秒收到心态将,关闭连接的定时器关闭掉
console.log(res.data)
clearTimeout(connTime)
//在继续开始关闭连接,相当于又重置10秒
closeConn()
} else {
$("#showMsg").append("<span>服务器:" + res.data + "</span><br>")
}
}
socket.onclose = function() {
console.log("客户端断开")
socket.close();
clearInterval(headTime)
clearTimeout(connTime)
setTimeout(function(){
// 重连 ,如果重连失败又会调用这个方法,所有形成了一个环
reConn();
},5000)
$("#showMsg").append("<span style='color:red'>客户端断开连接</span><br>")
}
socket.onerror = function() {
console.log("出现异常")
}
} else {
alert("浏览器不支持websocker")
}
}
function sendMsg() {
let text = $("#text").val();
socket.send(text)
$("#showMsg").append("<span>我:" + text + "</span><br>")
$("#text").val("")
}
//5秒发送心跳
let headTime;
function sendHead() {
headTime = setInterval(function() {
socket.send("head")
}, 5000)
}
//关闭连接,定时采用10秒
let connTime;
function closeConn() {
connTime = setTimeout(function() {
socket.close()
clearInterval(headTime)
}, 10000)
}
//重新连接
function reConn() {
console.log("重连.........")
init();
}
</script>
</head>
<body>
<div id="showMsg" style="width: 400px;height: 300px; border: 1px solid red;"></div>
<input type="text" id="text" />
<button onclick="sendMsg()">发送</button>
</body>
</html>
WebSocketServer
java
package org.example;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
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.timeout.ReadTimeoutHandler;
import java.util.concurrent.TimeUnit;
public class WebSocketServer {
public static void main(String[] args) throws Exception {
NioEventLoopGroup loopGroup = new NioEventLoopGroup();
NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(loopGroup, eventLoopGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(Channel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(1024 * 64));
//WebSocket 解编码器
pipeline.addLast(new WebSocketServerProtocolHandler("/"));
//客户端10s不发送信息自动断开
pipeline.addLast(new ReadTimeoutHandler(10, TimeUnit.SECONDS));
pipeline.addLast(new WebSocketHandler());
}
});
ChannelFuture future = bootstrap.bind(8080);
future.sync();
}
}
WebSocketHandler
java
package org.example;
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 ctx, TextWebSocketFrame tf) throws Exception {
System.out.println("服务器接收到内容:" + tf.text());
String text = tf.text();
if ("head".equals(text)) {
ctx.channel().writeAndFlush(new TextWebSocketFrame("head"));
} else {
ctx.channel().writeAndFlush(new TextWebSocketFrame("你好"));
}
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端链接");
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
ctx.close();
System.out.println("客户端断开");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
由于websocket都初始化在一个index.html,导致无法扩展,优化websocket.js文件
websocket.js
js
// https://www.bilibili.com/video/BV1vV411C7ed/?spm_id_from=333.1245.0.0
window.websocket = {
init: function(param) {
initWebSocket(param)
}
}
let socket;
function initWebSocket(param) {
if (window.WebSocket) {
socket = new WebSocket("ws://127.0.0.1:8080/")
socket.onopen = function() {
//发送心态
sendHead()
//同时触发关闭连接
closeConn()
param.onopen()
}
socket.onmessage = function(res) {
if (res.data == "head") {
//5秒收到心态将,关闭连接的定时器关闭掉
clearTimeout(connTime)
//在继续开始关闭连接,相当于又重置10秒
closeConn()
} else {
param.onmessage(res);
}
}
socket.onclose = function() {
clearInterval(headTime)
clearTimeout(connTime)
setTimeout(function(){
// 重连 ,如果重连失败又会调用这个方法,所有形成了一个环
reConn();
},5000)
param.onclose()
}
socket.onerror = function() {
console.log("出现异常")
}
} else {
alert("浏览器不支持websocker")
}
}
//5秒发送心跳
let headTime;
function sendHead() {
headTime = setInterval(function() {
console.log("head")
socket.send("head")
}, 5000)
}
//关闭连接,定时采用10秒
let connTime;
function closeConn() {
connTime = setTimeout(function() {
socket.close()
clearInterval(headTime)
}, 10000)
}
//重新连接
function reConn() {
console.log("重连.........")
init();
}
index.html
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/jquery.js"></script>
<script src="js/websocket.js"></script>
<script>
websocket.init({
onopen: function() {
console.log("客户端连接")
$("#showMsg").append("<span style='color:green'>客户端连接成功</span><br>")
},
onmessage: function(res) {
$("#showMsg").append("<span>服务器:" + res.data + "</span><br>")
},
onclose: function() {
console.log("客户端关闭")
},
})
function sendMsg() {
let text = $("#text").val();
socket.send(text)
$("#showMsg").append("<span>我:" + text + "</span><br>")
$("#text").val("")
}
</script>
</head>
<body>
<div id="showMsg" style="width: 400px;height: 300px; border: 1px solid red;"></div>
<input type="text" id="text" />
<button onclick="sendMsg()">发送</button>
</body>
</html>