|
|
|
@ -5,29 +5,40 @@ import com.fr.decision.webservice.utils.DecisionServiceConstants;
|
|
|
|
|
import com.fr.design.DesignerEnvManager; |
|
|
|
|
import com.fr.design.EnvChangeEntrance; |
|
|
|
|
import com.fr.design.dialog.FineJOptionPane; |
|
|
|
|
import com.fr.design.env.DesignerWorkspaceInfo; |
|
|
|
|
import com.fr.design.env.DesignerWorkspaceInfoContext; |
|
|
|
|
import com.fr.design.i18n.Toolkit; |
|
|
|
|
import com.fr.design.mainframe.DesignerContext; |
|
|
|
|
import com.fr.design.mainframe.loghandler.DesignerLogger; |
|
|
|
|
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.general.ComparatorUtils; |
|
|
|
|
import com.fr.log.FineLoggerFactory; |
|
|
|
|
import com.fr.report.RemoteDesignConstants; |
|
|
|
|
import com.fr.serialization.SerializerHelper; |
|
|
|
|
import com.fr.stable.ArrayUtils; |
|
|
|
|
import com.fr.stable.StringUtils; |
|
|
|
|
import com.fr.third.apache.log4j.spi.LoggingEvent; |
|
|
|
|
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.ssl.SSLContexts; |
|
|
|
|
import com.fr.web.WebSocketConfig; |
|
|
|
|
import com.fr.web.socketio.WebSocketProtocol; |
|
|
|
|
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.WorkspaceConnection; |
|
|
|
|
import com.fr.workspace.connect.WorkspaceConnectionInfo; |
|
|
|
|
import com.fr.workspace.server.socket.SocketInfoOperator; |
|
|
|
|
import io.socket.client.IO; |
|
|
|
|
import io.socket.client.Socket; |
|
|
|
|
import io.socket.emitter.Emitter; |
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
|
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.net.URI; |
|
|
|
@ -37,26 +48,14 @@ import java.util.TimerTask;
|
|
|
|
|
|
|
|
|
|
public class DesignerSocketIO { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static { |
|
|
|
|
EventDispatcher.listen(WorkspaceEvent.LostConnect, new Listener<Workspace>() { |
|
|
|
|
@Override |
|
|
|
|
public void on(Event event, Workspace param) { |
|
|
|
|
// 远程设计websocket不支持wss 所以断开无法提醒
|
|
|
|
|
// 使用远程设计的心跳断开来提醒断开
|
|
|
|
|
if (DesignerEnvManager.getEnvManager().isHttps()) { |
|
|
|
|
showConnectionLostDialog(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum Status { |
|
|
|
|
Connected, |
|
|
|
|
Disconnected, |
|
|
|
|
Disconnecting |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static final String HTTPS = "https"; |
|
|
|
|
private static final String HTTP = "http"; |
|
|
|
|
private static Socket socket = null; |
|
|
|
|
private static Status status = Status.Disconnected; |
|
|
|
|
private static Timer disConnectHintTimer = null; |
|
|
|
@ -65,6 +64,8 @@ public class DesignerSocketIO {
|
|
|
|
|
private static String[] uri; |
|
|
|
|
//维护一个关于uri列表的计数器
|
|
|
|
|
private static int count; |
|
|
|
|
// 当前webSocket选择的协议
|
|
|
|
|
private static String currentProtocol; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void close() { |
|
|
|
@ -95,7 +96,7 @@ public class DesignerSocketIO {
|
|
|
|
|
//根据uri和计数器建立连接,并注册监听
|
|
|
|
|
try { |
|
|
|
|
if (count < uri.length) { |
|
|
|
|
socket = IO.socket(new URI(uri[count])); |
|
|
|
|
socket = IO.socket(new URI(uri[count]), createOptions()); |
|
|
|
|
socket.on(WorkspaceConstants.WS_LOGRECORD, printLog); |
|
|
|
|
socket.on(WorkspaceConstants.CONFIG_MODIFY, modifyConfig); |
|
|
|
|
socket.on(Socket.EVENT_CONNECT_ERROR, failRetry); |
|
|
|
@ -112,15 +113,58 @@ public class DesignerSocketIO {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static IO.Options createOptions() { |
|
|
|
|
IO.Options options = new IO.Options(); |
|
|
|
|
try { |
|
|
|
|
if (ComparatorUtils.equals(currentProtocol, HTTPS)) { |
|
|
|
|
options.sslContext = getSSLContext(); |
|
|
|
|
options.hostnameVerifier = NoopHostnameVerifier.INSTANCE; |
|
|
|
|
options.secure = true; |
|
|
|
|
} |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
|
|
|
|
} |
|
|
|
|
return options; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static SSLContext getSSLContext() throws Exception { |
|
|
|
|
WorkspaceConnectionInfo connection = getConnectionInfo(); |
|
|
|
|
String certPath = connection.getCertPath(); |
|
|
|
|
String certSecretKey = connection.getCertSecretKey(); |
|
|
|
|
if (StringUtils.isBlank(certPath) || StringUtils.isBlank(certSecretKey)) { |
|
|
|
|
return SSLContexts.createDefault(); |
|
|
|
|
} |
|
|
|
|
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); |
|
|
|
|
try (FileInputStream keystore = new FileInputStream(new File(certPath))) { |
|
|
|
|
trustStore.load(keystore, certSecretKey.toCharArray()); |
|
|
|
|
} |
|
|
|
|
return SSLContexts.custom() |
|
|
|
|
.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) |
|
|
|
|
.build(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static WorkspaceConnectionInfo getConnectionInfo() { |
|
|
|
|
if (DesignerWorkspaceInfoContext.getWorkspaceInfo() == null) { |
|
|
|
|
String currentName = DesignerEnvManager.getEnvManager().getCurEnvName(); |
|
|
|
|
DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(currentName); |
|
|
|
|
return info.getConnection(); |
|
|
|
|
} else { |
|
|
|
|
return DesignerWorkspaceInfoContext.getWorkspaceInfo().getConnection(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static String[] getSocketUri() throws IOException { |
|
|
|
|
Workspace current = WorkContext.getCurrent(); |
|
|
|
|
URL url = new URL(current.getPath()); |
|
|
|
|
Integer[] ports = current.get(SocketInfoOperator.class).getPort(); |
|
|
|
|
WorkspaceConnection connection = current.getConnection(); |
|
|
|
|
// 服务器配置https webSocket可能是wss也可能是ws webSocket的协议可以单独配置
|
|
|
|
|
WebSocketProtocol webSocketProtocol = WebSocketConfig.getInstance().getProtocol(); |
|
|
|
|
currentProtocol = webSocketProtocol == WebSocketProtocol.PLAIN ? HTTP : HTTPS; |
|
|
|
|
String[] result = new String[ports.length]; |
|
|
|
|
for (int i = 0; i < ports.length; i++) { |
|
|
|
|
result[i] = String.format("%s://%s:%s%s?%s=%s&%s=%s", |
|
|
|
|
url.getProtocol(), |
|
|
|
|
currentProtocol, |
|
|
|
|
url.getHost(), |
|
|
|
|
ports[i], |
|
|
|
|
WorkspaceConstants.WS_NAMESPACE, |
|
|
|
@ -129,6 +173,7 @@ public class DesignerSocketIO {
|
|
|
|
|
RemoteDesignConstants.USER_LOCK_ID, |
|
|
|
|
connection.getId()); |
|
|
|
|
} |
|
|
|
|
FineLoggerFactory.getLogger().error("Available ports: {}, current Protocol: {}", Arrays.toString(ports), currentProtocol); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -136,7 +181,7 @@ public class DesignerSocketIO {
|
|
|
|
|
private static final Emitter.Listener failRetry = new Emitter.Listener() { |
|
|
|
|
@Override |
|
|
|
|
public void call(Object... args) { |
|
|
|
|
FineLoggerFactory.getLogger().warn("failed args: {}", Arrays.toString(args)); |
|
|
|
|
printLog(args, PrintEventLogImpl.WARN, "failed args: {}"); |
|
|
|
|
status = Status.Disconnecting; |
|
|
|
|
socket.close(); |
|
|
|
|
count++; |
|
|
|
@ -183,7 +228,7 @@ public class DesignerSocketIO {
|
|
|
|
|
* todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上,切换成心跳断开之后进行提醒, |
|
|
|
|
* socket 只用推日志和通知配置变更 |
|
|
|
|
*/ |
|
|
|
|
FineLoggerFactory.getLogger().error("disConnected args: {}", Arrays.toString(objects)); |
|
|
|
|
printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}"); |
|
|
|
|
if (status != Status.Disconnecting) { |
|
|
|
|
showConnectionLostDialog(); |
|
|
|
|
} |
|
|
|
@ -199,7 +244,7 @@ public class DesignerSocketIO {
|
|
|
|
|
|
|
|
|
|
private static void showConnectionLostDialog() { |
|
|
|
|
try { |
|
|
|
|
UIUtil.invokeAndWaitIfNeeded(new Runnable() { |
|
|
|
|
UIUtil.invokeLaterIfNeeded(new Runnable() { |
|
|
|
|
@Override |
|
|
|
|
public void run() { |
|
|
|
|
FineJOptionPane.showMessageDialog( |
|
|
|
@ -226,4 +271,46 @@ public class DesignerSocketIO {
|
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
private static void printLog(Object[] objects, PrintEventLog printEventLog, String prefix) { |
|
|
|
|
for (Object object : objects) { |
|
|
|
|
if (object instanceof Throwable) { |
|
|
|
|
Throwable throwable = (Throwable) object; |
|
|
|
|
printEventLog.printThrowable(throwable); |
|
|
|
|
} else { |
|
|
|
|
printEventLog.print(prefix, object); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
interface PrintEventLog { |
|
|
|
|
void printThrowable(Throwable throwable); |
|
|
|
|
void print(String s, Object ...object); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum PrintEventLogImpl implements PrintEventLog { |
|
|
|
|
ERROR { |
|
|
|
|
@Override |
|
|
|
|
public void printThrowable(Throwable throwable) { |
|
|
|
|
FineLoggerFactory.getLogger().error(throwable.getMessage(), throwable); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void print(String s, Object... object) { |
|
|
|
|
FineLoggerFactory.getLogger().error(s, object); |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
WARN { |
|
|
|
|
@Override |
|
|
|
|
public void printThrowable(Throwable throwable) { |
|
|
|
|
FineLoggerFactory.getLogger().warn(throwable.getMessage(), throwable); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void print(String s, Object... object) { |
|
|
|
|
FineLoggerFactory.getLogger().warn(s, object); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|