diff --git a/clients/java/signalr/src/main/java/CallbackMap.java b/clients/java/signalr/src/main/java/CallbackMap.java index b0182478b0..ec4bf817d0 100644 --- a/clients/java/signalr/src/main/java/CallbackMap.java +++ b/clients/java/signalr/src/main/java/CallbackMap.java @@ -17,12 +17,16 @@ public class CallbackMap { handlers.computeIfAbsent(target, (ac) -> new ArrayList<>(Arrays.asList(action))); } - public Boolean containsKey(String key){ + public Boolean containsKey(String key) { return handlers.containsKey(key); } - public List get(String key){ + public List get(String key) { return handlers.get(key); } + + public void remove(String key) { + handlers.remove(key); + } } diff --git a/clients/java/signalr/src/main/java/HubConnection.java b/clients/java/signalr/src/main/java/HubConnection.java index 30eeec1fc9..79ab0d4808 100644 --- a/clients/java/signalr/src/main/java/HubConnection.java +++ b/clients/java/signalr/src/main/java/HubConnection.java @@ -17,7 +17,7 @@ public class HubConnection { private Gson gson = new Gson(); private HubConnectionState connectionState = HubConnectionState.DISCONNECTED; - public HubConnection(String url, Transport transport){ + public HubConnection(String url, Transport transport) { this.url = url; this.protocol = new JsonHubProtocol(); this.callback = (payload) -> { @@ -126,4 +126,8 @@ public class HubConnection { }; handlers.put(target, action); } + + public void remove(String name) { + handlers.remove(name); + } } \ No newline at end of file diff --git a/clients/java/signalr/src/test/java/HubConnectionTest.java b/clients/java/signalr/src/test/java/HubConnectionTest.java index 77fc1f7f39..23c6b2847d 100644 --- a/clients/java/signalr/src/test/java/HubConnectionTest.java +++ b/clients/java/signalr/src/test/java/HubConnectionTest.java @@ -39,6 +39,74 @@ public class HubConnectionTest { assertEquals(2, value.get(), 0); } + @Test + public void RemoveHandlerByName() throws Exception { + AtomicReference value = new AtomicReference<>(0.0); + Transport mockTransport = new MockEchoTransport(); + HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); + Action action = () -> value.getAndUpdate((val) -> val + 1); + + hubConnection.on("inc", action); + + assertEquals(0.0, value.get(), 0); + + hubConnection.start(); + hubConnection.send("inc"); + + // Confirming that our handler was called and that the counter property was incremented. + assertEquals(1, value.get(), 0); + + hubConnection.remove("inc"); + hubConnection.send("inc"); + assertEquals(1, value.get(), 0); + } + + @Test + public void AddAndRemoveHandlerImmediately() throws Exception { + + AtomicReference value = new AtomicReference<>(0.0); + Transport mockTransport = new MockEchoTransport(); + HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); + Action action = () -> value.getAndUpdate((val) -> val + 1); + + hubConnection.on("inc", action); + hubConnection.remove("inc"); + + assertEquals(0.0, value.get(), 0); + + hubConnection.start(); + hubConnection.send("inc"); + + // Confirming that the handler was removed. + assertEquals(0, value.get(), 0); + } + + @Test + public void RemovingMultipleHandlersWithOneCallToRemove() throws Exception { + + AtomicReference value = new AtomicReference<>(0.0); + Transport mockTransport = new MockEchoTransport(); + HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); + Action action = () -> value.getAndUpdate((val) -> val + 1); + Action secondAction = () -> value.getAndUpdate((val) -> val + 2); + + hubConnection.on("inc", action); + hubConnection.on("inc", secondAction); + + assertEquals(0.0, value.get(), 0); + + hubConnection.start(); + hubConnection.send("inc"); + + assertEquals(3, value.get(), 0); + + hubConnection.remove("inc"); + hubConnection.send("inc"); + + // Confirm that another invocation doesn't change anything because the handlers have been removed. + assertEquals(3, value.get(), 0); + } + @Test public void RegisteringMultipleHandlersThatTakeParamsAndBothGetTriggered() throws Exception { AtomicReference value = new AtomicReference<>(0.0); @@ -58,7 +126,6 @@ public class HubConnectionTest { assertEquals(24, value.get(), 0); } - // We're using AtomicReference in the send tests instead of int here because Gson has trouble deserializing to Integer @Test public void SendWithNoParamsTriggersOnHandler() throws Exception {