注册到nacos的多种方式(本人只知道两种)
1. springboot中yml配置
2. java sdk方式注册
参考链接:https://nacos.io/zh-cn/docs/sdk.html
注意点:instance.setIp("127.0.0.1"), 这里的ip地址要与socketio服务的地址一样。可以采用InetAddress方式获取
netty-socketio服务端代码编写
我这里采用打成jar包方式给其他模块进行调用。可以理解为这个模块是一个公共模块
scoketio服务端怎么配置可以自己去查,下面直说如果做成jar包,供其他模块使用,并且哪些是坑。
- 定义一个注解,用于其他地方(模块)使用
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(SocketioConfigurationRegistrar.class)
public @interface EnableSocketIOServer {
String serviceName() default "socket-io-service";
int serverPort();
String groupName() default "GROUP";
}
- 自动配置Bean
@Configuration
public class SocketioConfigurationRegistrar {
@Bean
@ConditionalOnMissingBean(SocketioConfigurationRegistrar.Marker.class)
public Marker socketioMarker() {
return new Marker();
}
class Marker {
}
}
// 自动装配属性的类
@Configuration
@ConditionalOnBean(SocketioConfigurationRegistrar.Marker.class)
@PropertySource(value = {"classpath:socketio.properties"})
public class SocketIoConfigBean {
@Bean
SocketIOServerInitializer socketIOServerInitializer(SocketIOServer server, List<CustomSocketNamespace> namespaces) {
// 这个只是项目启动的时候初始化一些配置
return new SocketIOServerInitializer(server, namespaces);
}
@Bean
SocketIOServer socketIOServer(SocketIOConfig socketIOConfig) {
return socketIOConfig.socketIOServer();
}
@Bean
public SocketIOConfig socketIOConfig() {
// 这个是写在properties的配置,网上有很多这种写法
return new SocketIOConfig();
}
}
// 在初始化bean之前获取其他模块传过来的端口或者其他消息,暂时是使用全局变量存储
public class ConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Map<String, Object> attributes = importingClassMetadata.getAnnotationAttributes(EnableSocketIOServer.class.getName());
String serviceName = "serviceName";
if (attributes != null) {
serviceName = (String) attributes.get("serviceName");
}
int serverPort = 999;
if (attributes != null) {
serverPort = (int) attributes.get("serverPort");
}
String groupName = "groupName";
if (attributes != null) {
groupName = (String) attributes.get("groupName");
}
// 这里注册bean的时候报错,使用属性值赋值方式进行端口赋值
// 这里加载比SocketIOConfig类加载早,所以那里会用这里的的端口号
Constant.port = serverPort;
}
}
上面代码走完后就会去读取配置文件,初始化bean。
为什么要传递端口:每个socket服务都需要自己本身的一个端口地址,不然会出现地址或端口被占用情况
项目启动时启动socket与注册nacos
- socket启动前需要获取自定义的命名空间
- socket的地址必须与nacos注册的地址一模一样。不能出现127.0.0.1与自己机器IPV4这两种地址
@Slf4j
@Component
public class SocketIOServerInitializer implements ApplicationListener<ApplicationEvent> {
@Value("${nacos.serverAddr}")
private String serverAddr;
@Autowired
private SocketIOServer socketIOServer;
@Autowired
private List<CustomSocketNamespace> namespaces;
public SocketIOServerInitializer(SocketIOServer socketIOServer, List<CustomSocketNamespace> namespaces) {
this.socketIOServer = socketIOServer;
this.namespaces = namespaces;
}
public boolean flag = false;
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
log.info("启动SocketIO");
registerNamespaces();
try {
startSocketIOServer();
} catch (Exception e) {
log.info("启动时错误请查看详细日志:{}", e.getMessage());
e.printStackTrace();
}
} else if (event instanceof ContextClosedEvent) {
// 关闭 Socket.IO 服务器
stopSocketIOServer();
}
}
public void registerNamespaces() {
namespaces.forEach(namespace -> {
if (socketIOServer.getNamespace(namespace.getNamespaceName()) == null) {
System.out.println("namespace:" + namespace.getNamespaceName());
socketIOServer.addNamespace(namespace.getNamespaceName())
.addListeners(namespace.getNamespaceBean());
}
});
}
private void startSocketIOServer() throws NacosException {
socketIOServer.start();
System.out.println("Socket.IO 服务器已启动");
flag = true;
registerWithNacos();
Constant.port = 1111;
}
private void stopSocketIOServer() {
socketIOServer.stop();
System.out.println("Socket.IO 服务器已关闭");
}
private void registerWithNacos() throws NacosException {
log.info("注册到nacos");
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
NamingService naming = NamingFactory.createNamingService(properties);
// 注册到nacos
Instance instance = new Instance();
instance.setIp("127.0.0.1");
int port = Constant.port;
instance.setPort(port);
instance.setServiceName("socket-io-service");
instance.setWeight(1.0);
Map<String, String> map = new HashMap<>();
map.put("preserved.register.source", "SPRING_CLOUD");
instance.setMetadata(map);
naming.registerInstance("socket-io-service", instance);
log.info("注册到nacos成功");
}
}
自动配置
gateway
spring:
application:
name: gateway
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
import-check:
enabled: false
gateway:
discovery:
locator:
enabled: true
routes:
# socket 前面启动的socket服务端地址
- id: socket-client
uri: lb://socket-io-service
predicates:
- Path=/websocket/**
# 可以使用lb的方式
- id: socket-client2
uri: lb://socket-io-service2
predicates:
- Path=/service2/**
- id: web-demo
uri: lb://spring-cloud-alibaba-demo
predicates:
- Path=/demo/**