Merge branch 'dev_control' into dev_new_connect

# Conflicts:
#	.idea/workspace.xml
This commit is contained in:
2026-08-19 11:05:09 +08:00
9 changed files with 351 additions and 291 deletions

115
.idea/workspace.xml generated
View File

@@ -4,8 +4,16 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="84ac1b15-3cfa-4375-9957-45b7b581d04e" name="Changes" comment="#update">
<list default="true" id="84ac1b15-3cfa-4375-9957-45b7b581d04e" name="Changes" comment="# commit">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/core/business/device/NettyDevice.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/core/business/device/NettyDevice.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/memory/DeviceSessionManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/memory/DeviceSessionManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/dto/DeviceBindDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/dto/DeviceBindDTO.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/CommandForwardHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/CommandForwardHandler.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/DeviceConnectHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/DeviceConnectHandler.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/service/TransferDeviceService.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/service/TransferDeviceService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/dto/NettySwitchDeviceDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/dto/NettySwitchDeviceDTO.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/netty/handler/ClientHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/netty/handler/ClientHandler.java" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -69,40 +77,40 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;ASKED_SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;Application.test.executor&quot;: &quot;Debug&quot;,
&quot;HTTP Request.MiddlePlatformApplication | #1.executor&quot;: &quot;Run&quot;,
&quot;HTTP Request.MiddlePlatformApplication | #2.executor&quot;: &quot;Run&quot;,
&quot;HTTP Request.MiddlePlatformApplication | #3.executor&quot;: &quot;Run&quot;,
&quot;Maven.MiddlePlatform [clean].executor&quot;: &quot;Run&quot;,
&quot;Maven.MiddlePlatform [install].executor&quot;: &quot;Run&quot;,
&quot;Maven.maibu-netty-server [clean].executor&quot;: &quot;Run&quot;,
&quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
&quot;RequestMappingsPanelOrder0&quot;: &quot;0&quot;,
&quot;RequestMappingsPanelOrder1&quot;: &quot;1&quot;,
&quot;RequestMappingsPanelWidth0&quot;: &quot;75&quot;,
&quot;RequestMappingsPanelWidth1&quot;: &quot;75&quot;,
&quot;RunOnceActivity.MCP Project settings loaded&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;,
&quot;Spring Boot.MiddlePlatformApplication.executor&quot;: &quot;Debug&quot;,
&quot;git-widget-placeholder&quot;: &quot;dev__new__connect&quot;,
&quot;kotlin-language-version-configured&quot;: &quot;true&quot;,
&quot;last_opened_file_path&quot;: &quot;/home/maibu/Test/MiddlePlatform/maibu-external/src/main/java/com/maibu/uav&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;onboarding.tips.debug.path&quot;: &quot;D:/code/MiddlePlatform/maibu-service/maibu-system-service/src/main/java/com/maibu/Main.java&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;project.propVCSSupport.CommitDialog&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
"Application.test.executor": "Debug",
"HTTP Request.MiddlePlatformApplication | #1.executor": "Run",
"HTTP Request.MiddlePlatformApplication | #2.executor": "Run",
"HTTP Request.MiddlePlatformApplication | #3.executor": "Run",
"Maven.MiddlePlatform [clean].executor": "Run",
"Maven.MiddlePlatform [install].executor": "Run",
"Maven.maibu-netty-server [clean].executor": "Run",
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RequestMappingsPanelOrder0": "0",
"RequestMappingsPanelOrder1": "1",
"RequestMappingsPanelWidth0": "75",
"RequestMappingsPanelWidth1": "75",
"RunOnceActivity.MCP Project settings loaded": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"Spring Boot.MiddlePlatformApplication.executor": "Debug",
"git-widget-placeholder": "dev__control",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "/home/maibu/Test/MiddlePlatform/maibu-external/src/main/java/com/maibu/uav",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"onboarding.tips.debug.path": "D:/code/MiddlePlatform/maibu-service/maibu-system-service/src/main/java/com/maibu/Main.java",
"settings.editor.selected.configurable": "project.propVCSSupport.CommitDialog",
"vue.rearranger.settings.migration": "true"
}
}</component>
}]]></component>
<component name="RdControllerToolWindowsLayoutState" isNewUi="true">
<layout>
<window_info id="Bookmarks" side_tool="true" />
@@ -150,11 +158,11 @@
<recent name="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/service" />
</key>
<key name="CopyClassDialog.RECENTS_KEY">
<recent name="com.maibu.service.impl" />
<recent name="com.maibu.controller" />
<recent name="com.maibu.mqtt" />
<recent name="com.maibu.core.business.dto" />
<recent name="com.maibu.uav.dto" />
<recent name="com.maibu.uav.controller" />
<recent name="com.maibu.mapper" />
<recent name="com.maibu.core.business.uav" />
</key>
</component>
<component name="RunManager" selected="Spring Boot.MiddlePlatformApplication">
@@ -214,8 +222,8 @@
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-jdk-30f59d01ecdd-26cb7f24e5b0-intellij.indexing.shared.core-IU-253.29346.138" />
<option value="bundled-js-predefined-d6986cc7102b-9b0f141eb926-JavaScript-IU-253.29346.138" />
<option value="bundled-jdk-30f59d01ecdd-cffe25b9f5b3-intellij.indexing.shared.core-IU-253.28294.251" />
<option value="bundled-js-predefined-d6986cc7102b-c7e53b3be11b-JavaScript-IU-253.28294.251" />
</set>
</attachedChunks>
</component>
@@ -273,7 +281,6 @@
<workItem from="1779683678663" duration="17250000" />
<workItem from="1779755672380" duration="9935000" />
<workItem from="1779770107645" duration="17442000" />
<workItem from="1786062684292" duration="833000" />
</task>
<task id="LOCAL-00001" summary="#update">
<option name="closed" value="true" />
@@ -523,23 +530,7 @@
<option name="project" value="LOCAL" />
<updated>1779242181619</updated>
</task>
<task id="LOCAL-00032" summary="#update">
<option name="closed" value="true" />
<created>1785982626224</created>
<option name="number" value="00032" />
<option name="presentableId" value="LOCAL-00032" />
<option name="project" value="LOCAL" />
<updated>1785982626225</updated>
</task>
<task id="LOCAL-00033" summary="#update">
<option name="closed" value="true" />
<created>1785991726504</created>
<option name="number" value="00033" />
<option name="presentableId" value="LOCAL-00033" />
<option name="project" value="LOCAL" />
<updated>1785991726504</updated>
</task>
<option name="localTasksCounter" value="34" />
<option name="localTasksCounter" value="32" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@@ -590,6 +581,7 @@
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
<option name="CHECK_NEW_TODO" value="false" />
<MESSAGE value="#init" />
<MESSAGE value="#update" />
<MESSAGE value="物模型的新增和修改和查看列表接口" />
<MESSAGE value="SysUser新增权限字段,和需改增加和修改和查询列表接口" />
<MESSAGE value="修改接口system/site/list 根据组织id得到场站list" />
@@ -612,8 +604,7 @@
<MESSAGE value="#id重复bug" />
<MESSAGE value="#修复工单修改接口" />
<MESSAGE value="# commit" />
<MESSAGE value="#update" />
<option name="LAST_COMMIT_MESSAGE" value="#update" />
<option name="LAST_COMMIT_MESSAGE" value="# commit" />
<option name="NON_MODAL_COMMIT_POSTPONE_SLOW_CHECKS" value="false" />
</component>
<component name="XDebuggerManager">
@@ -696,17 +687,17 @@
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java</url>
<line>237</line>
<line>234</line>
<option name="timeStamp" value="51" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java</url>
<line>250</line>
<line>247</line>
<option name="timeStamp" value="52" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java</url>
<line>285</line>
<line>282</line>
<option name="timeStamp" value="61" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-method">

View File

@@ -58,8 +58,8 @@ public class NettyDevice extends Connector {
// todo 注册的时候更新 siteId
private Device device;
//todo 假如设置一个当前控制的token
private String currentControlToken;
//todo 当前登录的账号的token 以token为控制的权限
private String token;
@JsonIgnore
private DevicePlanTaskMapper devicePlanTaskMapper = SpringUtils.getBean(DevicePlanTaskMapper.class);

View File

@@ -30,6 +30,9 @@ public class DeviceSessionManager {
// 设备ID -> 设备对象(业务实体)
private final ConcurrentHashMap<String, NettyDevice> deviceMap = new ConcurrentHashMap<>();
//当前设备的控制权在哪 登录的账号 deviceId(下位机) -> token key 唯一保证一个deviceId 只有一个控制权
private final ConcurrentHashMap<String, String> controllerMap = new ConcurrentHashMap<>();
// 设备ID -> Channel(通信通道)
private final ConcurrentHashMap<String, Channel> channelMap = new ConcurrentHashMap<>();
@@ -105,6 +108,64 @@ public class DeviceSessionManager {
return deviceMap.get(deviceId);
}
/**
* 获取有控制权的 客户端
*/
public String getMaster(String deviceId) {
return controllerMap.get(deviceId);
}
/**
* 获取客户端当前 控制的设备
*/
public String getControl(String token) {
for (String key : controllerMap.keySet()) {
if (controllerMap.get(key).equals(token)) {
return controllerMap.get(token);
}
}
return null;
}
public void lock(String deviceId, String token) {
if (!StringUtils.isEmpty(deviceId) && !StringUtils.isEmpty(token)) {
controllerMap.put(deviceId, token);
}
}
public boolean unLock(String token) {
if (!StringUtils.isEmpty(token)) {
Iterator<String> iterator = controllerMap.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
if (controllerMap.get(key).equals(token)) {
iterator.remove();
}
}
}
return true;
}
public boolean unLock(String deviceId, String token, boolean force) {
if (!StringUtils.isEmpty(deviceId)) {
if (force) {
controllerMap.remove(deviceId);
return true;
} else {
String nowToken = controllerMap.get(deviceId);
if (!StringUtils.isEmpty(token) && nowToken.equals(token)) {
controllerMap.remove(deviceId);
return true;
}
}
}
return false;
}
// 模糊匹配
public List<NettyDevice> getDevicesLike(String query) {
return deviceMap.values().stream()

View File

@@ -24,4 +24,6 @@ public class DeviceBindDTO {
private Integer type; // releaseControl 1 完全释放 2 释放控制权 可监听数据
private String token;
}

View File

@@ -64,6 +64,12 @@ public class CommandForwardHandler extends SimpleChannelInboundHandler<String> {
}
if (ConnectorType.MASTER.equals(senderNettyDevice.getDeviceType())) {
//TODO 有控制权才能发
Set<Connector> connectedDevices = senderNettyDevice.getConnectedConnectors();
if (connectedDevices == null || connectedDevices.isEmpty()) {
logger.debug("发送拒绝master:{},该设备没有关联的设备", senderDeviceId);

View File

@@ -119,6 +119,8 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
logger.info("{}: 设备断开 status: {}", deviceId, ConnectorStatus.DISABLED);
// updateLogoutSingle(deviceId);
// todo 自动切换到其他?
sessionManager.unLock(deviceId);
}
if (nettyDevice != null && nettyDevice.getDeviceType() == ConnectorType.SLAVE) {
nettyDevice.setOnlineStatus(0);
@@ -159,7 +161,7 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
try {
byte[] bytes = Hex.decodeHex(msg.toCharArray());
@@ -185,86 +187,11 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
logger.info("上位机连接 sessionId: {}", sessionId);
logger.info("上位机连接 userName: {}", userName);
logger.info("上位机连接 type: {}", parts[1]);
SysUser sysUser = userService.selectUserByUserName(userName);
if (sysUser != null) {
sysUserClientService.insertUserClient(sysUser.getUserId(), userName, deviceId, "", 0);
}
// 如果 当前角色存在sessionId同时和当前的穿过来不同则下发剔除指令
boolean t = false;
if (StringUtils.isEmpty(sessionId) || sysUser == null) {
t = true;
}
if (sysUser != null && !StringUtils.isEmpty(sessionId)
&& !StringUtils.isEmpty(sysUser.getSessionId())) {
if (!sysUser.getSessionId().equals(sessionId)) {
t = true;
}
}
if (t) {
// 发送已登录状态到客户端
if ("web".equals(parts[1])) {
NettyDevice device = sessionManager.getDevice(deviceId);
logger.info("web 上位机连接重连: {}", JsonUtils.toJsonString(device));
if (device != null && !StringUtils.isEmpty(device.getCurrentSlaveId())) {
logger.info("上位机连接重连: {}", deviceId);
} else {
// 判断是否账号在控制空 如果在控制设置账号为非active
List<UserClient> userClients = sysUserClientService
.selectUserClientByUserName(userName);
ConnectorStatus status = ConnectorStatus.ACTIVE;
logger.info("web 上位机连接重连2: {}", JsonUtils.toJsonString(userClients));
UserClient nowClient = null;
if (!CollectionUtils.isEmpty(userClients)) {
long count = userClients.stream().filter(
x -> x.getIsAlive() == 1 && !deviceId.equals(x.getClientName()))
.count();
if (count > 0) {
status = ConnectorStatus.RECEIVER;
}
nowClient = userClients.stream().filter(
x -> x.getIsAlive() == 1 && deviceId.equals(x.getClientName()))
.findFirst().orElse(null);
}
logger.info("web 上位机连接重连3: {}", JsonUtils.toJsonString(status));
if (!ConnectorStatus.ACTIVE.equals(status)) {
handleMasterConnect(ctx, deviceId, null, status);
} else {
logger.info("web 上位机连接重连4: {}", JsonUtils.toJsonString(nowClient));
if (nowClient != null) {
handleMasterConnect(ctx, deviceId, nowClient.getDeviceName(), status);
} else {
handleMasterConnect(ctx, deviceId, null, status);
}
}
}
} else {
DeviceLoginResponseDTO responseDTO = new DeviceLoginResponseDTO();
responseDTO.setRespond(RespondCode.have_logged_in);
ByteBuf buf = ctx.alloc().buffer();
CommandUtils.buildCommand(buf, responseDTO, CommandConstant.interaction);
ctx.channel().writeAndFlush(buf);
}
} else {
// 判断是否账号在控制空 如果在控制设置账号为非active
List<UserClient> userClients = sysUserClientService
.selectUserClientByUserName(userName);
ConnectorStatus status = ConnectorStatus.ACTIVE;
if (!CollectionUtils.isEmpty(userClients)) {
long count = userClients.stream()
.filter(x -> x.getIsAlive() == 1 && !deviceId.equals(x.getClientName()))
.count();
if (count > 0) {
status = ConnectorStatus.RECEIVER;
}
}
logger.info("上位机上线:{}", status);
// if (ConnectorStatus.ACTIVE.equals(status)) {
// //todo 设置当前控制的token
// sysUser.setSessionId(sessionId);
// userService.updateUserProfile(sysUser);
// }
handleMasterConnect(ctx, deviceId, null, status);
NettyDevice masterDevice = sessionManager.getDevice(sessionId);
if (masterDevice == null) {
// sessionManager.getControl(sessionId);
handleMasterConnect(ctx, sessionId, null, ConnectorStatus.ACTIVE);
}
}
} else {
@@ -438,17 +365,19 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
logger.info("12指令切换权限,c:{}", c.getConnectorId());
if (!c.getConnectorId().equals(masterId)) {
// c.setCurrentSlaveId(null);
c.removeConnectedDevice(slaveDevice);
// c.removeConnectedDevice(slaveDevice);
c.setConnectorStatus(ConnectorStatus.RECEIVER);
sysUserClientService.updateAliveStatus(c.getConnectorId(), slaveId, 2);
sessionManager.unLock(c.getConnectorId());
// sysUserClientService.updateAliveStatus(c.getConnectorId(), slaveId, 2);
}
});
}
logger.info("12指令解析,切换权限,slaveId:{},masterId :{}", slaveId, masterId);
sessionManager.lock(slaveId, masterId);
masterDevice.setCurrentSlaveId(slaveId);
masterDevice.setConnectorStatus(ConnectorStatus.ACTIVE);
masterDevice.addConnectedDevice(slaveDevice);
sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(), slaveId, 1);
// sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(), slaveId, 1);
} else {
logger.info("权限切换请求被拒绝");
}
@@ -479,6 +408,74 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
}
}
// /**
// * 找到当前设备控制的主机 转发控制请求
// */
// private void handlePermissionRequest(DeviceRequestDTO requestDTO, byte[] bytes, ChannelHandlerContext ctx) {
// logger.info("转发控制请求 :{}", JsonUtils.toJsonString(requestDTO));
// String slaveId = requestDTO.getDeviceId();
// List<NettyDevice> controlList = sessionManager.getSlaveControl(slaveId);
// String masterId = requestDTO.getUserId() + ":" + requestDTO.getPlatform();
// logger.info("转发控制请求 controlList :{}", JsonUtils.toJsonString(controlList));
// if (!CollectionUtils.isEmpty(controlList)) {
// // 如果当前设备有控制
// logger.info("转发控制请求 发送报文");
// NettyDevice controlDevice = controlList.get(0);
// if (controlDevice != null && controlDevice.getChannel() != null && controlDevice.getChannel().isActive()) {
// controlDevice.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
// logger.info("转发控制请求 发送报文结束 deviceId :{}", controlDevice.getConnectorId());
// controlRequestMap.put(masterId, slaveId);
// logger.info("转发控制请求 controlRequestMap:{}", JsonUtils.toJsonString(controlRequestMap));
// }
//
// } else {
// // 判断直接给权限 还是 判断是否有该账号其他端的的控制有权限
// NettyDevice activeDevice = sessionManager.getUserControl(requestDTO.getUserId());
// boolean sendMes = true;
// if (activeDevice == null) {
// sendMes = false;
// } else {
// if (activeDevice.getConnectorId().equals(masterId)) {
// sendMes = false;
// }
// }
// if (sendMes) {
// if (activeDevice.getChannel() != null && activeDevice.getChannel().isActive()) {
// activeDevice.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
// logger.info("转发控制请求2 发送报文结束 deviceId :{}", activeDevice.getConnectorId());
// controlRequestMap.put(masterId, slaveId);
// logger.info("转发控制请求2 controlRequestMap:{}", JsonUtils.toJsonString(controlRequestMap));
// }
// } else {
// NettyDevice masterDevice = sessionManager.getDevice(masterId);
// if (masterDevice != null) {
// NettyDevice slaveDevice = sessionManager.getDevice(slaveId);
// masterDevice.setCurrentSlaveId(slaveId);
// masterDevice.setConnectorStatus(ConnectorStatus.ACTIVE);
// masterDevice.addConnectedDevice(slaveDevice);
//
// sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(), slaveId, 1);
// if (masterDevice.getChannel() != null && masterDevice.getChannel().isActive()) {
// DeviceRequestDTO reDto = new DeviceRequestDTO();
// reDto.setPlatform(requestDTO.getPlatform());
// DeviceRespondDTO respond = new DeviceRespondDTO();
// respond.setSwitchResult(true);
// respond.setHolder("you");
// respond.setDeviceId(slaveId);
// reDto.setRespond(respond);
// ByteBuf buf = ctx.alloc().buffer();
// CommandUtils.buildCommand(buf, reDto, CommandConstant.interaction);
// String content = buf.toString(CharsetUtil.UTF_8);
// masterDevice.getChannel().writeAndFlush(buf);
// logger.info("转发控制请求设置当前控制2 发送报文:{} deviceId :{}", content, masterId);
// }
// } else {
//
// }
// }
// }
// }
/**
* 找到当前设备控制的主机 转发控制请求
*/
@@ -486,62 +483,43 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
logger.info("转发控制请求 :{}", JsonUtils.toJsonString(requestDTO));
String slaveId = requestDTO.getDeviceId();
List<NettyDevice> controlList = sessionManager.getSlaveControl(slaveId);
String masterId = requestDTO.getUserId() + ":" + requestDTO.getPlatform();
String token = requestDTO.getToken();
// String masterId = requestDTO.getUserId() + ":" + requestDTO.getPlatform();
logger.info("转发控制请求 controlList :{}", JsonUtils.toJsonString(controlList));
if (!CollectionUtils.isEmpty(controlList)) {
String master = sessionManager.getMaster(slaveId);
if (!StringUtils.isEmpty(master)) {
// 如果当前设备有控制
logger.info("转发控制请求 发送报文");
NettyDevice controlDevice = controlList.get(0);
NettyDevice controlDevice = sessionManager.getDevice(master);
if (controlDevice != null && controlDevice.getChannel() != null && controlDevice.getChannel().isActive()) {
controlDevice.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
logger.info("转发控制请求 发送报文结束 deviceId :{}", controlDevice.getConnectorId());
controlRequestMap.put(masterId, slaveId);
controlRequestMap.put(token, slaveId);
logger.info("转发控制请求 controlRequestMap:{}", JsonUtils.toJsonString(controlRequestMap));
}
} else {
// 判断直接给权限 还是 判断是否有该账号其他端的的控制有权限
NettyDevice activeDevice = sessionManager.getUserControl(requestDTO.getUserId());
boolean sendMes = true;
if (activeDevice == null) {
sendMes = false;
} else {
if (activeDevice.getConnectorId().equals(masterId)) {
sendMes = false;
}
}
if (sendMes) {
if (activeDevice.getChannel() != null && activeDevice.getChannel().isActive()) {
activeDevice.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
logger.info("转发控制请求2 发送报文结束 deviceId :{}", activeDevice.getConnectorId());
controlRequestMap.put(masterId, slaveId);
logger.info("转发控制请求2 controlRequestMap:{}", JsonUtils.toJsonString(controlRequestMap));
}
} else {
NettyDevice masterDevice = sessionManager.getDevice(masterId);
if (masterDevice != null) {
NettyDevice slaveDevice = sessionManager.getDevice(slaveId);
masterDevice.setCurrentSlaveId(slaveId);
masterDevice.setConnectorStatus(ConnectorStatus.ACTIVE);
masterDevice.addConnectedDevice(slaveDevice);
sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(), slaveId, 1);
if (masterDevice.getChannel() != null && masterDevice.getChannel().isActive()) {
DeviceRequestDTO reDto = new DeviceRequestDTO();
reDto.setPlatform(requestDTO.getPlatform());
DeviceRespondDTO respond = new DeviceRespondDTO();
respond.setSwitchResult(true);
respond.setHolder("you");
respond.setDeviceId(slaveId);
reDto.setRespond(respond);
ByteBuf buf = ctx.alloc().buffer();
CommandUtils.buildCommand(buf, reDto, CommandConstant.interaction);
String content = buf.toString(CharsetUtil.UTF_8);
masterDevice.getChannel().writeAndFlush(buf);
logger.info("转发控制请求设置当前控制2 发送报文:{} deviceId :{}", content, masterId);
}
} else {
NettyDevice masterDevice = sessionManager.getDevice(token);
if (masterDevice != null) {
NettyDevice slaveDevice = sessionManager.getDevice(slaveId);
masterDevice.setCurrentSlaveId(slaveId);
masterDevice.setConnectorStatus(ConnectorStatus.ACTIVE);
masterDevice.addConnectedDevice(slaveDevice);
sessionManager.lock(slaveId, token);
if (masterDevice.getChannel() != null && masterDevice.getChannel().isActive()) {
DeviceRequestDTO reDto = new DeviceRequestDTO();
reDto.setPlatform(requestDTO.getPlatform());
DeviceRespondDTO respond = new DeviceRespondDTO();
respond.setSwitchResult(true);
respond.setHolder("you");
respond.setDeviceId(slaveId);
reDto.setRespond(respond);
ByteBuf buf = ctx.alloc().buffer();
CommandUtils.buildCommand(buf, reDto, CommandConstant.interaction);
String content = buf.toString(CharsetUtil.UTF_8);
masterDevice.getChannel().writeAndFlush(buf);
logger.info("转发控制请求设置当前控制2 发送报文:{} deviceId :{}", content, token);
}
}
}

View File

@@ -7,10 +7,12 @@ import com.maibu.core.domain.AjaxResult;
import com.maibu.core.domain.entity.UserClient;
import com.maibu.core.domain.model.LoginUser;
import com.maibu.core.enums.ConnectorStatus;
import com.maibu.exception.ServiceException;
import com.maibu.mapper.DeviceMapper;
import com.maibu.mapper.SysUserClientMapper;
import com.maibu.memory.DeviceSessionManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -20,6 +22,7 @@ import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@Slf4j
@@ -155,62 +158,111 @@ public class TransferDeviceService {
}
}
// public synchronized boolean switchDevice(DeviceBindDTO bindDTO, LoginUser user) {
// try {
// String slaveId = bindDTO.getDeviceId();
// String platform = bindDTO.getPlatform();
// String userName = user.getUsername();
// String masterId = userName + ":" + platform;
// //todo 判断是否有权限 正在控制才能切
// //todo 离线没有控制权的怎么切
// log.info("switchDevice:{}", masterId);
// NettyDevice deviceMaster = sessionManager.getDevice(masterId);
// log.info("deviceMaster:{}", deviceMaster);
// if (deviceMaster != null) {
// log.info("ConnectorStatus:{}", deviceMaster.getConnectorStatus());
// if (ConnectorStatus.RECEIVER.equals(deviceMaster.getConnectorStatus())) {
// //当前账号没有控制则可以切换为控制?
// NettyDevice activeDevice = sessionManager.getUserControl(userName);
// deviceMaster.getConnectedConnectors().clear();
// if (activeDevice == null) {
// log.info("bindConnector ACTIVE :{}", masterId);
// sessionManager.bindConnector(masterId, slaveId);
// deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
// deviceMaster.setCurrentSlaveId(slaveId);
// sysUserClientService.updateAliveStatus(masterId, slaveId, 1);
// } else {
// log.info("bindConnector RECEIVER :{}", masterId);
// sessionManager.bindConnector(masterId, slaveId);
// deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
// deviceMaster.setCurrentSlaveId(slaveId);
// sysUserClientService.updateAliveStatus(masterId, slaveId, 2);
// }
// } else {
// //从关联其他设备切换到 当前禁言 假如有控制且不是当前更新为2
// List<NettyDevice> controls = sessionManager.getSlaveControl(slaveId);
// if (CollectionUtils.isEmpty(controls)) {
// deviceMaster.getConnectedConnectors().clear();
// log.info("bindConnector 1:{}", masterId);
// sessionManager.bindConnector(masterId, slaveId);
// deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
// deviceMaster.setCurrentSlaveId(slaveId);
// sysUserClientService.updateAliveStatus(masterId, slaveId, 1);
// } else {
// NettyDevice controlDevice = controls.get(0);
// if (!masterId.equals(controlDevice.getConnectorId())) {
// //当前的设备有控制 的主机
// deviceMaster.getConnectedConnectors().clear();
// log.info("bindConnector RECEIVER 2:{}", masterId);
// sessionManager.bindConnector(masterId, slaveId);
// deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
// deviceMaster.setCurrentSlaveId(slaveId);
// sysUserClientService.updateAliveStatus(masterId, slaveId, 2);
// }
// //当前 切当前不做操作
// }
// }
// return true;
// }
// } catch (Exception e) {
// log.error("切换设备失败: {}", e.getMessage(), e);
// }
// return false;
// }
public synchronized boolean switchDevice(DeviceBindDTO bindDTO, LoginUser user) {
try {
String slaveId = bindDTO.getDeviceId();
String platform = bindDTO.getPlatform();
String userName = user.getUsername();
String masterId = userName + ":" + platform;
//todo 判断是否有权限 正在控制才能切
//todo 离线没有控制权的怎么切
log.info("switchDevice:{}", masterId);
NettyDevice deviceMaster = sessionManager.getDevice(masterId);
log.info("deviceMaster:{}", deviceMaster);
if (deviceMaster != null) {
log.info("ConnectorStatus:{}", deviceMaster.getConnectorStatus());
if (ConnectorStatus.RECEIVER.equals(deviceMaster.getConnectorStatus())) {
//当前账号没有控制则可以切换为控制?
NettyDevice activeDevice = sessionManager.getUserControl(userName);
deviceMaster.getConnectedConnectors().clear();
if (activeDevice == null) {
log.info("bindConnector ACTIVE :{}", masterId);
sessionManager.bindConnector(masterId, slaveId);
deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
deviceMaster.setCurrentSlaveId(slaveId);
sysUserClientService.updateAliveStatus(masterId, slaveId, 1);
} else {
log.info("bindConnector RECEIVER :{}", masterId);
sessionManager.bindConnector(masterId, slaveId);
deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
deviceMaster.setCurrentSlaveId(slaveId);
sysUserClientService.updateAliveStatus(masterId, slaveId, 2);
}
} else {
//从关联其他设备切换到 当前禁言 假如有控制且不是当前更新为2
List<NettyDevice> controls = sessionManager.getSlaveControl(slaveId);
if (CollectionUtils.isEmpty(controls)) {
deviceMaster.getConnectedConnectors().clear();
log.info("bindConnector 1:{}", masterId);
sessionManager.bindConnector(masterId, slaveId);
deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
deviceMaster.setCurrentSlaveId(slaveId);
sysUserClientService.updateAliveStatus(masterId, slaveId, 1);
} else {
NettyDevice controlDevice = controls.get(0);
if (!masterId.equals(controlDevice.getConnectorId())) {
//当前的设备有控制 的主机
deviceMaster.getConnectedConnectors().clear();
log.info("bindConnector RECEIVER 2:{}", masterId);
sessionManager.bindConnector(masterId, slaveId);
deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
deviceMaster.setCurrentSlaveId(slaveId);
sysUserClientService.updateAliveStatus(masterId, slaveId, 2);
}
//当前 切当前不做操作
}
}
return true;
// String platform = bindDTO.getPlatform();
// String userName = user.getUsername();
// String masterId = userName + ":" + platform;
String token = bindDTO.getToken();
log.info("switchDevice slaveId:{},token:{}", slaveId, token);
NettyDevice deviceMaster = sessionManager.getDevice(token);
log.info("switchDevice deviceMaster:{}", deviceMaster);
if (deviceMaster == null) {
throw new ServiceException("功能码当前账号未发送登录请求,不在线");
}
List<NettyDevice> controls = sessionManager.getAllSlaveControl(slaveId);
if (CollectionUtils.isEmpty(controls)) {
deviceMaster.getConnectedConnectors().clear();
sessionManager.bindConnector(token, slaveId);
deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
deviceMaster.setCurrentSlaveId(slaveId);
sessionManager.lock(slaveId, token);
log.info("switchDevice bindConnector slaveId:{},token:{}", slaveId, token);
} else {
List<String> connectorIds = controls.stream().map(NettyDevice::getConnectorId).collect(Collectors.toList());
if (!connectorIds.contains(token)) {
//当前的设备有控制 的主机
deviceMaster.getConnectedConnectors().clear();
sessionManager.bindConnector(token, slaveId);
deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
deviceMaster.setCurrentSlaveId(slaveId);
log.info("switchDevice bindConnector RECEIVER :{}", token);
} else {
deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
deviceMaster.setCurrentSlaveId(slaveId);
sessionManager.lock(slaveId, token);
}
//当前 切当前不做操作
}
return true;
} catch (Exception e) {
log.error("切换设备失败: {}", e.getMessage(), e);
}
@@ -220,51 +272,16 @@ public class TransferDeviceService {
public DeviceControlDTO remoteControl(DeviceBindDTO bindDTO, LoginUser user) {
try {
String slaveId = bindDTO.getDeviceId();
String platform = bindDTO.getPlatform();
String userName = user.getUsername();
String masterId = userName + ":" + platform;
String token = user.getToken();
String masterToken = sessionManager.getMaster(bindDTO.getDeviceId());
DeviceControlDTO dto = new DeviceControlDTO();
NettyDevice deviceMaster = sessionManager.getDevice(masterId);
log.info("remoteControl deviceMaster:{}", masterId);
// //TODO 拓展当前控制不是同一个账号
// NettyDevice currentDevice = sessionManager.getCurrentControl(slaveId);
// if(currentDevice != null){
// if(currentDevice.getConnectorId().equals(masterId)){
// dto.setRemoteControl(true);
// dto.setOwner(platform);
// }else{
// dto.setRemoteControl(false);
// dto.setOwner(currentDevice.getConnectorId());
// }
// }else{
// dto.setRemoteControl(false);
// dto.setOwner(null);
// dto.setReason("occupied");
// }
if (deviceMaster != null) {
if (ConnectorStatus.ACTIVE.equals(deviceMaster.getConnectorStatus())) {
dto.setRemoteControl(true);
dto.setOwner(platform);
} else {
dto.setRemoteControl(false);
dto.setReason("occupied");
NettyDevice activeDevice = sessionManager.getUserControl(userName);
if (activeDevice != null) {
String[] l = activeDevice.getConnectorId().split(":");
dto.setOwner(l[1]);
}
}
if (!StringUtils.isEmpty(token) && token.equals(masterToken)) {
dto.setRemoteControl(true);
dto.setOwner("you");
} else {
dto.setRemoteControl(false);
dto.setReason("not exist");
NettyDevice activeDevice = sessionManager.getUserControl(userName);
if (activeDevice != null) {
String[] l = activeDevice.getConnectorId().split(":");
dto.setOwner(l[1]);
}
dto.setReason("occupied");
dto.setOwner(masterToken);
}
return dto;
} catch (Exception e) {
@@ -334,16 +351,15 @@ public class TransferDeviceService {
String masterId = userName + ":" + platform;
Integer type = bindDTO.getType();
NettyDevice deviceMaster = sessionManager.getDevice(masterId);
if (deviceMaster != null && type!=null) {
if(type == 1){
sysUserClientService.updateAliveStatus(masterId, "", 0);
if (type != null && deviceMaster != null) {
if (type == 1) {
deviceMaster.setCurrentSlaveId(null);
deviceMaster.getConnectedConnectors().clear();
} else if (type == 2) {
deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
sysUserClientService.updateAliveStatus(masterId, deviceMaster.getCurrentSlaveId(), 2);
}
}
sessionManager.unLock(bindDTO.getDeviceId(), bindDTO.getToken(), false);
} catch (Exception e) {
log.error(e.getMessage());
}

View File

@@ -23,4 +23,9 @@ public class NettySwitchDeviceDTO {
*/
private String userId;
/**
* 用户名
*/
private String token;
}

View File

@@ -400,6 +400,7 @@ public class ClientHandler extends ChannelInboundHandlerAdapter {
NettySwitchDeviceDTO dto = new NettySwitchDeviceDTO();
dto.setDeviceId(nettyClient.requestDeviceId);
dto.setPlatform("web");
dto.setToken(token);
String result = httpService.doPost(postUrl, token, dto);
ResultDTO resultDTO = JsonUtils.parseObject(result, ResultDTO.class);
if (resultDTO != null && resultDTO.getData() != null) {