This is an automated email from the ASF dual-hosted git repository.

Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new da3616aaef fix: close removed websocket sync clients (#6784) (#6928)
da3616aaef is described below

commit da3616aaef760af2a6adee8b346b2cb9990e01df
Author: BobSong <[email protected]>
AuthorDate: Mon Aug 17 15:25:00 2026 +0800

    fix: close removed websocket sync clients (#6784) (#6928)
    
    Co-authored-by: aias00 <[email protected]>
---
 .../data/websocket/WebsocketSyncDataService.java   |  1 +
 .../websocket/WebsocketSyncDataServiceTest.java    | 77 ++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git 
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/WebsocketSyncDataService.java
 
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/WebsocketSyncDataService.java
index c85fa83a35..2b5abaa950 100644
--- 
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/WebsocketSyncDataService.java
+++ 
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/WebsocketSyncDataService.java
@@ -145,6 +145,7 @@ public class WebsocketSyncDataService implements 
SyncDataService {
         while (iterator.hasNext()) {
             ShenyuWebsocketClient websocketClient = iterator.next();
             if (!websocketClient.isOpen()) {
+                websocketClient.nowClose();
                 iterator.remove();
                 continue;
             }
diff --git 
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/WebsocketSyncDataServiceTest.java
 
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/WebsocketSyncDataServiceTest.java
new file mode 100644
index 0000000000..a34ef976d6
--- /dev/null
+++ 
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/WebsocketSyncDataServiceTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.sync.data.websocket;
+
+import org.apache.shenyu.common.config.ShenyuConfig;
+import 
org.apache.shenyu.plugin.sync.data.websocket.client.ShenyuWebsocketClient;
+import org.apache.shenyu.plugin.sync.data.websocket.config.WebsocketConfig;
+import org.apache.shenyu.sync.data.api.AiProxyApiKeyDataSubscriber;
+import org.apache.shenyu.sync.data.api.AuthDataSubscriber;
+import org.apache.shenyu.sync.data.api.DiscoveryUpstreamDataSubscriber;
+import org.apache.shenyu.sync.data.api.MetaDataSubscriber;
+import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
+import org.apache.shenyu.sync.data.api.ProxySelectorDataSubscriber;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public final class WebsocketSyncDataServiceTest {
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testMasterCheckClosesRemovedClient() throws Exception {
+        WebsocketConfig websocketConfig = new WebsocketConfig();
+        websocketConfig.setUrls(Collections.emptyList());
+        WebsocketSyncDataService websocketSyncDataService = new 
WebsocketSyncDataService(
+                websocketConfig,
+                new ShenyuConfig(),
+                mock(PluginDataSubscriber.class),
+                Collections.<MetaDataSubscriber>emptyList(),
+                Collections.<AuthDataSubscriber>emptyList(),
+                Collections.<ProxySelectorDataSubscriber>emptyList(),
+                Collections.<DiscoveryUpstreamDataSubscriber>emptyList(),
+                Collections.<AiProxyApiKeyDataSubscriber>emptyList(),
+                mock(ServerProperties.class));
+        ShenyuWebsocketClient websocketClient = 
mock(ShenyuWebsocketClient.class);
+        when(websocketClient.isOpen()).thenReturn(false);
+        Field clientsField = 
WebsocketSyncDataService.class.getDeclaredField("clients");
+        clientsField.setAccessible(true);
+        List<ShenyuWebsocketClient> clients = (List<ShenyuWebsocketClient>) 
clientsField
+                .get(websocketSyncDataService);
+        clients.add(websocketClient);
+
+        try {
+            Method masterCheck = 
WebsocketSyncDataService.class.getDeclaredMethod("masterCheck");
+            masterCheck.setAccessible(true);
+            masterCheck.invoke(websocketSyncDataService);
+            verify(websocketClient).nowClose();
+            assertTrue(clients.isEmpty());
+        } finally {
+            websocketSyncDataService.close();
+        }
+    }
+}

Reply via email to