Skip to content

Commit 3c636c3

Browse files
author
Anya Zenkina
committed
Initial commit for user_id feature
1 parent 1894ed2 commit 3c636c3

File tree

7 files changed

+131
-7
lines changed

7 files changed

+131
-7
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.pusher.client.channel;
2+
3+
public class EventMetadata {
4+
String userId;
5+
6+
public String getUserId() {
7+
return userId;
8+
}
9+
10+
11+
public void setUserId(String value) {
12+
this.userId = value;
13+
}
14+
15+
}

src/main/java/com/pusher/client/channel/PresenceChannelEventListener.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,6 @@ public interface PresenceChannelEventListener extends PrivateChannelEventListene
3939
* The user who unsubscribed.
4040
*/
4141
void userUnsubscribed(String channelName, User user);
42+
43+
void onEventWithMetadata(String channelName, String eventName, String data, EventMetadata metadata);
4244
}

src/main/java/com/pusher/client/channel/impl/ChannelImpl.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public class ChannelImpl implements InternalChannel {
2323
private final Map<String, Set<SubscriptionEventListener>> eventNameToListenerMap = new HashMap<String, Set<SubscriptionEventListener>>();
2424
protected volatile ChannelState state = ChannelState.INITIAL;
2525
private ChannelEventListener eventListener;
26+
27+
protected Factory getFactory() {
28+
return factory;
29+
}
30+
2631
private final Factory factory;
2732
private final Object lock = new Object();
2833

@@ -190,7 +195,7 @@ public String toString() {
190195
}
191196

192197
@SuppressWarnings("unchecked")
193-
private String extractDataFrom(final String message) {
198+
protected String extractDataFrom(final String message) {
194199
final Map<Object, Object> jsonObject = GSON.fromJson(message, Map.class);
195200
return (String)jsonObject.get("data");
196201
}
@@ -199,7 +204,7 @@ protected String[] getDisallowedNameExpressions() {
199204
return new String[] { "^private-.*", "^presence-.*" };
200205
}
201206

202-
private void validateArguments(final String eventName, final SubscriptionEventListener listener) {
207+
protected void validateArguments(final String eventName, final SubscriptionEventListener listener) {
203208

204209
if (eventName == null) {
205210
throw new IllegalArgumentException("Cannot bind or unbind to channel " + name + " with a null event name");

src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.pusher.client.AuthorizationFailureException;
66
import com.pusher.client.Authorizer;
77
import com.pusher.client.channel.ChannelEventListener;
8+
import com.pusher.client.channel.ChannelState;
9+
import com.pusher.client.channel.EventMetadata;
810
import com.pusher.client.channel.PresenceChannel;
911
import com.pusher.client.channel.PresenceChannelEventListener;
1012
import com.pusher.client.channel.SubscriptionEventListener;
@@ -13,6 +15,8 @@
1315
import com.pusher.client.util.Factory;
1416

1517
import java.util.Collections;
18+
import java.util.HashMap;
19+
import java.util.HashSet;
1620
import java.util.LinkedHashMap;
1721
import java.util.LinkedHashSet;
1822
import java.util.List;
@@ -51,7 +55,47 @@ public User getMe() {
5155
@Override
5256
public void onMessage(final String event, final String message) {
5357

54-
super.onMessage(event, message);
58+
if (event.equals(SUBSCRIPTION_SUCCESS_EVENT)) {
59+
updateState(ChannelState.SUBSCRIBED);
60+
}
61+
else {
62+
final Set<PresenceChannelEventListener> listeners;
63+
synchronized (lock) {
64+
final Set<PresenceChannelEventListener> sharedListeners = eventNameToListenerMap.get(event);
65+
if (sharedListeners != null) {
66+
listeners = new HashSet<PresenceChannelEventListener>(sharedListeners);
67+
}
68+
else {
69+
listeners = null;
70+
}
71+
}
72+
73+
if (listeners != null) {
74+
for (final PresenceChannelEventListener listener : listeners) {
75+
final String data = extractDataFrom(message);
76+
final EventMetadata metadata = new EventMetadata();
77+
78+
// extracting user_id if client-event
79+
if (event.startsWith(CLIENT_EVENT_PREFIX)) {
80+
81+
// extracting user_id from message
82+
String userId = extractUserIdStringFrom(message);
83+
84+
metadata.setUserId(userId);
85+
86+
}
87+
getFactory().queueOnEventThread(new Runnable() {
88+
@Override
89+
public void run() {
90+
listener.onEvent(name, event, data);
91+
92+
listener.onEventWithMetadata(name, event, data, metadata);
93+
}
94+
});
95+
}
96+
}
97+
}
98+
5599

56100
if (event.equals(SUBSCRIPTION_SUCCESS_EVENT)) {
57101
handleSubscriptionSuccessfulMessage(message);
@@ -96,6 +140,9 @@ public String toSubscribeMessage() {
96140
}
97141
}
98142

143+
private final Object lock = new Object();
144+
private final Map<String, Set<PresenceChannelEventListener>> eventNameToListenerMap = new HashMap<String, Set<PresenceChannelEventListener>>();
145+
99146
@Override
100147
public void bind(final String eventName, final SubscriptionEventListener listener) {
101148

@@ -104,7 +151,31 @@ public void bind(final String eventName, final SubscriptionEventListener listene
104151
"Only instances of PresenceChannelEventListener can be bound to a presence channel");
105152
}
106153

107-
super.bind(eventName, listener);
154+
validateArguments(eventName, listener);
155+
156+
synchronized (lock) {
157+
Set<PresenceChannelEventListener> listeners = eventNameToListenerMap.get(eventName);
158+
if (listeners == null) {
159+
listeners = new HashSet<PresenceChannelEventListener>();
160+
eventNameToListenerMap.put(eventName, listeners);
161+
}
162+
listeners.add((PresenceChannelEventListener)listener);
163+
}
164+
}
165+
166+
@Override
167+
public void unbind(final String eventName, final SubscriptionEventListener listener) {
168+
validateArguments(eventName, listener);
169+
170+
synchronized (lock) {
171+
final Set<PresenceChannelEventListener> listeners = eventNameToListenerMap.get(eventName);
172+
if (listeners != null) {
173+
listeners.remove(listener);
174+
if (listeners.isEmpty()) {
175+
eventNameToListenerMap.remove(eventName);
176+
}
177+
}
178+
}
108179
}
109180

110181
@Override
@@ -177,7 +248,12 @@ private void handleMemberRemovedEvent(final String message) {
177248
@SuppressWarnings("rawtypes")
178249
private static String extractDataStringFrom(final String message) {
179250
final Map jsonObject = GSON.fromJson(message, Map.class);
180-
return (String) jsonObject.get("data");
251+
return (String) jsonObject.get("data");
252+
}
253+
254+
private static String extractUserIdStringFrom(final String message) {
255+
final Map jsonObject = GSON.fromJson(message, Map.class);
256+
return (String) jsonObject.get("user_id");
181257
}
182258

183259
@SuppressWarnings("rawtypes")

src/main/java/com/pusher/client/channel/impl/PrivateChannelImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
public class PrivateChannelImpl extends ChannelImpl implements PrivateChannel {
2020

2121
private static final Gson GSON = new Gson();
22-
private static final String CLIENT_EVENT_PREFIX = "client-";
22+
protected static final String CLIENT_EVENT_PREFIX = "client-";
2323
private final InternalConnection connection;
2424
private final Authorizer authorizer;
2525

src/main/java/com/pusher/client/example/PresenceChannelExampleApp.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.pusher.client.Pusher;
66
import com.pusher.client.PusherOptions;
7+
import com.pusher.client.channel.EventMetadata;
78
import com.pusher.client.channel.PresenceChannel;
89
import com.pusher.client.channel.PresenceChannelEventListener;
910
import com.pusher.client.channel.User;
@@ -99,6 +100,13 @@ public void onEvent(final String channelName, final String eventName, final Stri
99100
data));
100101
}
101102

103+
@Override
104+
public void onEventWithMetadata(final String channelName, final String eventName, final String data, final EventMetadata metadata) {
105+
106+
System.out.println(String.format("Received event [%s] on channel [%s] with data [%s] with metadata user_id: [%s]", eventName, channelName,
107+
data, metadata.getUserId()));
108+
}
109+
102110
@Override
103111
public void onSubscriptionSucceeded(final String channelName) {
104112

src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import com.pusher.client.channel.ChannelEventListener;
2222
import com.pusher.client.channel.ChannelState;
23+
import com.pusher.client.channel.EventMetadata;
2324
import com.pusher.client.channel.PresenceChannelEventListener;
2425
import com.pusher.client.channel.PrivateChannelEventListener;
2526
import com.pusher.client.channel.User;
@@ -69,6 +70,23 @@ public void testIsSubscribedMethod(){
6970
assertTrue(channel.isSubscribed());
7071
}
7172

73+
@Override
74+
@Test
75+
public void testDataIsExtractedFromMessageAndPassedToSingleListener() {
76+
final ArgumentCaptor<EventMetadata> argument = ArgumentCaptor.forClass(EventMetadata.class);
77+
78+
final String eventName = "client-my-event";
79+
PresenceChannelEventListener mockListener = getEventListener();
80+
81+
channel = newInstance(getChannelName());
82+
channel.bind(eventName, mockListener);
83+
channel.onMessage(eventName, "{\"event\":\"client-my-event\",\"data\":\"{\\\"fish\\\":\\\"chips\\\"}\",\"user_id\":\"Kuzya\"}");
84+
85+
verify(mockListener).onEventWithMetadata(eq(getChannelName()), eq(eventName), eq("{\"fish\":\"chips\"}"), argument.capture());
86+
87+
assertEquals("Kuzya", argument.getValue().getUserId());
88+
}
89+
7290
@Test
7391
@Override
7492
@SuppressWarnings({ "rawtypes", "unchecked" })
@@ -225,7 +243,7 @@ protected String getChannelName() {
225243
}
226244

227245
@Override
228-
protected ChannelEventListener getEventListener() {
246+
protected PresenceChannelEventListener getEventListener() {
229247
return mock(PresenceChannelEventListener.class);
230248
}
231249

0 commit comments

Comments
 (0)