You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

809 lines
32 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import sys
import socket
import threading
import requests
import json
import time
import uuid
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QPushButton, \
QListWidget, QLabel, QWidget, QMessageBox, QTextEdit, \
QLineEdit, QHBoxLayout, QRadioButton, QButtonGroup, QGroupBox
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QObject, QTimer
from PyQt5.QtNetwork import QNetworkInterface,QAbstractSocket
from datetime import datetime
from utils import Globals
class TcpClient(object):
def __init__(self):
# 配置信息
self.udpPort = 54321
self.broadcastAddr = '<broadcast>'
def discoverServers(self):
# print("[*] 正在扫描局域网设备...")
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udpSock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
udpSock.settimeout(2)
udpSock.sendto(b"DISCOVERY_REQUEST", (self.broadcastAddr, self.udpPort))
servers = []
seen = set()
local_ips = self.getLocalIps()
try:
while True:
data, addr = udpSock.recvfrom(1024)
if data.startswith(b"DISCOVERY_RESPONSE"):
_, hostname, tcpPort = data.decode('utf-8').split(':')
serverIp = addr[0]
# 跳过本机IP
if serverIp in local_ips:
continue
key = (serverIp, int(tcpPort))
if key in seen:
continue
seen.add(key)
servers.append({
'ip': (serverIp,),
'port': int(tcpPort),
'hostname': hostname
})
print(data.decode('utf-8'))
except socket.timeout:
pass
finally:
udpSock.close()
return servers
def connectToServer(self, ip, tcpPort):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 显式转换类型确保安全
client.connect((str(ip), int(tcpPort)))
# print(f"[+] 已连接到 {ip}:{tcpPort}")
Globals.getValue('protocolManage').setServerMode()
clientName = Globals.getValue('protocolManage').RpcServer.getNextClientName()
client.send(clientName.encode('utf-8'))
response = client.recv(1024)
# print(f"服务端响应: {response.decode('utf-8')}")
resClientName = response.decode('utf-8')
Globals.getValue('protocolManage').addClient(clientName = resClientName)
QMessageBox.information(None, '连接成功', f'已成功连接到从站 {ip}:{tcpPort}')
return True
except Exception as e:
print(f"连接失败: {e}")
return False
finally:
client.close()
def getLocalIps(self):
"""获取本机所有IPv4地址"""
ips = set()
for interface in QNetworkInterface.allInterfaces():
if interface.flags() & QNetworkInterface.IsUp:
for entry in interface.addressEntries():
ip = entry.ip()
if ip.protocol() == QAbstractSocket.IPv4Protocol and not ip.isLoopback():
ips.add(ip.toString())
return ips
class DiscoveryThread(QThread):
"""用于在后台执行设备发现的线程"""
discoveryFinished = pyqtSignal(list) # 信号,携带发现的设备列表
def __init__(self, tcpClient):
super().__init__()
self.tcpClient = tcpClient
def run(self):
servers = self.tcpClient.discoverServers()
self.discoveryFinished.emit(servers)
class DeviceMasterWidget(QMainWindow):
def __init__(self):
super().__init__()
self.tcpClient = TcpClient()
self.servers = []
self.discoveryThread = None
self.statusLabel = None
self.infoLabel = None
self.disconnectList = None
self.publicServerInput = None
self.publicClientList = None
self.publicClients = []
self.autoRefreshEnabled = False
self.initUI()
# 定时器启动放到控件初始化后
self.statusTimer = QTimer(self)
self.statusTimer.timeout.connect(self.updateStatusInfo)
self.statusTimer.start(1000)
# 公网客户端自动刷新定时器
self.publicRefreshTimer = QTimer(self)
self.publicRefreshTimer.timeout.connect(self.autoRefreshPublicClients)
def initUI(self):
self.setWindowTitle('设备连接管理')
# self.setGeometry(1000, 500, 400, 300)
# 主窗口部件
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
layout = QVBoxLayout()
self.statusLabel = QLabel('服务器模式: 无')
layout.addWidget(self.statusLabel)
self.infoLabel = QLabel('连接信息: 无')
layout.addWidget(self.infoLabel)
# 新增:断开客户端区
self.disconnectList = QListWidget()
self.disconnectList.setFixedHeight(60)
layout.addWidget(QLabel('已连接客户端(点击可断开):'))
layout.addWidget(self.disconnectList)
self.disconnectList.itemClicked.connect(self.disconnectClient)
# 公网服务端配置区域
publicGroup = QGroupBox('公网服务端配置')
publicLayout = QVBoxLayout()
# 服务器地址输入
serverLayout = QHBoxLayout()
serverLayout.addWidget(QLabel('服务器地址:'))
self.publicServerInput = QLineEdit('43.138.48.181')
self.publicServerInput.setPlaceholderText('输入公网服务器IP地址')
serverLayout.addWidget(self.publicServerInput)
publicLayout.addLayout(serverLayout)
# 启动公网服务端按钮
self.publicConnectButton = QPushButton('启动公网服务端模式')
self.publicConnectButton.clicked.connect(self.startPublicServer)
self.publicConnectButton.setObjectName('setButton')
publicLayout.addWidget(self.publicConnectButton)
# 公网客户端扫描区域
publicLayout.addWidget(QLabel('公网服务器客户端列表:'))
self.publicClientList = QListWidget()
self.publicClientList.setFixedHeight(100)
self.publicClientList.itemDoubleClicked.connect(self.connectToPublicClient)
publicLayout.addWidget(self.publicClientList)
# 扫描和连接按钮
publicButtonLayout = QHBoxLayout()
self.scanPublicButton = QPushButton('扫描公网客户端')
self.scanPublicButton.clicked.connect(self.scanPublicClients)
self.scanPublicButton.setObjectName('setButton')
publicButtonLayout.addWidget(self.scanPublicButton)
self.connectPublicButton = QPushButton('连接选中客户端')
self.connectPublicButton.clicked.connect(self.connectToPublicClient)
self.connectPublicButton.setEnabled(False)
self.connectPublicButton.setObjectName('setButton')
publicButtonLayout.addWidget(self.connectPublicButton)
publicLayout.addLayout(publicButtonLayout)
# 自动刷新选项
from PyQt5.QtWidgets import QCheckBox
self.autoRefreshCheckBox = QCheckBox('自动刷新客户端列表 (5秒)')
self.autoRefreshCheckBox.stateChanged.connect(self.toggleAutoRefresh)
publicLayout.addWidget(self.autoRefreshCheckBox)
publicGroup.setLayout(publicLayout)
layout.addWidget(publicGroup)
self.ipAddresslabel = QLabel(self)
self.ipAddresslabel.setObjectName("setlabel")
self.ipAddresslabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter)
layout.addWidget(self.ipAddresslabel)
# 局域网设备发现区域
lanGroup = QGroupBox('局域网设备发现')
lanLayout = QVBoxLayout()
# 标题标签
self.titleLabel = QLabel('点击"扫描设备"按钮发现局域网中的设备')
lanLayout.addWidget(self.titleLabel)
# 设备列表
self.deviceList = QListWidget()
lanLayout.addWidget(self.deviceList)
lanLayout2 = QHBoxLayout()
self.scanButton = QPushButton('扫描设备')
self.scanButton.clicked.connect(self.startDiscovery)
self.scanButton.setObjectName('setButton')
lanLayout2.addWidget(self.scanButton)
self.connectButton = QPushButton('连接设备')
self.connectButton.clicked.connect(self.connectToDevice)
self.connectButton.setEnabled(False)
self.connectButton.setObjectName('setButton')
lanLayout2.addWidget(self.connectButton)
lanLayout.addLayout(lanLayout2)
lanGroup.setLayout(lanLayout)
layout.addWidget(lanGroup)
self.ipAddresslabel.setText('当前设备IP地址: ' + self.getLocalIp())
centralWidget.setLayout(layout)
# self.show()
def startDiscovery(self):
"""开始扫描设备"""
self.scanButton.setEnabled(False)
self.titleLabel.setText('正在扫描局域网设备...')
self.deviceList.clear()
# 创建并启动发现线程
self.discoveryThread = DiscoveryThread(self.tcpClient)
self.discoveryThread.discoveryFinished.connect(self.onDiscoveryFinished)
self.discoveryThread.start()
def onDiscoveryFinished(self, servers):
"""设备扫描完成后的回调"""
self.scanButton.setEnabled(True)
self.servers = servers
if not servers:
self.titleLabel.setText('未发现任何设备')
QMessageBox.information(self, '提示', '未发现任何设备')
return
self.titleLabel.setText(f'发现 {len(servers)} 个设备:')
# 在列表中显示设备
for server in servers:
itemText = f"{server['hostname']} ({server['ip'][0]})"
self.deviceList.addItem(itemText)
self.connectButton.setEnabled(True)
def startPublicServer(self):
"""启动公网服务端模式"""
serverIp = self.publicServerInput.text().strip()
if not serverIp:
QMessageBox.warning(self, '警告', '请输入服务器地址')
return
try:
# 设置为服务端模式
Globals.getValue('protocolManage').closeClient()
Globals.getValue('protocolManage').setServerMode(rabbitmqHost=serverIp)
QMessageBox.information(self, '成功', f'已启动公网服务端模式\n服务器地址: {serverIp}')
except Exception as e:
QMessageBox.critical(self, '失败', f'启动公网服务端模式失败: {str(e)}')
def scanPublicClients(self):
"""扫描公网服务器上的客户端"""
serverIp = self.publicServerInput.text().strip()
if not serverIp:
QMessageBox.warning(self, '警告', '请输入服务器地址')
return
try:
# 通过RabbitMQ管理API获取所有RPC队列
url = f"http://{serverIp}:15672/api/queues"
response = requests.get(url, auth=('dcs', '123456'), timeout=10)
queues = response.json()
# 筛选RPC客户端队列
rpc_queues = []
for queue in queues:
queue_name = queue['name']
if queue_name.startswith('rpc_queue_client'):
client_name = queue_name.replace('rpc_queue_', '')
rpc_queues.append({
'name': client_name,
'queue': queue_name,
'messages': queue.get('messages', 0),
'consumers': queue.get('consumers', 0),
'status': 'online' if queue.get('consumers', 0) > 0 else 'offline'
})
# 更新客户端列表
self.publicClients = rpc_queues
self.publicClientList.clear()
if not rpc_queues:
self.publicClientList.addItem('未发现任何客户端')
self.connectPublicButton.setEnabled(False)
else:
for client in rpc_queues:
status_text = "在线" if client['status'] == 'online' else "离线"
item_text = f"{client['name']} ({status_text}) - 消息:{client['messages']}"
self.publicClientList.addItem(item_text)
self.connectPublicButton.setEnabled(True)
QMessageBox.information(self, '扫描完成', f'发现 {len(rpc_queues)} 个客户端')
except Exception as e:
QMessageBox.critical(self, '扫描失败', f'扫描公网客户端失败: {str(e)}')
self.publicClientList.clear()
self.publicClientList.addItem('扫描失败')
self.connectPublicButton.setEnabled(False)
def connectToPublicClient(self):
"""连接到选中的公网客户端"""
selectedIndex = self.publicClientList.currentRow()
if selectedIndex == -1:
QMessageBox.warning(self, '警告', '请先选择一个客户端')
return
if selectedIndex >= len(self.publicClients):
QMessageBox.warning(self, '警告', '选择的客户端无效')
return
selectedClient = self.publicClients[selectedIndex]
clientName = selectedClient['name']
# 检查客户端状态
# if selectedClient['status'] == 'offline':
# reply = QMessageBox.question(self, '客户端离线',
# f'客户端 {clientName} 当前离线,是否仍要尝试连接?',
# QMessageBox.Yes | QMessageBox.No)
# if reply == QMessageBox.No:
# return
try:
# 检查是否已经连接
protocolManage = Globals.getValue('protocolManage')
if protocolManage and hasattr(protocolManage, 'RpcServer') and protocolManage.RpcServer:
existing_clients = protocolManage.RpcServer.getClientNames()
if clientName in existing_clients:
QMessageBox.information(self, '提示', f'客户端 {clientName} 已连接,无需重复连接')
return
# 尝试添加客户端
if protocolManage.RpcServer.addClient(clientName):
QMessageBox.information(self, '连接成功', f'已成功连接到客户端 {clientName}')
# 刷新状态信息
self.updateStatusInfo()
else:
QMessageBox.warning(self, '连接失败', f'无法连接到客户端 {clientName},客户端可能不在线')
else:
QMessageBox.warning(self, '错误', '请先启动公网服务端模式')
except Exception as e:
QMessageBox.critical(self, '连接失败', f'连接客户端失败: {str(e)}')
def autoRefreshPublicClients(self):
"""自动刷新公网客户端列表(静默模式)"""
if not self.autoRefreshEnabled:
return
serverIp = self.publicServerInput.text().strip()
if not serverIp:
return
try:
# 静默扫描,不显示消息框
url = f"http://{serverIp}:15672/api/queues"
response = requests.get(url, auth=('dcs', '123456'), timeout=5)
queues = response.json()
# 筛选RPC客户端队列
rpc_queues = []
for queue in queues:
queue_name = queue['name']
if queue_name.startswith('rpc_queue_client'):
client_name = queue_name.replace('rpc_queue_', '')
rpc_queues.append({
'name': client_name,
'queue': queue_name,
'messages': queue.get('messages', 0),
'consumers': queue.get('consumers', 0),
'status': 'online' if queue.get('consumers', 0) > 0 else 'offline'
})
# 更新客户端列表(保持选中状态)
current_selection = self.publicClientList.currentRow()
self.publicClients = rpc_queues
self.publicClientList.clear()
if not rpc_queues:
self.publicClientList.addItem('未发现任何客户端')
self.connectPublicButton.setEnabled(False)
else:
for client in rpc_queues:
status_text = "在线" if client['status'] == 'online' else "离线"
item_text = f"{client['name']} ({status_text}) - 消息:{client['messages']}"
self.publicClientList.addItem(item_text)
self.connectPublicButton.setEnabled(True)
# 恢复选中状态
if 0 <= current_selection < len(rpc_queues):
self.publicClientList.setCurrentRow(current_selection)
except Exception as e:
# 静默处理错误,不显示消息框
print(f"自动刷新公网客户端失败: {e}")
def toggleAutoRefresh(self, state):
"""切换自动刷新状态"""
self.autoRefreshEnabled = state == 2 # Qt.Checked = 2
if self.autoRefreshEnabled:
self.publicRefreshTimer.start(5000) # 每5秒刷新一次
print("已启用公网客户端自动刷新")
else:
self.publicRefreshTimer.stop()
print("已禁用公网客户端自动刷新")
def connectToDevice(self):
"""连接选中的设备"""
selectedIndex = self.deviceList.currentRow()
if selectedIndex == -1:
QMessageBox.warning(self, '警告', '请先选择一个设备')
return
selectedServer = self.servers[selectedIndex]
from utils import Globals
protocolManage = Globals.getValue('protocolManage')
already_connected = False
ip = selectedServer['ip'][0] if isinstance(selectedServer['ip'], (list, tuple)) else selectedServer['ip']
if protocolManage and hasattr(protocolManage, 'RpcServer') and protocolManage.RpcServer:
clients = protocolManage.RpcServer.getClientNames()
ipMap = protocolManage.RpcServer.getClientIpMap() if hasattr(protocolManage.RpcServer, 'getClientIpMap') else {}
for c in clients:
if ipMap.get(c, '') == ip:
already_connected = True
break
if already_connected:
QMessageBox.information(self, '提示', f'客户端 {ip} 已连接,无需重复连接')
return
self.tcpClient.connectToServer(ip, selectedServer['port'])
def getLocalIp(self):
for interface in QNetworkInterface.allInterfaces():
if interface.flags() & QNetworkInterface.IsUp:
for entry in interface.addressEntries():
ip = entry.ip()
# 修改为新的枚举访问方式
if ip.protocol() == QAbstractSocket.IPv4Protocol and not ip.isLoopback():
return ip.toString()
return "192.168.1.1" # 默认回退值
def cleanup(self):
# 释放后台线程
if self.discoveryThread and self.discoveryThread.isRunning():
self.discoveryThread.terminate()
self.discoveryThread.wait()
def closeEvent(self, event):
self.cleanup()
event.accept()
def __del__(self):
self.cleanup()
def updateStatusInfo(self):
protocolManage = Globals.getValue('protocolManage')
mode = ''
info = ''
if protocolManage:
if hasattr(protocolManage, 'RpcServer') and protocolManage.RpcServer:
mode = '服务端模式'
try:
clients = protocolManage.RpcServer.getClientNames()
clientIpMap = protocolManage.RpcServer.getClientIpMap() if hasattr(protocolManage.RpcServer, 'getClientIpMap') else {}
info = '已连接客户端: ' + (', '.join([f"{c} ({clientIpMap.get(c, '')})" for c in clients]) if clients else '')
self.disconnectList.clear()
for c in clients:
ip = clientIpMap.get(c, '')
display = f"{c} ({ip})" if ip else c
self.disconnectList.addItem(display)
except:
info = '已连接客户端: 无'
self.disconnectList.clear()
elif hasattr(protocolManage, 'RpcClient') and protocolManage.RpcClient:
mode = '客户端模式'
try:
clientName = protocolManage.RpcClient.clientName
serverInfo = protocolManage.RpcClient.rabbitHost
info = f'客户端名: {clientName} 服务器: {serverInfo}'
self.disconnectList.clear()
except:
info = '客户端信息获取失败'
self.disconnectList.clear()
self.statusLabel.setText(f'服务器模式: {mode}')
self.infoLabel.setText(f'连接信息: {info}')
def disconnectClient(self, item):
# 支持“客户端名 (IP)”格式
text = item.text()
clientName = text.split(' ')[0]
from utils import Globals
protocolManage = Globals.getValue('protocolManage')
if protocolManage and hasattr(protocolManage, 'disconnectClient'):
protocolManage.disconnectClient(clientName)
QMessageBox.information(self, '断开连接', f'已断开客户端 {clientName}')
# 立即刷新列表
self.updateStatusInfo()
class TcpServer(QObject):
updateSignal = pyqtSignal(str)
def __init__(self):
super().__init__()
# 配置信息
self.tcpPort = 12345 # 服务端TCP监听端口
self.udpPort = 54321 # 设备发现UDP端口
self.broadcastAddr = '<broadcast>' # 广播地址
self.tcpRunning = False
self.udpRunning = False
self.tcpThread = None
self.udpThread = None
self.serverSocket = None
self.udpSocket = None
def log(self, message):
currentTime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
logMessage = f"[{currentTime}] {message}"
self.updateSignal.emit(logMessage)
def tcpServer(self):
try:
self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.serverSocket.settimeout(1) # 设置1秒超时
self.serverSocket.bind(('0.0.0.0', self.tcpPort))
self.serverSocket.listen(5)
self.log(f"TCP服务端已启动监听端口 {self.tcpPort}")
while self.tcpRunning:
try:
clientSock, addr = self.serverSocket.accept()
self.log(f"接收到来自 {addr} 的连接")
clientThread = threading.Thread(target=self.handleClient, args=(clientSock,addr))
clientThread.start()
except socket.timeout:
continue # 超时后继续检查运行标志
except:
break
except Exception as e:
self.log(f"TCP服务器错误: {e}")
finally:
if self.serverSocket:
self.serverSocket.close()
self.log("TCP服务端已停止")
def handleClient(self, clientSock, addr):
try:
while True:
data = clientSock.recv(1024)
if not data:
break
Globals.getValue('protocolManage').closeServer()
Globals.getValue('protocolManage').setClentMode(data.decode('utf-8'), rabbitmqHost = addr[0])
self.log(f"收到消息: {data.decode('utf-8')}")
clientSock.send(data) # 返回确认
# 新增:弹窗提示本机已被连接
# QMessageBox.information(None, '连接提示', f'本机已被 {addr[0]} 连接')
except Exception as e:
self.log(f"客户端异常断开: {e}")
finally:
clientSock.close()
def udpDiscoveryServer(self):
try:
self.udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.udpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.udpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.udpSocket.bind(('', self.udpPort))
self.log(f"UDP发现服务已启动监听端口 {self.udpPort}")
while self.udpRunning:
try:
data, addr = self.udpSocket.recvfrom(1024)
if data.decode('utf-8') == "DISCOVERY_REQUEST":
self.log(f"收到来自 {addr} 的发现请求")
response = f"DISCOVERY_RESPONSE:{socket.gethostname()}:{self.tcpPort}"
# print(response)
self.udpSocket.sendto(response.encode('utf-8'), addr)
except:
break
except Exception as e:
self.log(f"UDP服务器错误: {e}")
finally:
if self.udpSocket:
self.udpSocket.close()
self.log("UDP发现服务已停止")
def startTcpServer(self):
if not self.tcpRunning:
self.tcpRunning = True
self.tcpThread = threading.Thread(target=self.tcpServer)
self.tcpThread.start()
def stopTcpServer(self):
if self.tcpRunning:
self.tcpRunning = False
# 唤醒accept阻塞安全关闭线程
if self.serverSocket:
try:
self.serverSocket.shutdown(socket.SHUT_RDWR)
except:
pass
try:
self.serverSocket.close()
except:
pass
if self.tcpThread and self.tcpThread.is_alive():
self.tcpThread.join(timeout=1)
def startUdpServer(self):
if not self.udpRunning:
self.udpRunning = True
self.udpThread = threading.Thread(target=self.udpDiscoveryServer)
self.udpThread.start()
def stopUdpServer(self):
if self.udpRunning:
self.udpRunning = False
# 唤醒recvfrom阻塞安全关闭线程
if self.udpSocket:
try:
self.udpSocket.shutdown(socket.SHUT_RDWR)
except:
pass
try:
self.udpSocket.close()
except:
pass
if self.udpThread and self.udpThread.is_alive():
self.udpThread.join(timeout=1)
class DeviceSlaveWidget(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("设备从站控制")
# self.setGeometry(100, 100, 600, 400)
self.server = TcpServer()
self.server.updateSignal.connect(self.updateLog)
self.statusLabel = None
self.infoLabel = None
self.publicServerInput = None
self.initUI()
# 定时器启动放到控件初始化后
self.statusTimer = QTimer(self)
self.statusTimer.timeout.connect(self.updateStatusInfo)
self.statusTimer.start(1000)
def initUI(self):
# 主布局
mainLayout = QVBoxLayout()
self.statusLabel = QLabel('服务器模式: 无')
mainLayout.addWidget(self.statusLabel)
self.infoLabel = QLabel('连接信息: 无')
mainLayout.addWidget(self.infoLabel)
# 公网客户端连接配置
publicGroup = QGroupBox('公网客户端连接')
publicLayout = QVBoxLayout()
# 服务器地址输入
serverLayout = QHBoxLayout()
serverLayout.addWidget(QLabel('服务器地址:'))
self.publicServerInput = QLineEdit('43.138.48.181')
self.publicServerInput.setPlaceholderText('输入公网服务器IP地址')
serverLayout.addWidget(self.publicServerInput)
publicLayout.addLayout(serverLayout)
# 公网客户端连接按钮
self.publicConnectButton = QPushButton('连接公网服务器')
self.publicConnectButton.clicked.connect(self.connectToPublicServer)
self.publicConnectButton.setObjectName('setButton')
publicLayout.addWidget(self.publicConnectButton)
publicGroup.setLayout(publicLayout)
mainLayout.addWidget(publicGroup)
# 局域网模式控制
lanGroup = QGroupBox('局域网通讯模式')
lanLayout = QVBoxLayout()
self.udpButton = QPushButton("开启远程通讯模式")
self.udpButton.clicked.connect(self.toggleUdpServer)
self.udpButton.setObjectName('setButton')
lanLayout.addWidget(self.udpButton)
lanGroup.setLayout(lanLayout)
mainLayout.addWidget(lanGroup)
# 日志显示
self.logDisplay = QTextEdit()
self.logDisplay.setReadOnly(True)
mainLayout.addWidget(QLabel("服务器日志:"))
mainLayout.addWidget(self.logDisplay)
# 设置中心部件
container = QWidget()
container.setLayout(mainLayout)
self.setCentralWidget(container)
def toggleTcpServer(self):
if self.server.tcpRunning:
self.server.stopTcpServer()
# print("关闭 TCP 服务器")
else:
self.server.startTcpServer()
# print("启动 TCP 服务器")
def connectToPublicServer(self):
"""连接到公网服务器作为客户端"""
serverIp = self.publicServerInput.text().strip()
if not serverIp:
QMessageBox.warning(self, '警告', '请输入服务器地址')
return
# try:
# 获取客户端名称
from protocol.RPC.RpcClient import RpcClient
clientName = RpcClient.getNextClientNameFromRabbitMQ(serverIp)
print(f"获取到客户端名称: {clientName}")
# 设置为客户端模式
Globals.getValue('protocolManage').closeServer()
Globals.getValue('protocolManage').setClentMode(clientName, rabbitmqHost=serverIp)
QMessageBox.information(self, '连接成功', f'已成功连接到公网服务器 {serverIp}\n客户端名称: {clientName}')
# except Exception as e:
# QMessageBox.critical(self, '连接失败', f'连接公网服务器失败: {str(e)}')
def toggleUdpServer(self):
if self.server.udpRunning:
self.server.stopUdpServer()
self.udpButton.setText("开启远程通讯模式")
else:
self.server.startUdpServer()
self.udpButton.setText("关闭远程通讯模式")
self.toggleTcpServer()
def updateLog(self, message):
self.logDisplay.append(message)
def cleanup(self):
if self.server.tcpRunning:
self.server.stopTcpServer()
if self.server.udpRunning:
self.server.stopUdpServer()
def closeEvent(self, event):
self.cleanup()
event.accept()
def __del__(self):
# print(111111111111111111)
self.cleanup()
def updateStatusInfo(self):
protocolManage = Globals.getValue('protocolManage')
mode = ''
info = ''
if protocolManage:
if hasattr(protocolManage, 'RpcClient') and protocolManage.RpcClient:
mode = '客户端模式'
try:
clientName = protocolManage.RpcClient.clientName
serverInfo = protocolManage.RpcClient.rabbitHost
info = f'客户端名: {clientName} 服务器: {serverInfo}'
except:
info = '客户端信息获取失败'
else:
# 没有RpcClient显示无
mode = ''
info = ''
else:
mode = ''
info = ''
self.statusLabel.setText(f'服务器模式: {mode}')
self.infoLabel.setText(f'连接信息: {info}')