com.iteaj.iot.client.component.SocketClientComponent Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of iot-client Show documentation
Show all versions of iot-client Show documentation
基于netty的tcp, http, udp等协议的客户端
The newest version!
package com.iteaj.iot.client.component;
import cn.hutool.core.collection.CollectionUtil;
import com.iteaj.iot.*;
import com.iteaj.iot.client.*;
import com.iteaj.iot.client.protocol.ClientSocketProtocol;
import com.iteaj.iot.client.protocol.ServerInitiativeProtocol;
import com.iteaj.iot.codec.SocketMessageDecoder;
import com.iteaj.iot.codec.filter.DecoderInterceptor;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.util.ReferenceCounted;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.util.List;
/**
* 基于socket的客户端组件 主要tcp, upd等
* @param
*/
public abstract class SocketClientComponent extends SocketProtocolFactory
implements ClientComponent, SocketMessageDecoder, IotProtocolFactory {
/**
* 是否启用
*/
private boolean start;
/**
* 开启时间
*/
private long startTime;
/**
* 解码拦截器
*/
private DecoderInterceptor interceptor;
/**
* 默认客户端
* @see #config
*/
private SocketClient iotClient;
/**
* 报文类型
*/
private Class messageClass;
/**
* 报文类型构造函数
*/
private Constructor constructor;
/**
* 默认客户端配置
* @see #iotClient
*/
private ClientConnectProperties config;
/**
* 多客户端管理器
*/
private MultiClientManager clientManager;
protected Logger logger = LoggerFactory.getLogger(getClass());
public SocketClientComponent() {
this(null);
}
/**
* @param config 默认客户端
*/
public SocketClientComponent(ClientConnectProperties config) {
this(config, new SimpleMultiClientManager());
}
public SocketClientComponent(ClientConnectProperties config, MultiClientManager clientManager) {
this.config = config;
this.clientManager = clientManager;
this.setDelegation(createProtocolTimeoutStorage());
}
@Override
public SocketMessage proxy(ChannelHandlerContext ctx, R in) throws Exception {
ClientMessage socketMessage = (ClientMessage) SocketMessageDecoder.super.proxy(ctx, in);
// 设置此客户端的配置信息
if(socketMessage != null) {
socketMessage.setProperties(ctx.channel().attr(CoreConst.CLIENT_KEY).get());
}
return socketMessage;
}
@Override
protected abstract ServerInitiativeProtocol doGetProtocol(M message, ProtocolType type);
@Override
public void start(Object config) {
if(!this.isStart()) {
this.start = true;
this.startTime = System.currentTimeMillis();
if(this.interceptor == null) {
this.interceptor = DecoderInterceptor.DEFAULT;
}
if(getConfig() != null) {
synchronized (this) {
this.getClient().init(config);
this.getClient().connect();
}
}
}
}
@Override
public void close() {
if(this.start) {
this.start = false;
List clients = this.clientManager.clients();
if(CollectionUtil.isNotEmpty(clients)) {
clients.forEach(item -> item.close());
}
}
}
@Override
public void finished() {
ClientComponent.super.finished();
}
@Override
public void addClient(Object clientKey, IotClient value) {
this.clientManager.addClient(clientKey, value);
}
@Override
public SocketClient getClient() {
if(this.iotClient != null) {
return this.iotClient;
} else {
if(this.getConfig() != null) {
return this.iotClient = createNewClient(this.config);
}
}
return null;
}
/**
* 写出报文
* @param properties 客户端配置
* @param msg 发送的协议
* @param args 自定义参数
* @return
*/
public ChannelFuture writeAndFlush(ClientConnectProperties properties, Object msg, Object... args) {
SocketClient socketClient = this.getOrElseCreate(properties);
return socketClient.writeAndFlush(msg, args);
}
/**
* 写出协议
* @see Protocol#requestMessage() 请求的报文
* @see Protocol#responseMessage() 响应的报文
* @param properties 客户端配置
* @param protocol 要写出的协议
* @return
*/
public ChannelFuture writeAndFlush(ClientConnectProperties properties, ClientSocketProtocol protocol) {
return this.writeAndFlush(properties, protocol, null);
}
@Override
public List clients() {
return clientManager.clients();
}
@Override
public SocketClient getClient(Object clientKey) {
return (SocketClient) clientManager.getClient(clientKey);
}
/**
* 获取客户端 如果不存在则创建
* @param properties
* @return
*/
public synchronized SocketClient getOrElseCreate(ClientConnectProperties properties) {
SocketClient client = this.getClient(properties);
if(client == null) {
return this.createNewClientAndConnect(properties);
}
return client;
}
@Override
public IotClient removeClient(Object clientKey) {
return clientManager.removeClient(clientKey);
}
@Override
public Class getMessageClass() {
if(this.messageClass == null) {
// @since 2.3.0 只解析一次报文类
this.messageClass = ClientComponent.super.getMessageClass();
// 注意:只在空的时候解析一次
this.resolveConstructor();
}
return this.messageClass;
}
@Override
public SocketMessage createMessage(byte[] message) {
final Constructor constructor = this.resolveConstructor();
try {
return constructor.newInstance(message);
} catch (ReflectiveOperationException e) {
throw new FrameworkException(e);
}
}
private Constructor resolveConstructor() {
if(this.constructor == null) {
try {
this.constructor = this.getMessageClass().getConstructor(byte[].class);
} catch (NoSuchMethodException e) {
final String simpleName = this.getMessageClass().getSimpleName();
throw new ProtocolException("报文类型缺少构造函数["+simpleName+"(byte[])]", e);
}
}
return this.constructor;
}
/**
* 创建一个新客户端
* @param config
* @return
*/
@Override
public abstract SocketClient createNewClient(ClientConnectProperties config);
/**
* 创建新的客户端并连接
* @param config
*/
public SocketClient createNewClientAndConnect(ClientConnectProperties config) {
SocketClient newClient = createNewClient(config);
newClient.init(null);
// 创建连接
ChannelFuture connect = newClient.connect();
boolean await = connect.awaitUninterruptibly(config.getConnectTimeout());
if(!await) {
throw new FrameworkException("连接超时["+config.getConnectTimeout()+"]");
}
if(!connect.isSuccess()) {
throw new ProtocolException("连接异常", connect.cause());
}
return newClient;
}
@Override
public Object idle(String deviceSn, IdleState state) {
return getInterceptor().idle(deviceSn, state);
}
@Override
public boolean isActivation(Channel channel, FrameworkComponent component) {
return getInterceptor().isActivation(channel, component);
}
@Override
public boolean isDecoder(Channel channel, ReferenceCounted msg) {
return getInterceptor().isDecoder(channel, msg);
}
@Override
public long startTime() {
return startTime;
}
@Override
public DecoderInterceptor getInterceptor() {
return this.interceptor;
}
public void setInterceptor(DecoderInterceptor interceptor) {
this.interceptor = interceptor;
}
@Override
public IotProtocolFactory protocolFactory() {
return this;
}
public MultiClientManager getClientManager() {
return clientManager;
}
protected ProtocolTimeoutStorage createProtocolTimeoutStorage() {
return new ProtocolTimeoutStorage(getName());
}
@Override
public ClientConnectProperties getConfig() {
return config;
}
public void setConfig(ClientConnectProperties config) {
this.config = config;
}
@Override
public boolean isStart() {
return start;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy