package com.fr.design; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.ui.util.UIUtil; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; import com.fr.log.FineLoggerFactory; import com.fr.stable.StableUtils; 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.impl.client.CloseableHttpClient; import com.fr.third.org.apache.http.impl.client.HttpClients; import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; import com.fr.workspace.WorkspaceEvent; import com.fr.workspace.base.WorkspaceConstants; import com.fr.workspace.connect.WorkspaceConnectionInfo; import com.fr.workspace.engine.channel.WorkspaceChannelFactory; import com.fr.workspace.engine.exception.WorkspaceConnectionException; import javax.swing.JOptionPane; import javax.swing.UIManager; /** * RPC连接处理中心 * * @author Roger * @since 11.0 * Created on 2023/12/13 */ public class RPCConnectHandlerCenter { private static volatile boolean alerting = false; private static final int TIMEOUT = 5000; private static Listener listener = new Listener() { @Override public void on(Event event, Workspace workspace) { //暂时先不做重连处理,3次RPC连接失败后提示切换工作目录 showRPCDisconnectDialog(); } }; /** * 开启事件监听 */ public static void startListener() { if (!WorkContext.getCurrent().isLocal()) { EventDispatcher.listen(WorkspaceEvent.LostConnect, listener); } } /** * 弹窗提示连接断开 */ public static void showRPCDisconnectDialog() { UIUtil.invokeLaterIfNeeded(RPCConnectHandlerCenter::showDialog); } /** * RPC连接测试 * * @param info 连接信息 * @return 是否连接成功 */ public static boolean checkRPCConnect(WorkspaceConnectionInfo info) { try { return WorkspaceChannelFactory.testConnection(info); } catch (Exception e) { FineLoggerFactory.getLogger().error(e, e.getMessage()); return false; } } /** * http连接检测,从DesignerSocketIO中移过来的,先保留着 * * @param info 连接信息 * @return 是否连接成功 */ public static boolean checkHttpConnect(WorkspaceConnectionInfo info) { CloseableHttpClient httpclient = HttpClients.createDefault(); 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); if (isErrorStatus(response.getStatusLine().getStatusCode())) { //这边nginx做负载,服务器被kill掉,返回的是502,不会抛错,导致checkRPCConnect通过 //针对500-600的错误码加个判断,其他类型的状态码暂不考虑,如果有遇到再处理,不然怕影响范围大 throw new WorkspaceConnectionException("Response " + response.getStatusLine().toString()); } } catch (Exception e) { FineLoggerFactory.getLogger().error(e, e.getMessage()); return false; } return true; } /** * 提示连接已经断开,如果已经在提示中了就直接返回 */ private static void showDialog() { if (alerting) { return; } synchronized (RPCConnectHandlerCenter.class) { if (alerting) { return; } alerting = true; try { 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(); } finally { alerting = false; } } } /** * 错误状态码 * 5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。代码 说明 * 500 (服务器内部错误) 服务器遇到错误,无法完成请求。 * 501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 * 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 * 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 * 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。 * 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。 * * @param status 错误状态码 * @return 是否是错误状态码 */ private static boolean isErrorStatus(int status) { return status >= 500 && status <= 600; } /** * 停止事件监听 */ public static void stopListener() { if (!WorkContext.getCurrent().isLocal()) { EventDispatcher.stopListen(listener); } } }