94 lines
3.0 KiB
Java
94 lines
3.0 KiB
Java
/*
|
|
package com.guwan.backend.netty.chat;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import io.netty.channel.Channel;
|
|
import io.netty.channel.ChannelHandler;
|
|
import io.netty.channel.ChannelHandlerContext;
|
|
import io.netty.channel.SimpleChannelInboundHandler;
|
|
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import java.util.Map;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
@Slf4j
|
|
@Component
|
|
@ChannelHandler.Sharable
|
|
public class ChatServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
|
|
|
|
private static final Map<String, Channel> clients = new ConcurrentHashMap<>();
|
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
@Override
|
|
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {
|
|
// 解析消息
|
|
ChatMessage message = objectMapper.readValue(frame.text(), ChatMessage.class);
|
|
|
|
// 处理不同类型的消息
|
|
switch (message.getType()) {
|
|
case "CONNECT":
|
|
handleConnect(ctx, message);
|
|
break;
|
|
case "CHAT":
|
|
handleChat(message);
|
|
break;
|
|
case "DISCONNECT":
|
|
handleDisconnect(message);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void handleConnect(ChannelHandlerContext ctx, ChatMessage message) {
|
|
// 保存用户Channel
|
|
clients.put(message.getFrom(), ctx.channel());
|
|
|
|
// 广播用户上线消息
|
|
broadcastMessage(new ChatMessage() {{
|
|
setType("CHAT");
|
|
setFrom("System");
|
|
setContent(message.getFrom() + " joined the chat");
|
|
setTimestamp(System.currentTimeMillis());
|
|
}});
|
|
}
|
|
|
|
private void handleChat(ChatMessage message) {
|
|
// 广播聊天消息
|
|
broadcastMessage(message);
|
|
}
|
|
|
|
private void handleDisconnect(ChatMessage message) {
|
|
// 移除用户Channel
|
|
clients.remove(message.getFrom());
|
|
|
|
// 广播用户下线消息
|
|
broadcastMessage(new ChatMessage() {{
|
|
setType("CHAT");
|
|
setFrom("System");
|
|
setContent(message.getFrom() + " left the chat");
|
|
setTimestamp(System.currentTimeMillis());
|
|
}});
|
|
}
|
|
|
|
private void broadcastMessage(ChatMessage message) {
|
|
try {
|
|
String messageJson = objectMapper.writeValueAsString(message);
|
|
TextWebSocketFrame frame = new TextWebSocketFrame(messageJson);
|
|
|
|
// 广播给所有在线用户
|
|
clients.values().forEach(channel ->
|
|
channel.writeAndFlush(frame.retain())
|
|
);
|
|
} catch (Exception e) {
|
|
log.error("广播消息失败", e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
|
log.error("WebSocket error", cause);
|
|
ctx.close();
|
|
}
|
|
} */
|