Commit 888fcd4d by giaogiao

nacos设置心跳;

返回一个健康websocket实例的公网ip;
登陆验证tokenVo返回websocket实例的公网ip;
nacos注册时公网ip
parent fee7ce64
///*
// * Copyright 2019-2029 geekidea(https://github.com/geekidea)
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
//package io.geekidea.springbootplus.config;
//
//import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
//import com.alibaba.cloud.nacos.NacosServiceManager;
//import com.alibaba.cloud.nacos.discovery.NacosWatch;
//import com.alibaba.nacos.api.naming.PreservedMetadataKeys;
//import com.wecloud.im.register.GetIpUtils;
//import org.springframework.beans.factory.ObjectProvider;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
//import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
//
//import javax.annotation.Resource;
//import java.text.SimpleDateFormat;
//import java.util.Date;
//import java.util.HashMap;
//import java.util.Map;
//
//
//@Configuration
//@EnableDiscoveryClient
//public class NacosConfig {
// @Value("${netty.port}")
// private String nettyPort;
// @Resource
// private GetIpUtils getIpUtils;
//
// @Bean
// @ConditionalOnMissingBean
// public NacosDiscoveryProperties nacosProperties() {
// return new NacosDiscoveryProperties();
// }
//
// @Bean
// @ConditionalOnMissingBean
// @ConditionalOnProperty(value = {"spring.cloud.nacos.discovery.watch.enabled"}, matchIfMissing = true)
// public NacosWatch nacosWatch(NacosServiceManager nacosServiceManager, NacosDiscoveryProperties nacosDiscoveryProperties, ObjectProvider<ThreadPoolTaskScheduler> taskScheduler) {
// Map<String, String> metadataMap = nacosDiscoveryProperties.getMetadata();
// if (metadataMap == null) {
// metadataMap = new HashMap<>();
// }
// String key = "ip.netty.public";
package io.geekidea.springbootplus.config;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.cloud.nacos.discovery.NacosWatch;
import com.alibaba.nacos.api.naming.PreservedMetadataKeys;
import com.wecloud.im.register.GetIpUtils;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import static com.wecloud.im.ws.model.WsConstants.IP_NETTY_PUBLIC;
@Configuration
@EnableDiscoveryClient
public class NacosConfig {
@Value("${netty.port}")
private String nettyPort;
@Resource
private GetIpUtils getIpUtils;
@Bean
@ConditionalOnMissingBean
public NacosDiscoveryProperties nacosProperties() {
return new NacosDiscoveryProperties();
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(value = {"spring.cloud.nacos.discovery.watch.enabled"}, matchIfMissing = true)
public NacosWatch nacosWatch(NacosServiceManager nacosServiceManager, NacosDiscoveryProperties nacosDiscoveryProperties, ObjectProvider<ThreadPoolTaskScheduler> taskScheduler) {
Map<String, String> metadataMap = nacosDiscoveryProperties.getMetadata();
if (metadataMap == null) {
metadataMap = new HashMap<>();
}
// metadataMap.put("startup.time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// String value = getIpUtils.getPublicIp() + ":" + nettyPort;
// metadataMap.put(key, value);
// // 设置心跳的周期,单位为秒,这里将心跳间隔设置为3秒:
// metadataMap.put(PreservedMetadataKeys.HEART_BEAT_INTERVAL, "3000");
// // 设置心跳超时时间,单位为秒,这里将心跳超时时间设为6秒,
// // 即服务端6秒收不到客户端心跳,会将该客户端注册的实例设为不健康:
// metadataMap.put(PreservedMetadataKeys.HEART_BEAT_TIMEOUT, "6000");
// // 设置实例删除的超时时间,单位为秒,这里将实例删除超时时间设为9秒,
// // 即服务端9秒收不到客户端心跳,会将该客户端注册的实例删除:
// metadataMap.put(PreservedMetadataKeys.IP_DELETE_TIMEOUT, "9000");
//
// nacosDiscoveryProperties.setMetadata(metadataMap);
// return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties, taskScheduler);
// }
//
//
//}
\ No newline at end of file
String value = getIpUtils.getPublicIp() + ":" + nettyPort;
metadataMap.put(IP_NETTY_PUBLIC, value);
// 设置心跳的周期,单位为秒,这里将心跳间隔设置为3秒:
metadataMap.put(PreservedMetadataKeys.HEART_BEAT_INTERVAL, "3000");
// 设置心跳超时时间,单位为秒,这里将心跳超时时间设为6秒,
// 即服务端6秒收不到客户端心跳,会将该客户端注册的实例设为不健康:
metadataMap.put(PreservedMetadataKeys.HEART_BEAT_TIMEOUT, "6000");
// 设置实例删除的超时时间,单位为秒,这里将实例删除超时时间设为9秒,
// 即服务端9秒收不到客户端心跳,会将该客户端注册的实例删除:
metadataMap.put(PreservedMetadataKeys.IP_DELETE_TIMEOUT, "9000");
nacosDiscoveryProperties.setMetadata(metadataMap);
return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties, taskScheduler);
}
}
\ No newline at end of file
///*
// * Copyright 2019-2029 geekidea(https://github.com/geekidea)
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
//package io.geekidea.springbootplus.test;
//
//import com.alibaba.nacos.api.exception.NacosException;
//import com.alibaba.nacos.api.naming.NamingFactory;
//import com.alibaba.nacos.api.naming.NamingService;
//import com.alibaba.nacos.api.naming.pojo.Instance;
//import com.wecloud.im.register.GetIpUtils;
//import io.geekidea.springbootplus.SpringBootPlusApplication;
//import org.junit.Test;
//import org.junit.runner.RunWith;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.test.context.junit4.SpringRunner;
//
//import java.util.Map;
//
///**
// * get ip
// **/
//@RunWith(SpringRunner.class)
//@SpringBootTest(classes = SpringBootPlusApplication.class)
//public class GetIpTest {
// @Autowired
// private GetIpUtils publicIpUtils;
//
// @Value("${spring.cloud.nacos.discovery.server-addr}")
// private String addr;
//
//
// @Test
// public void test() throws NacosException {
//
//// String s = publicIpUtils.getlanIp();
//// String publicIp = publicIpUtils.getPublicIp();
//// String s2 = publicIpUtils.getlanIp();
//// String publicIp2 = publicIpUtils.getPublicIp();
//
//// String serveAddr = System.getProperty("serveAddr");
// NamingService naming = NamingFactory.createNamingService(addr);
// Instance wecloudIm = naming.selectOneHealthyInstance("wecloud_im");
// Map<String, String> metadata = wecloudIm.getMetadata();
// String publicIp = metadata.get("ip.netty.public");
// System.out.println(wecloudIm);
//
//// naming.subscribe("ip.netty.public", event -> {
//// if (event instanceof NamingEvent) {
//// System.out.println(((NamingEvent) event).getServiceName());
//// System.out.println(((NamingEvent) event).getInstances());
//// }
//// });
//
//// while (true){
////
//// }
//
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.geekidea.springbootplus.test;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.wecloud.im.register.GetIpUtils;
import io.geekidea.springbootplus.SpringBootPlusApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Map;
/**
* 获取一个健康实例的ip
**/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootPlusApplication.class)
public class GetIpTest {
@Autowired
private GetIpUtils publicIpUtils;
@Value("${spring.cloud.nacos.discovery.server-addr}")
private String addr;
@Test
public void test() throws NacosException {
// String s = publicIpUtils.getlanIp();
// String publicIp = publicIpUtils.getPublicIp();
// String s2 = publicIpUtils.getlanIp();
// String publicIp2 = publicIpUtils.getPublicIp();
// String serveAddr = System.getProperty("serveAddr");
NamingService naming = NamingFactory.createNamingService(addr);
Instance wecloudIm = naming.selectOneHealthyInstance("wecloud_im");
Map<String, String> metadata = wecloudIm.getMetadata();
String publicIp = metadata.get("ip.netty.public");
System.out.println(wecloudIm);
System.out.println("publicIp:" + publicIp);
// naming.subscribe("ip.netty.public", event -> {
// if (event instanceof NamingEvent) {
// System.out.println(((NamingEvent) event).getServiceName());
// System.out.println(((NamingEvent) event).getInstances());
// }
// });
// while (true){
//
//
//}
// }
}
}
......@@ -4,7 +4,7 @@ import cn.hutool.core.lang.Snowflake;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.ws.utils.RSAGenerator;
import com.wecloud.im.ws.utils.KeyGenerator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -27,8 +27,8 @@ public class ImApplicationTest {
private ImApplicationService imApplicationService;
public static void main(String[] args) {
String appKey = RSAGenerator.getAppKey(); //定义变量接收
String appSecret = RSAGenerator.getAppSecret(appKey);
String appKey = KeyGenerator.getAppKey(); //定义变量接收
String appSecret = KeyGenerator.getAppSecret(appKey);
int i = 1;
}
......@@ -42,10 +42,10 @@ public class ImApplicationTest {
private void addDb( int i) {
// 生成AppKey
String appKey = RSAGenerator.getAppKey(); //定义变量接收
String appKey = KeyGenerator.getAppKey(); //定义变量接收
// 生成appSecret
String appSecret = RSAGenerator.getAppSecret(appKey);
String appSecret = KeyGenerator.getAppSecret(appKey);
ImApplication imApplication = new ImApplication();
imApplication.setCreateTime(new Date());
......
......@@ -21,11 +21,11 @@
<artifactId>framework</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
<!-- <version>2.2.5.RELEASE</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.google.firebase</groupId>
......
package com.wecloud.im.balance;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Map;
import static com.wecloud.im.ws.model.WsConstants.IP_NETTY_PUBLIC;
@Component
@Slf4j
public class WsInstance {
@Value("${spring.cloud.nacos.discovery.server-addr}")
private String addr;
/**
* 返回一个健康实例的公网ip
*
* @return
* @throws NacosException
*/
public String selectOneHealthyInstance() throws NacosException {
NamingService naming = NamingFactory.createNamingService(addr);
Instance wecloudIm = naming.selectOneHealthyInstance("wecloud_im");
Map<String, String> metadata = wecloudIm.getMetadata();
String publicIp = metadata.get(IP_NETTY_PUBLIC);
log.info("get_wecloud_im_publicIp:" + publicIp);
return publicIp;
}
}
......@@ -5,7 +5,7 @@ import com.wecloud.im.param.ImApplicationPageParam;
import com.wecloud.im.param.ImApplicationQueryVo;
import com.wecloud.im.param.add.ImApplicationAdd;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.ws.utils.RSAGenerator;
import com.wecloud.im.ws.utils.KeyGenerator;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
......@@ -59,9 +59,9 @@ public class ImApplicationController extends BaseController {
BeanUtils.copyProperties(imApplicationAdd, imApplication);
// 生成AppKey
String appKey = RSAGenerator.getAppKey(); //定义变量接收
String appKey = KeyGenerator.getAppKey(); //定义变量接收
// 生成appSecret
String appSecret = RSAGenerator.getAppSecret(appKey);
String appSecret = KeyGenerator.getAppSecret(appKey);
imApplication.setAppKey(appKey);
imApplication.setAppSecret(appSecret);
......
package com.wecloud.im.service;
import com.alibaba.nacos.api.exception.NacosException;
import com.wecloud.im.param.ImTokenVerify;
import com.wecloud.im.vo.TokenVo;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
......@@ -18,6 +19,6 @@ public interface ImClientLoginService {
* @param imTokenVerify
* @return
*/
ApiResult<TokenVo> verifySign(ImTokenVerify imTokenVerify);
ApiResult<TokenVo> verifySign(ImTokenVerify imTokenVerify) throws NacosException;
}
......@@ -2,7 +2,9 @@ package com.wecloud.im.service.impl;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.nacos.api.exception.NacosException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wecloud.im.balance.WsInstance;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.param.ImTokenVerify;
......@@ -38,6 +40,8 @@ public class ImClientLoginServiceImpl implements ImClientLoginService {
@Autowired
private ImClientService imClientService;
@Autowired
private WsInstance wsInstance;
private static JwtProperties jwtProperties;
@Autowired
......@@ -56,7 +60,7 @@ public class ImClientLoginServiceImpl implements ImClientLoginService {
*/
@Override
@Transactional(rollbackFor = Exception.class)
public ApiResult<TokenVo> verifySign(ImTokenVerify imTokenVerify) {
public ApiResult<TokenVo> verifySign(ImTokenVerify imTokenVerify) throws NacosException {
// 根据appKey从数据库查询密钥
ImApplication imApplication = imApplicationService.getOneByAppKey(imTokenVerify.getAppKey());
......@@ -76,16 +80,13 @@ public class ImClientLoginServiceImpl implements ImClientLoginService {
return ApiResult.result(ApiCode.FAIL, null);
}
ImClient imClient;
// 判断client是否存在
imClient = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
ImClient imClient = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getClientId, imTokenVerify.getClientId()));
if (imClient == null) {
log.info("client不存在,先走注册流程");
imClient = new ImClient();
imClient.setId(new Snowflake(1L, 1L).nextId());
imClient.setFkAppid(imApplication.getId());
......@@ -100,12 +101,11 @@ public class ImClientLoginServiceImpl implements ImClientLoginService {
// redisTemplate.opsForValue().set("client:" + imApplication.getAppKey() + ":" + imTokenVerify.getClientId(), generateToken);
JwtToken jwtToken = JwtToken.build(generateToken, secret, jwtProperties.getExpireSecond(), imClient.getClientId(), imTokenVerify.getAppKey());
appLoginRedisService.cacheLoginInfo(jwtToken);
TokenVo tokenVo = new TokenVo();
tokenVo.setToken(generateToken);
tokenVo.setWsAddr(wsInstance.selectOneHealthyInstance());
tokenVo.setId(imClient.getId());
tokenVo.setAttributes(imClient.getAttributes());
return ApiResult.ok(tokenVo);
......
......@@ -9,11 +9,19 @@ import java.io.Serializable;
@Data
public class TokenVo implements Serializable {
/**
* websocket登陆令牌
*/
private String token;
@ApiModelProperty("客户端id")
private Long id;
@ApiModelProperty("webSocket连接地址")
private String wsAddr;
@ApiModelProperty("加密密钥")
private String dataAesKey;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
......
......@@ -8,6 +8,11 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class WsConstants {
/**
* Nacos公网ip
*/
public static final String IP_NETTY_PUBLIC = "ip.netty.public";
/*
* 当前服务器cpu核心数量()
*/
......
......@@ -6,7 +6,7 @@ import java.security.Key;
public class EncrypDES {
// 字符串默认键值
private static final String STR_DEFAULT_KEY = "inventec2020@#$%^&";
private static final String STR_DEFAULT_KEY = "IMinventec2021@#$%^&";
//加密工具
......
......@@ -2,8 +2,7 @@ package com.wecloud.im.ws.utils;
import java.util.UUID;
public class RSAGenerator {
public class KeyGenerator {
private final static String[] CHARS = new String[]{"a", "b", "c", "d", "e", "f",
......@@ -30,11 +29,11 @@ public class RSAGenerator {
}
//生成32位appSecret
public static String getAppSecret(String appId){
String EncryoAppSecret="";
public static String getAppSecret(String appId) {
String EncryoAppSecret = "";
try {
EncrypDES des1 = new EncrypDES();// 使用默认密钥
EncryoAppSecret=des1.encrypt(appId);
EncryoAppSecret = des1.encrypt(appId);
} catch (Exception e) {
e.printStackTrace();
}
......
......@@ -84,7 +84,7 @@
<!-- 解决SpringBootAdmin错误日志问题 -->
<logger name="org.apache.catalina.connector.CoyoteAdapter" level="OFF"/>
<root level="INFO">
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ASYNC_FILE"/>
<appender-ref ref="ASYNC_ERROR_FILE"/>
......
......@@ -76,3 +76,5 @@ Invoke-RestMethod http://169.254.169.254/latest/meta-data/public-ipv4
load-blance:
服务器配置 Local,AWS,AlibabaCloud,HuaweiCloud
server-type: Local
## 启动单机nacos
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment