All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetlinks.gateway.vertx.tcp.DefaultTcpServer Maven / Gradle / Ivy

package org.jetlinks.gateway.vertx.tcp;

import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.jetlinks.core.ProtocolSupports;
import org.jetlinks.core.device.AuthenticationResponse;
import org.jetlinks.core.device.DeviceOperation;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.DeviceMessageReply;
import org.jetlinks.core.message.EmptyDeviceMessage;
import org.jetlinks.core.message.codec.EncodedMessage;
import org.jetlinks.core.message.codec.FromDeviceMessageContext;
import org.jetlinks.core.message.codec.Transport;
import org.jetlinks.gateway.session.DeviceSession;
import org.jetlinks.gateway.vertx.tcp.message.MessageType;
import org.jetlinks.gateway.vertx.tcp.message.TcpMessageCodec;

import java.util.concurrent.CompletionStage;
import java.util.function.BiConsumer;

@Slf4j
public abstract class DefaultTcpServer extends TcpServer {

    @Getter
    @Setter
    private TcpMessageCodec messageCodec;

    @Getter
    @Setter
    protected ProtocolSupports protocolSupports;

    @Getter
    @Setter
    private BiConsumer deviceMessageHandler;

    protected abstract CompletionStage doAuth(NetSocket socket, Buffer payload);

    protected abstract void handleNoRegister(NetSocket socket);

    @Override
    protected void handleMessage(NetSocket socket, Buffer data) {
        messageCodec.decoder()
                .handlerPing(ping -> handlePing(socket))
                .handlerMessage((messageType, buffer) -> handleMessage(socket, messageType, buffer))
                .decode(data);

    }

    protected String createClientId(NetSocket socket) {
        return socket.remoteAddress()
                .toString()
                .concat("-")
                .concat(Integer.toHexString(socket.hashCode()));
    }

    protected void handlePing(NetSocket socket) {
        log.debug("TCP ping from [{}] ", socket.remoteAddress());
        DeviceSession session = getDeviceSessionManager().getSession(createClientId(socket));
        if (session != null) {
            session.ping();
        }
    }

    protected void handleMessage(NetSocket socket, MessageType messageType, Buffer payload) {
        //授权
        if (messageType == MessageType.AUTH) {
            doAuth(socket, payload)
                    .whenComplete((response, throwable) -> {
                        if (response == null) {
                            log.error("TCP 认证失败!", throwable);
                            return;
                        }
                        if (response.isSuccess()) {
                            TcpDeviceSession session = new TcpDeviceSession() {
                                @Override
                                public void send(EncodedMessage encodedMessage) {
                                    DefaultTcpServer.this.send(socket, MessageType.MESSAGE, Buffer.buffer(encodedMessage.getByteBuf()));
                                }
                            };
                            session.setId(createClientId(socket));
                            session.setDeviceId(response.getDeviceId());
                            session.setOperationSupplier(getRegistry()::getDevice);
                            session.setSocket(socket);
                            acceptConnect(session);
                        } else {
                            log.info("TCP 认证失败:{}", response.getMessage());
                        }
                    });

        } else { //消息
            String id = createClientId(socket);
            DeviceSession session = getDeviceSessionManager().getSession(id);
            if (null == session) {
                //设备没有注册就发送消息
                handleNoRegister(socket);
            } else {
                session.ping();
                EncodedMessage message = EncodedMessage.simple(session.getDeviceId(), payload.getByteBuf());
                DeviceMessage deviceMessage = session.getProtocolSupport()
                        .getMessageCodec()
                        .decode(Transport.TCP, new FromDeviceMessageContext() {
                            @Override
                            public void sendToDevice(EncodedMessage message) {
                                session.send(message);
                            }

                            @Override
                            public void disconnect() {
                                doClose(session);
                            }

                            @Override
                            public EncodedMessage getMessage() {
                                return message;
                            }

                            @Override
                            public DeviceOperation getDeviceOperation() {
                                return session.getOperation();
                            }
                        });
                if (deviceMessage == null || deviceMessage instanceof EmptyDeviceMessage) {
                    return;
                }
                if (deviceMessage instanceof DeviceMessageReply) {
                    getDeviceSessionManager()
                            .handleDeviceMessageReply(session, ((DeviceMessageReply) deviceMessage));
                }
                if (null != deviceMessageHandler) {
                    deviceMessageHandler.accept(session, deviceMessage);
                }

            }
        }
    }

    protected void send(NetSocket socket, MessageType type, Buffer payload) {
        socket.write(messageCodec.encoder().encode(type, payload));
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy