Commit e998b0c7ebe0123972f9a3aaaf43aacdba0ff75d
1 parent
a2532013
【代码评审】IoT:评审 plugin 实现
Showing
11 changed files
with
42 additions
and
37 deletions
yudao-module-iot/yudao-module-iot-api/pom.xml
| @@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||
| 22 | <artifactId>yudao-common</artifactId> | 22 | <artifactId>yudao-common</artifactId> |
| 23 | </dependency> | 23 | </dependency> |
| 24 | <!-- PF4J --> | 24 | <!-- PF4J --> |
| 25 | + <!-- TODO 芋艿:这个依赖,要不要放在 api 包 --> | ||
| 25 | <dependency> | 26 | <dependency> |
| 26 | <groupId>org.pf4j</groupId> | 27 | <groupId>org.pf4j</groupId> |
| 27 | <artifactId>pf4j-spring</artifactId> | 28 | <artifactId>pf4j-spring</artifactId> |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/ServiceRegistry.java
| @@ -7,6 +7,7 @@ import java.util.Map; | @@ -7,6 +7,7 @@ import java.util.Map; | ||
| 7 | * 服务注册表 - 插架模块使用,无法使用 Spring 注入 | 7 | * 服务注册表 - 插架模块使用,无法使用 Spring 注入 |
| 8 | */ | 8 | */ |
| 9 | public class ServiceRegistry { | 9 | public class ServiceRegistry { |
| 10 | + | ||
| 10 | private static final Map<Class<?>, Object> services = new HashMap<>(); | 11 | private static final Map<Class<?>, Object> services = new HashMap<>(); |
| 11 | 12 | ||
| 12 | /** | 13 | /** |
| @@ -31,4 +32,5 @@ public class ServiceRegistry { | @@ -31,4 +32,5 @@ public class ServiceRegistry { | ||
| 31 | public static <T> T getService(Class<T> serviceClass) { | 32 | public static <T> T getService(Class<T> serviceClass) { |
| 32 | return (T) services.get(serviceClass); | 33 | return (T) services.get(serviceClass); |
| 33 | } | 34 | } |
| 35 | + | ||
| 34 | } | 36 | } |
| 35 | \ No newline at end of file | 37 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/DeviceDataApi.java renamed to yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/DeviceDataApi.java
yudao-module-iot/yudao-module-iot-biz/pom.xml
| @@ -81,6 +81,7 @@ | @@ -81,6 +81,7 @@ | ||
| 81 | <dependency> | 81 | <dependency> |
| 82 | <groupId>org.pf4j</groupId> | 82 | <groupId>org.pf4j</groupId> |
| 83 | <artifactId>pf4j-spring</artifactId> | 83 | <artifactId>pf4j-spring</artifactId> |
| 84 | + <!-- TODO @芋艿:可以放到 bom 里配置 --> | ||
| 84 | <exclusions> | 85 | <exclusions> |
| 85 | <exclusion> | 86 | <exclusion> |
| 86 | <groupId>org.slf4j</groupId> | 87 | <groupId>org.slf4j</groupId> |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/DeviceDataApiImpl.java
| 1 | package cn.iocoder.yudao.module.iot.api.device; | 1 | package cn.iocoder.yudao.module.iot.api.device; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.api.DeviceDataApi; | ||
| 4 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceDataService; | 3 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceDataService; |
| 5 | import org.springframework.stereotype.Service; | 4 | import org.springframework.stereotype.Service; |
| 6 | import org.springframework.validation.annotation.Validated; | 5 | import org.springframework.validation.annotation.Validated; |
| @@ -15,11 +14,11 @@ import javax.annotation.Resource; | @@ -15,11 +14,11 @@ import javax.annotation.Resource; | ||
| 15 | public class DeviceDataApiImpl implements DeviceDataApi { | 14 | public class DeviceDataApiImpl implements DeviceDataApi { |
| 16 | 15 | ||
| 17 | @Resource | 16 | @Resource |
| 18 | - private IotDeviceDataService iotDeviceDataService; | 17 | + private IotDeviceDataService deviceDataService; |
| 19 | 18 | ||
| 20 | @Override | 19 | @Override |
| 21 | public void saveDeviceData(String productKey, String deviceName, String message) { | 20 | public void saveDeviceData(String productKey, String deviceName, String message) { |
| 22 | - iotDeviceDataService.saveDeviceData(productKey, deviceName, message); | 21 | + deviceDataService.saveDeviceData(productKey, deviceName, message); |
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | } | 24 | } |
| 26 | \ No newline at end of file | 25 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/package-info.java
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/ServiceRegistryConfiguration.java
| 1 | package cn.iocoder.yudao.module.iot.framework.plugin; | 1 | package cn.iocoder.yudao.module.iot.framework.plugin; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.api.DeviceDataApi; | 3 | +import cn.iocoder.yudao.module.iot.api.device.DeviceDataApi; |
| 4 | import cn.iocoder.yudao.module.iot.api.ServiceRegistry; | 4 | import cn.iocoder.yudao.module.iot.api.ServiceRegistry; |
| 5 | import lombok.extern.slf4j.Slf4j; | 5 | import lombok.extern.slf4j.Slf4j; |
| 6 | import org.springframework.context.annotation.Bean; | 6 | import org.springframework.context.annotation.Bean; |
| @@ -26,9 +26,10 @@ public class ServiceRegistryConfiguration { | @@ -26,9 +26,10 @@ public class ServiceRegistryConfiguration { | ||
| 26 | /** | 26 | /** |
| 27 | * 定义一个标记用的 Bean,用于表示 ServiceRegistry 已初始化完成 | 27 | * 定义一个标记用的 Bean,用于表示 ServiceRegistry 已初始化完成 |
| 28 | */ | 28 | */ |
| 29 | - @Bean("serviceRegistryInitializedMarker") | 29 | + @Bean("serviceRegistryInitializedMarker") // TODO @haohao:1)这个名字,可以搞个 public static final 常量;2)是不是 conditionBefore 啥 |
| 30 | public Object serviceRegistryInitializedMarker() { | 30 | public Object serviceRegistryInitializedMarker() { |
| 31 | - // 返回任意对象即可,这里返回null都可以,但最好返回个实际对象 | 31 | + // 返回任意对象即可,这里返回 null 都可以,但最好返回个实际对象 |
| 32 | return new Object(); | 32 | return new Object(); |
| 33 | } | 33 | } |
| 34 | + | ||
| 34 | } | 35 | } |
| 35 | \ No newline at end of file | 36 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java
| @@ -21,7 +21,7 @@ public interface IotDeviceDataService { | @@ -21,7 +21,7 @@ public interface IotDeviceDataService { | ||
| 21 | * @param productKey 产品 key | 21 | * @param productKey 产品 key |
| 22 | * @param deviceName 设备名称 | 22 | * @param deviceName 设备名称 |
| 23 | * @param message 消息 | 23 | * @param message 消息 |
| 24 | - * <p>JSON 格式,参见 <a href="https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services?spm=a2c4g.11186623.0.0.3a3335aeUdzkz2#concept-mvc-4tw-y2b">...</a> | 24 | + * <p>参见 <a href="https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services?spm=a2c4g.11186623.0.0.3a3335aeUdzkz2#concept-mvc-4tw-y2b">JSON 格式</a> |
| 25 | */ | 25 | */ |
| 26 | void saveDeviceData(String productKey, String deviceName, String message); | 26 | void saveDeviceData(String productKey, String deviceName, String message); |
| 27 | 27 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugininstance/PluginInstanceServiceImpl.java
| @@ -13,6 +13,7 @@ import org.springframework.validation.annotation.Validated; | @@ -13,6 +13,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 13 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 13 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 14 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PLUGIN_INSTANCE_NOT_EXISTS; | 14 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PLUGIN_INSTANCE_NOT_EXISTS; |
| 15 | 15 | ||
| 16 | +// TODO @haohao:可以搞个 plugin 包,然后把 plugininfo、plugininstance | ||
| 16 | /** | 17 | /** |
| 17 | * IoT 插件实例 Service 实现类 | 18 | * IoT 插件实例 Service 实现类 |
| 18 | * | 19 | * |
yudao-module-iot/yudao-module-iot-plugin/yudao-module-iot-http-plugin/src/main/java/cn/iocoder/yudao/module/iot/plugin/HttpHandler.java
| @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.plugin; | @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.plugin; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.json.JSONObject; | 3 | import cn.hutool.json.JSONObject; |
| 4 | import cn.hutool.json.JSONUtil; | 4 | import cn.hutool.json.JSONUtil; |
| 5 | -import cn.iocoder.yudao.module.iot.api.DeviceDataApi; | 5 | +import cn.iocoder.yudao.module.iot.api.device.DeviceDataApi; |
| 6 | import io.netty.buffer.Unpooled; | 6 | import io.netty.buffer.Unpooled; |
| 7 | import io.netty.channel.ChannelFutureListener; | 7 | import io.netty.channel.ChannelFutureListener; |
| 8 | import io.netty.channel.ChannelHandlerContext; | 8 | import io.netty.channel.ChannelHandlerContext; |
| @@ -12,12 +12,9 @@ import io.netty.util.CharsetUtil; | @@ -12,12 +12,9 @@ import io.netty.util.CharsetUtil; | ||
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | * 基于 Netty 的 HTTP 处理器,用于接收设备上报的数据并调用主程序的 DeviceDataApi 接口进行处理。 | 14 | * 基于 Netty 的 HTTP 处理器,用于接收设备上报的数据并调用主程序的 DeviceDataApi 接口进行处理。 |
| 15 | - * <p> | ||
| 16 | - * 请求格式: | ||
| 17 | - * POST /sys/{productKey}/{deviceName}/thing/event/property/post | ||
| 18 | - * 请求体为 JSON 格式数据。 | ||
| 19 | - * <p> | ||
| 20 | - * 返回结果为 JSON 格式,包含统一的 code、data、id、message、method、version 字段。 | 15 | + * |
| 16 | + * 1. 请求格式:JSON 格式,地址为 POST /sys/{productKey}/{deviceName}/thing/event/property/post | ||
| 17 | + * 2. 返回结果:JSON 格式,包含统一的 code、data、id、message、method、version 字段 | ||
| 21 | */ | 18 | */ |
| 22 | public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | 19 | public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { |
| 23 | 20 | ||
| @@ -29,10 +26,9 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | @@ -29,10 +26,9 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | ||
| 29 | 26 | ||
| 30 | @Override | 27 | @Override |
| 31 | protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) { | 28 | protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) { |
| 32 | - String uri = request.uri(); | ||
| 33 | - | ||
| 34 | // 期望的路径格式: /sys/{productKey}/{deviceName}/thing/event/property/post | 29 | // 期望的路径格式: /sys/{productKey}/{deviceName}/thing/event/property/post |
| 35 | // 使用 "/" 拆分路径 | 30 | // 使用 "/" 拆分路径 |
| 31 | + String uri = request.uri(); | ||
| 36 | String[] parts = uri.split("/"); | 32 | String[] parts = uri.split("/"); |
| 37 | 33 | ||
| 38 | /* | 34 | /* |
| @@ -52,25 +48,19 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | @@ -52,25 +48,19 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | ||
| 52 | && "event".equals(parts[5]) | 48 | && "event".equals(parts[5]) |
| 53 | && "property".equals(parts[6]) | 49 | && "property".equals(parts[6]) |
| 54 | && "post".equals(parts[7]); | 50 | && "post".equals(parts[7]); |
| 55 | - | ||
| 56 | if (!isCorrectPath) { | 51 | if (!isCorrectPath) { |
| 57 | - // 如果路径不匹配,返回 404 错误 | ||
| 58 | writeResponse(ctx, HttpResponseStatus.NOT_FOUND, "Not Found"); | 52 | writeResponse(ctx, HttpResponseStatus.NOT_FOUND, "Not Found"); |
| 59 | return; | 53 | return; |
| 60 | } | 54 | } |
| 61 | - | ||
| 62 | String productKey = parts[2]; | 55 | String productKey = parts[2]; |
| 63 | String deviceName = parts[3]; | 56 | String deviceName = parts[3]; |
| 64 | 57 | ||
| 65 | - // 从请求中获取原始数据 | 58 | + // 从请求中获取原始数据,尝试解析请求数据为 JSON 对象 |
| 66 | String requestBody = request.content().toString(CharsetUtil.UTF_8); | 59 | String requestBody = request.content().toString(CharsetUtil.UTF_8); |
| 67 | - | ||
| 68 | - // 尝试解析请求数据为 JSON 对象 | ||
| 69 | JSONObject jsonData; | 60 | JSONObject jsonData; |
| 70 | try { | 61 | try { |
| 71 | jsonData = JSONUtil.parseObj(requestBody); | 62 | jsonData = JSONUtil.parseObj(requestBody); |
| 72 | } catch (Exception e) { | 63 | } catch (Exception e) { |
| 73 | - // 数据不是合法的 JSON 格式,返回 400 错误 | ||
| 74 | JSONObject res = createResponseJson( | 64 | JSONObject res = createResponseJson( |
| 75 | 400, | 65 | 400, |
| 76 | new JSONObject(), | 66 | new JSONObject(), |
| @@ -82,8 +72,6 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | @@ -82,8 +72,6 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | ||
| 82 | writeResponse(ctx, HttpResponseStatus.BAD_REQUEST, res.toString()); | 72 | writeResponse(ctx, HttpResponseStatus.BAD_REQUEST, res.toString()); |
| 83 | return; | 73 | return; |
| 84 | } | 74 | } |
| 85 | - | ||
| 86 | - // 获取请求中的 id 字段,若不存在则为 null | ||
| 87 | String id = jsonData.getStr("id", null); | 75 | String id = jsonData.getStr("id", null); |
| 88 | 76 | ||
| 89 | try { | 77 | try { |
| @@ -101,7 +89,6 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | @@ -101,7 +89,6 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | ||
| 101 | ); | 89 | ); |
| 102 | writeResponse(ctx, HttpResponseStatus.OK, successRes.toString()); | 90 | writeResponse(ctx, HttpResponseStatus.OK, successRes.toString()); |
| 103 | } catch (Exception e) { | 91 | } catch (Exception e) { |
| 104 | - // 保存数据过程中出现异常,返回 500 错误 | ||
| 105 | JSONObject errorRes = createResponseJson( | 92 | JSONObject errorRes = createResponseJson( |
| 106 | 500, | 93 | 500, |
| 107 | new JSONObject(), | 94 | new JSONObject(), |
| @@ -128,7 +115,7 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | @@ -128,7 +115,7 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | ||
| 128 | private JSONObject createResponseJson(int code, JSONObject data, String id, String message, String method, String version) { | 115 | private JSONObject createResponseJson(int code, JSONObject data, String id, String message, String method, String version) { |
| 129 | JSONObject res = new JSONObject(); | 116 | JSONObject res = new JSONObject(); |
| 130 | res.set("code", code); | 117 | res.set("code", code); |
| 131 | - res.set("data", data != null ? data : new JSONObject()); // 确保 data 不为 null | 118 | + res.set("data", data != null ? data : new JSONObject()); |
| 132 | res.set("id", id); | 119 | res.set("id", id); |
| 133 | res.set("message", message); | 120 | res.set("message", message); |
| 134 | res.set("method", method); | 121 | res.set("method", method); |
| @@ -137,24 +124,24 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | @@ -137,24 +124,24 @@ public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> { | ||
| 137 | } | 124 | } |
| 138 | 125 | ||
| 139 | /** | 126 | /** |
| 140 | - * 向客户端返回 HTTP 响应的辅助方法。 | 127 | + * 向客户端返回 HTTP 响应的辅助方法 |
| 141 | * | 128 | * |
| 142 | * @param ctx 通道上下文 | 129 | * @param ctx 通道上下文 |
| 143 | * @param status HTTP 响应状态码(网络层面的) | 130 | * @param status HTTP 响应状态码(网络层面的) |
| 144 | * @param content 响应内容(JSON 字符串或其他文本) | 131 | * @param content 响应内容(JSON 字符串或其他文本) |
| 145 | */ | 132 | */ |
| 146 | private void writeResponse(ChannelHandlerContext ctx, HttpResponseStatus status, String content) { | 133 | private void writeResponse(ChannelHandlerContext ctx, HttpResponseStatus status, String content) { |
| 134 | + // 设置响应头为 JSON 类型和正确的编码 | ||
| 147 | FullHttpResponse response = new DefaultFullHttpResponse( | 135 | FullHttpResponse response = new DefaultFullHttpResponse( |
| 148 | HttpVersion.HTTP_1_1, | 136 | HttpVersion.HTTP_1_1, |
| 149 | status, | 137 | status, |
| 150 | Unpooled.copiedBuffer(content, CharsetUtil.UTF_8) | 138 | Unpooled.copiedBuffer(content, CharsetUtil.UTF_8) |
| 151 | ); | 139 | ); |
| 152 | - | ||
| 153 | - // 设置响应头为 JSON 类型和正确的编码 | ||
| 154 | response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8"); | 140 | response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8"); |
| 155 | response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); | 141 | response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); |
| 156 | 142 | ||
| 157 | // 发送响应并在发送完成后关闭连接 | 143 | // 发送响应并在发送完成后关闭连接 |
| 158 | ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); | 144 | ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); |
| 159 | } | 145 | } |
| 146 | + | ||
| 160 | } | 147 | } |
| 161 | \ No newline at end of file | 148 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-plugin/yudao-module-iot-http-plugin/src/main/java/cn/iocoder/yudao/module/iot/plugin/HttpPlugin.java
| 1 | package cn.iocoder.yudao.module.iot.plugin; | 1 | package cn.iocoder.yudao.module.iot.plugin; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.api.DeviceDataApi; | 3 | +import cn.iocoder.yudao.module.iot.api.device.DeviceDataApi; |
| 4 | import cn.iocoder.yudao.module.iot.api.ServiceRegistry; | 4 | import cn.iocoder.yudao.module.iot.api.ServiceRegistry; |
| 5 | import io.netty.bootstrap.ServerBootstrap; | 5 | import io.netty.bootstrap.ServerBootstrap; |
| 6 | import io.netty.channel.*; | 6 | import io.netty.channel.*; |
| @@ -18,12 +18,14 @@ import java.util.concurrent.Executors; | @@ -18,12 +18,14 @@ import java.util.concurrent.Executors; | ||
| 18 | public class HttpPlugin extends Plugin { | 18 | public class HttpPlugin extends Plugin { |
| 19 | 19 | ||
| 20 | private static final int PORT = 8092; | 20 | private static final int PORT = 8092; |
| 21 | + | ||
| 21 | private final ExecutorService executorService; | 22 | private final ExecutorService executorService; |
| 22 | - private DeviceDataApi deviceDataApi; // 用于保存设备数据的 API | 23 | + private DeviceDataApi deviceDataApi; |
| 23 | 24 | ||
| 24 | public HttpPlugin(PluginWrapper wrapper) { | 25 | public HttpPlugin(PluginWrapper wrapper) { |
| 25 | super(wrapper); | 26 | super(wrapper); |
| 26 | - this.executorService = Executors.newSingleThreadExecutor(); // 创建单线程池 | 27 | + // 创建单线程池 |
| 28 | + this.executorService = Executors.newSingleThreadExecutor(); | ||
| 27 | } | 29 | } |
| 28 | 30 | ||
| 29 | @Override | 31 | @Override |
| @@ -44,10 +46,13 @@ public class HttpPlugin extends Plugin { | @@ -44,10 +46,13 @@ public class HttpPlugin extends Plugin { | ||
| 44 | @Override | 46 | @Override |
| 45 | public void stop() { | 47 | public void stop() { |
| 46 | log.info("HttpPlugin.stop()"); | 48 | log.info("HttpPlugin.stop()"); |
| 47 | - executorService.shutdownNow(); // 停止线程池 | 49 | + // 停止线程池 |
| 50 | + executorService.shutdownNow(); | ||
| 48 | } | 51 | } |
| 49 | 52 | ||
| 50 | - // 启动 HTTP 服务 | 53 | + /** |
| 54 | + * 启动 HTTP 服务 | ||
| 55 | + */ | ||
| 51 | private void startHttpServer() { | 56 | private void startHttpServer() { |
| 52 | EventLoopGroup bossGroup = new NioEventLoopGroup(1); | 57 | EventLoopGroup bossGroup = new NioEventLoopGroup(1); |
| 53 | EventLoopGroup workerGroup = new NioEventLoopGroup(); | 58 | EventLoopGroup workerGroup = new NioEventLoopGroup(); |
| @@ -56,7 +61,8 @@ public class HttpPlugin extends Plugin { | @@ -56,7 +61,8 @@ public class HttpPlugin extends Plugin { | ||
| 56 | ServerBootstrap bootstrap = new ServerBootstrap(); | 61 | ServerBootstrap bootstrap = new ServerBootstrap(); |
| 57 | bootstrap.group(bossGroup, workerGroup) | 62 | bootstrap.group(bossGroup, workerGroup) |
| 58 | .channel(NioServerSocketChannel.class) | 63 | .channel(NioServerSocketChannel.class) |
| 59 | - .childHandler(new ChannelInitializer<Channel>() { | 64 | + .childHandler(new ChannelInitializer<>() { |
| 65 | + | ||
| 60 | @Override | 66 | @Override |
| 61 | protected void initChannel(Channel channel) { | 67 | protected void initChannel(Channel channel) { |
| 62 | channel.pipeline().addLast(new HttpServerCodec()); | 68 | channel.pipeline().addLast(new HttpServerCodec()); |
| @@ -64,6 +70,7 @@ public class HttpPlugin extends Plugin { | @@ -64,6 +70,7 @@ public class HttpPlugin extends Plugin { | ||
| 64 | // 将从 ServiceRegistry 获取的 deviceDataApi 传入处理器 | 70 | // 将从 ServiceRegistry 获取的 deviceDataApi 传入处理器 |
| 65 | channel.pipeline().addLast(new HttpHandler(deviceDataApi)); | 71 | channel.pipeline().addLast(new HttpHandler(deviceDataApi)); |
| 66 | } | 72 | } |
| 73 | + | ||
| 67 | }); | 74 | }); |
| 68 | 75 | ||
| 69 | // 绑定端口并启动服务器 | 76 | // 绑定端口并启动服务器 |
| @@ -78,4 +85,5 @@ public class HttpPlugin extends Plugin { | @@ -78,4 +85,5 @@ public class HttpPlugin extends Plugin { | ||
| 78 | workerGroup.shutdownGracefully(); | 85 | workerGroup.shutdownGracefully(); |
| 79 | } | 86 | } |
| 80 | } | 87 | } |
| 88 | + | ||
| 81 | } | 89 | } |