实现的功能
- 多客户端通信(群聊)
具体实现代码
客户端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>网页聊天室</title>
</head>
<body>
输入消息:<input type="text" id="msgContent">
<input type="button" value="发送" onclick="CHAT.chat()">
<div id="receiveMsg" style="background-color: gainsboro;"></div>
<script>
window.CHAT = {
socket: null,
init: function () {
if (window.WebSocket) {
CHAT.socket = new WebSocket("ws://192.168.43.178:8899/ws")
CHAT.socket.onopen = function () {
console.log("连接建立成功")
},
CHAT.socket.onclose = function () {
console.log("连接关闭")
},
CHAT.socket.onerror = function () {
console.log("发生错误")
},
CHAT.socket.onmessage = function (e) {
console.log("接收到消息:" + e.data)
var receiveMsg = document.getElementById("receiveMsg")
var html = receiveMsg.innerHTML
receiveMsg.innerHTML = html + "<br/>" + e.data;
}
} else {
alert("浏览器不支持WebSocket")
}
},
chat: function () {
var msg = document.getElementById("msgContent")
CHAT.socket.send(msg.value)
}
}
CHAT.init()
</script>
</body>
</html>
服务端
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).
childHandler(new WebSocketChannelInitializer());
ChannelFuture channelFuture = serverBootstrap.bind(new InetSocketAddress(8899)).sync();
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
- WebSocketChannelInitializer
public class WebSocketChannelInitializer 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(8192));
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
pipeline.addLast(new TextWebSocketFrameHandler());
}
}
- TextWebSocketFrameHandler
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
private static ChannelGroup clients =
new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
String content = msg.text();
for(Channel channel: clients) {
channel.writeAndFlush(
new TextWebSocketFrame(
"[服务器在]"+ LocalDateTime.now()+"接收到消息,消息为:"+content));
}
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
clients.add(ctx.channel());
System.out.println("handlerAdd:" + ctx.channel().id().asLongText());
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
System.out.println("handlerRemoved:" + ctx.channel().id().asLongText());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("异常发生");
ctx.close();
}
}