Browse Source

Pull request #8904: REPORT-71425 websocket断开优化 同步到10.0.19.13

Merge in DESIGN/design from ~HADES/design:release/10.0 to release/10.0

* commit '527618f35a6891c8cfe7406f4e93b11224d44c17':
  REPORT-71425 websocket断开优化 同步到10.0.19.13
security/10.0
Hades 3 years ago
parent
commit
38fa734e03
  1. 20
      designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java
  2. 22
      designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java
  3. 136
      designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java

20
designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java

@ -6,17 +6,17 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.stable.Constants; import com.fr.stable.Constants;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Window;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JEditorPane; import javax.swing.JEditorPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Frame;
import java.awt.Window;
/** /**
* Created by kerry on 5/6/21 * Created by kerry on 5/6/21
@ -31,6 +31,13 @@ public class DesignerToastMsgUtil {
} }
public static ToastMsgDialog createPromptDialog(String text) {
return createDialog(PROMPT_ICON, toastPane(text), DesignerContext.getDesignerFrame());
}
public static ToastMsgDialog createPromptDialog(JPanel contentPane) {
return createDialog(PROMPT_ICON, contentPane, DesignerContext.getDesignerFrame());
}
public static void toastPrompt(JPanel contendPane) { public static void toastPrompt(JPanel contendPane) {
toastPane(PROMPT_ICON, contendPane, DesignerContext.getDesignerFrame()); toastPane(PROMPT_ICON, contendPane, DesignerContext.getDesignerFrame());
@ -69,6 +76,11 @@ public class DesignerToastMsgUtil {
} }
private static void toastPane(Icon icon, JPanel contendPane, Window parent) { private static void toastPane(Icon icon, JPanel contendPane, Window parent) {
ToastMsgDialog dialog = createDialog(icon, contendPane, parent);
dialog.setVisible(true);
}
private static ToastMsgDialog createDialog(Icon icon, JPanel contendPane, Window parent) {
JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane();
UILabel uiLabel = new UILabel(icon); UILabel uiLabel = new UILabel(icon);
uiLabel.setVerticalAlignment(SwingConstants.TOP); uiLabel.setVerticalAlignment(SwingConstants.TOP);
@ -83,7 +95,7 @@ public class DesignerToastMsgUtil {
} else { } else {
dialog = new ToastMsgDialog((Frame) parent, pane); dialog = new ToastMsgDialog((Frame) parent, pane);
} }
dialog.setVisible(true); return dialog;
} }

22
designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java

@ -3,10 +3,11 @@ package com.fr.design.mainframe.toast;
import com.fr.concurrent.NamedThreadFactory; import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.dialog.UIDialog; import com.fr.design.dialog.UIDialog;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.module.ModuleContext; import com.fr.module.ModuleContext;
import java.awt.Dialog;
import javax.swing.JPanel; import javax.swing.JPanel;
import java.awt.Dialog;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Frame; import java.awt.Frame;
import java.awt.Point; import java.awt.Point;
@ -24,6 +25,7 @@ public class ToastMsgDialog extends UIDialog {
private ScheduledExecutorService TIMER; private ScheduledExecutorService TIMER;
private int hide_height = 0; private int hide_height = 0;
private JPanel contentPane; private JPanel contentPane;
private boolean show = false;
public ToastMsgDialog(Frame parent, JPanel panel) { public ToastMsgDialog(Frame parent, JPanel panel) {
super(parent); super(parent);
@ -50,12 +52,16 @@ public class ToastMsgDialog extends UIDialog {
hide_height = dimension.height; hide_height = dimension.height;
setSize(new Dimension(dimension.width, 0)); setSize(new Dimension(dimension.width, 0));
contentPane.setSize(dimension); contentPane.setSize(dimension);
setLocationRelativeTo(DesignerContext.getDesignerFrame().getContentFrame()); setRelativeLocation(dimension);
int positionY = DesignerContext.getDesignerFrame().getContentFrame().getLocationOnScreen().y + 10;
setLocation((DesignerContext.getDesignerFrame().getWidth() - dimension.width) / 2, positionY);
addMouseEvent(contentPane); addMouseEvent(contentPane);
} }
private void setRelativeLocation(Dimension dimension) {
DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
int positionX = designerFrame.getLocationOnScreen().x + (designerFrame.getWidth() - dimension.width) / 2;
int positionY = designerFrame.getContentFrame().getLocationOnScreen().y + 10;
this.setLocation(positionX, positionY);
}
private Dimension calculatePreferSize() { private Dimension calculatePreferSize() {
Dimension contentDimension = contentPane.getPreferredSize(); Dimension contentDimension = contentPane.getPreferredSize();
@ -65,6 +71,7 @@ public class ToastMsgDialog extends UIDialog {
public void display(JPanel outerJPanel) { public void display(JPanel outerJPanel) {
show = true;
outerJPanel.setLocation(0, -hide_height); outerJPanel.setLocation(0, -hide_height);
ScheduledExecutorService TIP_TOOL_TIMER = createToastScheduleExecutorService(); ScheduledExecutorService TIP_TOOL_TIMER = createToastScheduleExecutorService();
TIP_TOOL_TIMER.scheduleAtFixedRate(new Runnable() { TIP_TOOL_TIMER.scheduleAtFixedRate(new Runnable() {
@ -98,12 +105,13 @@ public class ToastMsgDialog extends UIDialog {
TIP_TOOL_TIMER.shutdown(); TIP_TOOL_TIMER.shutdown();
ToastMsgDialog.this.setVisible(false); ToastMsgDialog.this.setVisible(false);
ToastMsgDialog.this.dispose(); ToastMsgDialog.this.dispose();
ToastMsgDialog.this.show = false;
} }
outerJPanel.setLocation(point.x, point.y - 5); outerJPanel.setLocation(point.x, point.y - 5);
Dimension dimension = ToastMsgDialog.this.getSize(); Dimension dimension = ToastMsgDialog.this.getSize();
ToastMsgDialog.this.setSize(new Dimension(dimension.width, dimension.height - 5)); ToastMsgDialog.this.setSize(new Dimension(dimension.width, dimension.height - 5));
} }
}, 0,50, TimeUnit.MILLISECONDS); }, 0, 50, TimeUnit.MILLISECONDS);
} }
}, 5000, TimeUnit.MILLISECONDS); }, 5000, TimeUnit.MILLISECONDS);
@ -159,5 +167,7 @@ public class ToastMsgDialog extends UIDialog {
super.dispose(); super.dispose();
} }
public boolean isShow() {
return show;
}
} }

136
designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java

@ -7,20 +7,33 @@ 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;
@ -29,7 +42,6 @@ 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;
@ -38,15 +50,21 @@ import io.socket.engineio.client.transports.Polling;
import io.socket.engineio.client.transports.WebSocket; import io.socket.engineio.client.transports.WebSocket;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.net.URL;
import java.security.KeyStore; import java.security.KeyStore;
import java.util.Arrays; import java.util.Arrays;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.swing.*; 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.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URL;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask;
public class DesignerSocketIO { public class DesignerSocketIO {
@ -56,18 +74,21 @@ 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() {
@ -109,6 +130,7 @@ public class DesignerSocketIO {
} else { } else {
//表示所有的uri都连接不成功 //表示所有的uri都连接不成功
FineLoggerFactory.getLogger().warn("All uris failed to connect"); FineLoggerFactory.getLogger().warn("All uris failed to connect");
showSocketDisconnectToast();
} }
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
@ -227,41 +249,35 @@ 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(); /*
disConnectHintTimer.schedule(new TimerTask() { * todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上切换成心跳断开之后进行提醒
@Override * socket 只用推日志和通知配置变更
public void run() { */
try { printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}");
/* if (status != Status.Disconnecting) {
* todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上切换成心跳断开之后进行提醒 dealWithSocketDisconnect();
* 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 showConnectionLostDialog() { private static void dealWithSocketDisconnect() {
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() {
FineJOptionPane.showMessageDialog( if (dialog == null || !dialog.isShow()) {
DesignerContext.getDesignerFrame(), dialog = DesignerToastMsgUtil.createPromptDialog(createDialogContent());
Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"), dialog.setVisible(true);
UIManager.getString("OptionPane.messageDialogTitle"), }
JOptionPane.ERROR_MESSAGE,
UIManager.getIcon("OptionPane.errorIcon"));
EnvChangeEntrance.getInstance().chooseEnv();
} }
}); });
} catch (Exception e) { } catch (Exception e) {
@ -269,6 +285,57 @@ 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
@ -282,7 +349,7 @@ public class DesignerSocketIO {
private static void printLog(Object[] objects, PrintEventLog printEventLog, String prefix) { private static void printLog(Object[] objects, PrintEventLog printEventLog, String prefix) {
for (Object object : objects) { for (Object object : objects) {
if (object instanceof Throwable) { if (object instanceof Throwable) {
Throwable throwable = (Throwable) object; Throwable throwable = (Throwable) object;
printEventLog.printThrowable(throwable); printEventLog.printThrowable(throwable);
} else { } else {
printEventLog.print(prefix, object); printEventLog.print(prefix, object);
@ -292,7 +359,8 @@ public class DesignerSocketIO {
interface PrintEventLog { interface PrintEventLog {
void printThrowable(Throwable throwable); void printThrowable(Throwable throwable);
void print(String s, Object ...object);
void print(String s, Object... object);
} }
enum PrintEventLogImpl implements PrintEventLog { enum PrintEventLogImpl implements PrintEventLog {

Loading…
Cancel
Save