使用Springboot + netty 打造聊天服务之Nacos集群问题记录
import cn.hutool.core.bean.BeanUtil;
import com.qhkj.nettychatserver.bean.domain.Message;
import com.qhkj.nettychatserver.bean.request.MessageRequest;
import com.qhkj.nettychatserver.config.NettyConfig;
import com.qhkj.nettychatserver.config.http.HttpResult;
import com.qhkj.nettychatserver.config.http.HttpResultGenerator;
import com.qhkj.nettychatserver.config.http.HttpStatusEnum;
import com.qhkj.nettychatserver.constant.Common;
import com.qhkj.nettychatserver.constant.NettyCommon;
import com.qhkj.nettychatserver.netty.NettyHandler;
import com.qhkj.nettychatserver.service.MessageService;
import com.qhkj.nettychatserver.util.RedisUtil;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import com.qhkj.nettychatserver.bean.request.NettyMesaage;
import com.qhkj.nettychatserver.service.NettyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
@Slf4j
@Service("chat")
public class ChatNettyServiceImpl implements NettyService {
@Resource
private MessageService messageService;
@Resource
private NettyConfig nettyConfig;
@Resource
private RedisUtil redisUtil;
@Resource
private RestTemplate restTemplate;
// 确定channel之后,发送消息
private void nettyHandler(NettyMesaage message, Channel channel) {
log.info("message-> channelId:{} , nettyName: {}", channel.id(), nettyConfig.getNettyServerName());
Date now = new Date();
Message dbmsg = Message.builder()
.messageId(NettyCommon.getIdWorker().nextId())
.createTime(now)
.modifyTime(now)
.build();
BeanUtil.copyProperties(message, dbmsg, Common.options);
boolean flag = messageService.insertOne(dbmsg);
if (flag) {
channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(HttpResultGenerator.success(nettyConfig.getNettyServerName()))));
} else {
channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(HttpResultGenerator.fail(HttpStatusEnum.INTERNAM_SERVER_ERROR.getCode(), nettyConfig.getNettyServerName() + ""))));
}
}
@Override
public HttpResult nettyHandler(MessageRequest request) {
NettyMesaage nettyMesaage = new MessageRequest();
BeanUtil.copyProperties(request, nettyMesaage);
String serverInfo = (String) redisUtil.get(request.getChannelId());
if(StringUtils.isEmpty(serverInfo)) {
log.info("用户不在线!");
return HttpResultGenerator.success("用户不在线!");
}
Channel channel = NettyHandler.channelMap.get(request.getChannelId());
// 本机与用户有连接
if(null != channel) {
this.nettyHandler(nettyMesaage, channel);
} else {
String url = "http://" + serverInfo + "/msg/send";
HashMap jsonObject = restTemplate.postForObject(url, request, HashMap.class);
if( !jsonObject.get("code").equals(200) ) {
log.info("消息发送失败!");
return HttpResultGenerator.fail(HttpStatusEnum.SERVER_BUSY.getCode(),"消息发送失败");
}
}
return HttpResultGenerator.success("消息发送成功!");
}
}