|
|
@ -7,33 +7,20 @@ import com.fr.design.EnvChangeEntrance; |
|
|
|
import com.fr.design.dialog.FineJOptionPane; |
|
|
|
import com.fr.design.dialog.FineJOptionPane; |
|
|
|
import com.fr.design.env.DesignerWorkspaceInfo; |
|
|
|
import com.fr.design.env.DesignerWorkspaceInfo; |
|
|
|
import com.fr.design.env.DesignerWorkspaceInfoContext; |
|
|
|
import com.fr.design.env.DesignerWorkspaceInfoContext; |
|
|
|
import com.fr.design.gui.ilable.UILabel; |
|
|
|
|
|
|
|
import com.fr.design.i18n.Toolkit; |
|
|
|
import com.fr.design.i18n.Toolkit; |
|
|
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
|
|
|
|
|
|
import com.fr.design.mainframe.DesignerContext; |
|
|
|
import com.fr.design.mainframe.DesignerContext; |
|
|
|
import com.fr.design.mainframe.loghandler.DesignerLogger; |
|
|
|
import com.fr.design.mainframe.loghandler.DesignerLogger; |
|
|
|
import com.fr.design.mainframe.share.ui.base.MouseClickListener; |
|
|
|
|
|
|
|
import com.fr.design.mainframe.toast.DesignerToastMsgUtil; |
|
|
|
|
|
|
|
import com.fr.design.mainframe.toast.ToastMsgDialog; |
|
|
|
|
|
|
|
import com.fr.design.ui.util.UIUtil; |
|
|
|
import com.fr.design.ui.util.UIUtil; |
|
|
|
import com.fr.design.utils.BrowseUtils; |
|
|
|
|
|
|
|
import com.fr.event.EventDispatcher; |
|
|
|
import com.fr.event.EventDispatcher; |
|
|
|
import com.fr.general.CloudCenter; |
|
|
|
|
|
|
|
import com.fr.general.ComparatorUtils; |
|
|
|
import com.fr.general.ComparatorUtils; |
|
|
|
import com.fr.log.FineLoggerFactory; |
|
|
|
import com.fr.log.FineLoggerFactory; |
|
|
|
import com.fr.report.RemoteDesignConstants; |
|
|
|
import com.fr.report.RemoteDesignConstants; |
|
|
|
import com.fr.serialization.SerializerHelper; |
|
|
|
import com.fr.serialization.SerializerHelper; |
|
|
|
import com.fr.stable.ArrayUtils; |
|
|
|
import com.fr.stable.ArrayUtils; |
|
|
|
import com.fr.stable.StableUtils; |
|
|
|
|
|
|
|
import com.fr.stable.StringUtils; |
|
|
|
import com.fr.stable.StringUtils; |
|
|
|
import com.fr.third.apache.log4j.spi.LoggingEvent; |
|
|
|
import com.fr.third.apache.log4j.spi.LoggingEvent; |
|
|
|
import com.fr.third.org.apache.http.client.config.RequestConfig; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.http.client.methods.HttpGet; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier; |
|
|
|
import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier; |
|
|
|
import com.fr.third.org.apache.http.conn.ssl.TrustSelfSignedStrategy; |
|
|
|
import com.fr.third.org.apache.http.conn.ssl.TrustSelfSignedStrategy; |
|
|
|
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.http.impl.client.HttpClients; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.http.ssl.SSLContexts; |
|
|
|
import com.fr.third.org.apache.http.ssl.SSLContexts; |
|
|
|
import com.fr.web.WebSocketConfig; |
|
|
|
import com.fr.web.WebSocketConfig; |
|
|
|
import com.fr.web.socketio.WebSocketProtocol; |
|
|
|
import com.fr.web.socketio.WebSocketProtocol; |
|
|
@ -42,27 +29,22 @@ import com.fr.workspace.Workspace; |
|
|
|
import com.fr.workspace.base.WorkspaceConstants; |
|
|
|
import com.fr.workspace.base.WorkspaceConstants; |
|
|
|
import com.fr.workspace.connect.WorkspaceConnection; |
|
|
|
import com.fr.workspace.connect.WorkspaceConnection; |
|
|
|
import com.fr.workspace.connect.WorkspaceConnectionInfo; |
|
|
|
import com.fr.workspace.connect.WorkspaceConnectionInfo; |
|
|
|
|
|
|
|
import com.fr.workspace.server.socket.SocketInfoOperator; |
|
|
|
import io.socket.client.IO; |
|
|
|
import io.socket.client.IO; |
|
|
|
import io.socket.client.Socket; |
|
|
|
import io.socket.client.Socket; |
|
|
|
import io.socket.emitter.Emitter; |
|
|
|
import io.socket.emitter.Emitter; |
|
|
|
|
|
|
|
|
|
|
|
import javax.net.ssl.SSLContext; |
|
|
|
|
|
|
|
import javax.swing.BorderFactory; |
|
|
|
|
|
|
|
import javax.swing.JOptionPane; |
|
|
|
|
|
|
|
import javax.swing.JPanel; |
|
|
|
|
|
|
|
import javax.swing.UIManager; |
|
|
|
|
|
|
|
import java.awt.BorderLayout; |
|
|
|
|
|
|
|
import java.awt.Color; |
|
|
|
|
|
|
|
import java.awt.Cursor; |
|
|
|
|
|
|
|
import java.awt.event.MouseEvent; |
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.File; |
|
|
|
import java.io.FileInputStream; |
|
|
|
import java.io.FileInputStream; |
|
|
|
|
|
|
|
import java.security.KeyStore; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
|
|
|
|
import javax.net.ssl.SSLContext; |
|
|
|
|
|
|
|
import javax.swing.*; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.net.URI; |
|
|
|
import java.net.URI; |
|
|
|
import java.net.URL; |
|
|
|
import java.net.URL; |
|
|
|
import java.security.KeyStore; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
|
|
|
|
import java.util.Timer; |
|
|
|
import java.util.Timer; |
|
|
|
|
|
|
|
import java.util.TimerTask; |
|
|
|
|
|
|
|
|
|
|
|
public class DesignerSocketIO { |
|
|
|
public class DesignerSocketIO { |
|
|
|
|
|
|
|
|
|
|
@ -72,21 +54,18 @@ public class DesignerSocketIO { |
|
|
|
Disconnecting |
|
|
|
Disconnecting |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static final String WEBSOCKET_HELP_DOC = CloudCenter.getInstance().acquireUrlByKind("websocketConnect", "https://help.fanruan.com/finereport/doc-view-2512.html"); |
|
|
|
|
|
|
|
private static final String HTTPS = "https"; |
|
|
|
private static final String HTTPS = "https"; |
|
|
|
private static final String HTTP = "http"; |
|
|
|
private static final String HTTP = "http"; |
|
|
|
private static Socket socket = null; |
|
|
|
private static Socket socket = null; |
|
|
|
private static Status status = Status.Disconnected; |
|
|
|
private static Status status = Status.Disconnected; |
|
|
|
private static Timer disConnectHintTimer = null; |
|
|
|
private static Timer disConnectHintTimer = null; |
|
|
|
private static long disConnectHintTimerDelay = 3000; |
|
|
|
private static long disConnectHintTimerDelay = 3000; |
|
|
|
private static final int TIMEOUT = 5000; |
|
|
|
|
|
|
|
//维护一个当前工作环境的uri列表
|
|
|
|
//维护一个当前工作环境的uri列表
|
|
|
|
private static String[] uri; |
|
|
|
private static String[] uri; |
|
|
|
//维护一个关于uri列表的计数器
|
|
|
|
//维护一个关于uri列表的计数器
|
|
|
|
private static int count; |
|
|
|
private static int count; |
|
|
|
// 当前webSocket选择的协议
|
|
|
|
// 当前webSocket选择的协议
|
|
|
|
private static String currentProtocol; |
|
|
|
private static String currentProtocol; |
|
|
|
private static ToastMsgDialog dialog = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void close() { |
|
|
|
public static void close() { |
|
|
@ -154,7 +133,7 @@ public class DesignerSocketIO { |
|
|
|
String certPath = connection.getCertPath(); |
|
|
|
String certPath = connection.getCertPath(); |
|
|
|
String certSecretKey = connection.getCertSecretKey(); |
|
|
|
String certSecretKey = connection.getCertSecretKey(); |
|
|
|
if (StringUtils.isBlank(certPath) || StringUtils.isBlank(certSecretKey)) { |
|
|
|
if (StringUtils.isBlank(certPath) || StringUtils.isBlank(certSecretKey)) { |
|
|
|
return SSLContexts.createDefault(); |
|
|
|
return SSLContexts.createDefault(); |
|
|
|
} |
|
|
|
} |
|
|
|
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); |
|
|
|
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); |
|
|
|
try (FileInputStream keystore = new FileInputStream(new File(certPath))) { |
|
|
|
try (FileInputStream keystore = new FileInputStream(new File(certPath))) { |
|
|
@ -207,7 +186,6 @@ public class DesignerSocketIO { |
|
|
|
private static final Emitter.Listener failRetry = new Emitter.Listener() { |
|
|
|
private static final Emitter.Listener failRetry = new Emitter.Listener() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void call(Object... args) { |
|
|
|
public void call(Object... args) { |
|
|
|
showSocketDisconnectToast(); |
|
|
|
|
|
|
|
printLog(args, PrintEventLogImpl.WARN, "failed args: {}"); |
|
|
|
printLog(args, PrintEventLogImpl.WARN, "failed args: {}"); |
|
|
|
status = Status.Disconnecting; |
|
|
|
status = Status.Disconnecting; |
|
|
|
socket.close(); |
|
|
|
socket.close(); |
|
|
@ -246,38 +224,41 @@ public class DesignerSocketIO { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void call(Object... objects) { |
|
|
|
public void call(Object... objects) { |
|
|
|
FineLoggerFactory.getLogger().info("start disConnectHintTimer"); |
|
|
|
FineLoggerFactory.getLogger().info("start disConnectHintTimer"); |
|
|
|
/* |
|
|
|
disConnectHintTimer = new Timer(); |
|
|
|
* todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上,切换成心跳断开之后进行提醒, |
|
|
|
disConnectHintTimer.schedule(new TimerTask() { |
|
|
|
* socket 只用推日志和通知配置变更 |
|
|
|
@Override |
|
|
|
*/ |
|
|
|
public void run() { |
|
|
|
printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}"); |
|
|
|
try { |
|
|
|
if (status != Status.Disconnecting) { |
|
|
|
/* |
|
|
|
dealWithSocketDisconnect(); |
|
|
|
* todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上,切换成心跳断开之后进行提醒, |
|
|
|
} |
|
|
|
* socket 只用推日志和通知配置变更 |
|
|
|
status = Status.Disconnected; |
|
|
|
*/ |
|
|
|
|
|
|
|
printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}"); |
|
|
|
|
|
|
|
if (status != Status.Disconnecting) { |
|
|
|
|
|
|
|
showConnectionLostDialog(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
status = Status.Disconnected; |
|
|
|
|
|
|
|
} finally { |
|
|
|
|
|
|
|
disConnectHintTimer.cancel(); |
|
|
|
|
|
|
|
disConnectHintTimer = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, disConnectHintTimerDelay); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
private static void dealWithSocketDisconnect() { |
|
|
|
private static void showConnectionLostDialog() { |
|
|
|
if (checkRPCConnect()) { |
|
|
|
|
|
|
|
showSocketDisconnectToast(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
showRPCDisconnectDialog(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void showSocketDisconnectToast() { |
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
UIUtil.invokeLaterIfNeeded(new Runnable() { |
|
|
|
UIUtil.invokeLaterIfNeeded(new Runnable() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void run() { |
|
|
|
public void run() { |
|
|
|
if (dialog == null) { |
|
|
|
FineJOptionPane.showMessageDialog( |
|
|
|
dialog = DesignerToastMsgUtil.createPromptDialog(createDialogContent()); |
|
|
|
DesignerContext.getDesignerFrame(), |
|
|
|
} |
|
|
|
Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"), |
|
|
|
|
|
|
|
UIManager.getString("OptionPane.messageDialogTitle"), |
|
|
|
if (!dialog.isShow()) { |
|
|
|
JOptionPane.ERROR_MESSAGE, |
|
|
|
dialog.setVisible(true); |
|
|
|
UIManager.getIcon("OptionPane.errorIcon")); |
|
|
|
} |
|
|
|
EnvChangeEntrance.getInstance().chooseEnv(); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
} catch (Exception e) { |
|
|
|
} catch (Exception e) { |
|
|
@ -285,57 +266,6 @@ public class DesignerSocketIO { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static JPanel createDialogContent() { |
|
|
|
|
|
|
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
|
|
|
|
|
|
jPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_WebSocket_Lost_Tip")), BorderLayout.WEST); |
|
|
|
|
|
|
|
UILabel hyperLinkLabel = new UILabel(Toolkit.i18nText("Fine-Design_WebSocket_Lost_Tip_HyperLink_Text")); |
|
|
|
|
|
|
|
hyperLinkLabel.addMouseListener(new MouseClickListener() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void mouseClicked(MouseEvent e) { |
|
|
|
|
|
|
|
BrowseUtils.browser(WEBSOCKET_HELP_DOC); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
hyperLinkLabel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); |
|
|
|
|
|
|
|
hyperLinkLabel.setForeground(Color.BLUE); |
|
|
|
|
|
|
|
hyperLinkLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
|
|
|
|
|
|
|
jPanel.add(hyperLinkLabel, BorderLayout.CENTER); |
|
|
|
|
|
|
|
return jPanel; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void showRPCDisconnectDialog() { |
|
|
|
|
|
|
|
UIUtil.invokeLaterIfNeeded(new Runnable() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void run() { |
|
|
|
|
|
|
|
FineJOptionPane.showMessageDialog( |
|
|
|
|
|
|
|
DesignerContext.getDesignerFrame(), |
|
|
|
|
|
|
|
Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"), |
|
|
|
|
|
|
|
UIManager.getString("OptionPane.messageDialogTitle"), |
|
|
|
|
|
|
|
JOptionPane.ERROR_MESSAGE, |
|
|
|
|
|
|
|
UIManager.getIcon("OptionPane.errorIcon")); |
|
|
|
|
|
|
|
EnvChangeEntrance.getInstance().chooseEnv(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static boolean checkRPCConnect() { |
|
|
|
|
|
|
|
CloseableHttpClient httpclient = HttpClients.createDefault(); |
|
|
|
|
|
|
|
WorkspaceConnectionInfo info = getConnectionInfo(); |
|
|
|
|
|
|
|
HttpGet httpGet = new HttpGet(StableUtils.pathJoin(info.getUrl(), WorkspaceConstants.CONTROLLER_PREFIX, WorkspaceConstants.VT)); |
|
|
|
|
|
|
|
RequestConfig requestConfig = RequestConfig |
|
|
|
|
|
|
|
.custom() |
|
|
|
|
|
|
|
.setConnectTimeout(TIMEOUT) |
|
|
|
|
|
|
|
.setConnectionRequestTimeout(TIMEOUT) |
|
|
|
|
|
|
|
.build(); |
|
|
|
|
|
|
|
httpGet.setConfig(requestConfig); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
CloseableHttpResponse response = httpclient.execute(httpGet); |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
|
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//配置变更监听器
|
|
|
|
//配置变更监听器
|
|
|
|
private static final Emitter.Listener modifyConfig = new Emitter.Listener() { |
|
|
|
private static final Emitter.Listener modifyConfig = new Emitter.Listener() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|