18045010223
2025-07-07 0d3a683a0c97154b1f2e6657398664537e4e3e82
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package org.yzh.web.config;
 
import io.github.yezhihao.netmc.NettyConfig;
import io.github.yezhihao.netmc.Server;
import io.github.yezhihao.netmc.codec.Delimiter;
import io.github.yezhihao.netmc.codec.LengthField;
import io.github.yezhihao.netmc.core.HandlerMapping;
import io.github.yezhihao.netmc.core.SpringHandlerMapping;
import io.github.yezhihao.netmc.session.SessionListener;
import io.github.yezhihao.netmc.session.SessionManager;
import io.github.yezhihao.protostar.SchemaManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.yzh.commons.spring.SSEService;
import org.yzh.protocol.codec.*;
import org.yzh.web.endpoint.JTHandlerInterceptor;
import org.yzh.web.endpoint.JTMessagePushAdapter;
import org.yzh.web.endpoint.JTMultiPacketListener;
import org.yzh.web.model.enums.SessionKey;
 
@Order(Integer.MIN_VALUE)
@Configuration
@ConditionalOnProperty(value = "jt-server.jt808.enabled", havingValue = "true", matchIfMissing = true)
public class JTConfig {
 
    @ConditionalOnProperty(value = "jt-server.jt808.tcp-port")
    @Bean(initMethod = "start", destroyMethod = "stop")
    public Server jt808TCPServer(JTMessageAdapter messageAdapter,
                                 HandlerMapping handlerMapping,
                                 JTHandlerInterceptor handlerInterceptor,
                                 SessionManager sessionManager,
                                 JTProperties jtProperties) {
        return NettyConfig.custom()
                .setIdleStateTime(jtProperties.getIdleTimeout(), 0, 0)
                .setPort(jtProperties.getTcpPort())
                //标识位[2] + 消息头[21] + 消息体[1023 * 2(转义预留)]  + 校验码[1] + 标识位[2]
                .setMaxFrameLength(2 + 21 + 1023 * 2 + 1 + 2)
                .setDelimiters(new Delimiter(new byte[]{0x7e}, false))
                .setDecoder(messageAdapter)
                .setEncoder(messageAdapter)
                .setHandlerMapping(handlerMapping)
                .setHandlerInterceptor(handlerInterceptor)
                .setSessionManager(sessionManager)
                .setName("808-TCP")
                .build();
    }
 
    @ConditionalOnProperty(value = "jt-server.jt808.udp-port")
    @Bean(initMethod = "start", destroyMethod = "stop")
    public Server jt808UDPServer(JTMessageAdapter messageAdapter,
                                 HandlerMapping handlerMapping,
                                 JTHandlerInterceptor handlerInterceptor,
                                 SessionManager sessionManager,
                                 JTProperties jtProperties) {
        return NettyConfig.custom()
                .setPort(jtProperties.getUdpPort())
                .setDelimiters(new Delimiter(new byte[]{0x7e}, false))
                .setDecoder(messageAdapter)
                .setEncoder(messageAdapter)
                .setHandlerMapping(handlerMapping)
                .setHandlerInterceptor(handlerInterceptor)
                .setSessionManager(sessionManager)
                .setName("808-UDP")
                .setEnableUDP(true)
                .build();
    }
 
    @ConditionalOnProperty(value = "jt-server.jt808.t9208.enabled", havingValue = "true")
    @Bean(initMethod = "start", destroyMethod = "stop")
    public Server alarmFileServer(HandlerMapping handlerMapping,
                                  JTHandlerInterceptor handlerInterceptor,
                                  SchemaManager schemaManager,
                                  SSEService sseService,
                                  JTProperties jtProperties) {
 
        JTMessageEncoder encoder = new JTMessageEncoder(schemaManager);
        JTMessageDecoder decoder = new DataFrameMessageDecoder(schemaManager, new byte[]{0x30, 0x31, 0x63, 0x64});
        JTMessagePushAdapter alarmFileMessageAdapter = new JTMessagePushAdapter(encoder, decoder, sseService);
 
        return NettyConfig.custom()
                .setPort(jtProperties.getT9208().getPort())
                .setMaxFrameLength(2 + 21 + 1023 * 2 + 1 + 2)
                .setLengthField(new LengthField(new byte[]{0x30, 0x31, 0x63, 0x64}, 1024 * 65, 58, 4))
                .setDelimiters(new Delimiter(new byte[]{0x7e}, false))
                .setDecoder(alarmFileMessageAdapter)
                .setEncoder(alarmFileMessageAdapter)
                .setHandlerMapping(handlerMapping)
                .setHandlerInterceptor(handlerInterceptor)
                .setName("AlarmFile")
                .build();
    }
 
    @Bean
    public JTMessageAdapter jtMessageAdapter(SchemaManager schemaManager, SSEService sseService) {
        JTMessageEncoder messageEncoder = new JTMessageEncoder(schemaManager);
        JTMessageDecoder messageDecoder = new MultiPacketDecoder(schemaManager, new JTMultiPacketListener(10));
        return new JTMessagePushAdapter(messageEncoder, messageDecoder, sseService);
    }
 
    @Bean
    public HandlerMapping handlerMapping() {
        return new SpringHandlerMapping();
    }
 
    @Bean
    public SessionManager sessionManager(SessionListener sessionListener) {
        return new SessionManager(SessionKey.class, sessionListener);
    }
 
    @Bean
    public SchemaManager schemaManager(JTProperties jtProperties) {
        return new SchemaManager(jtProperties.getMessagePackage());
    }
 
    @Bean
    public MultiPacketDecoder multiPacketDecoder(SchemaManager schemaManager) {
        return new MultiPacketDecoder(schemaManager);
    }
}