Skip to content

Commit ee377e9

Browse files
committed
sync: cherry-pick changes from feature/3.0.x
1 parent fe57db4 commit ee377e9

14 files changed

Lines changed: 1913 additions & 62 deletions
Lines changed: 109 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
/*
2-
* Copyright (c) 2018, Loong Wan (https://github.com/loong10k).
2+
* Copyright (c) 2018-present, easy-4-java (https://github.com/easy-4-java).
33
*
4-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5-
* use this file except in compliance with the License. You may obtain a copy of
6-
* the License at
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13-
* License for the specific language governing permissions and limitations under
14-
* the License.
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
1515
*/
1616
package com.corundumstudio.socketio.spring.boot.handler;
1717

@@ -25,20 +25,69 @@
2525
import java.util.Collection;
2626
import java.util.UUID;
2727

28+
/**
29+
* Reusable base class for netty-socketio event handlers.
30+
*
31+
* <p>Subclasses only have to declare their own event methods (annotated with
32+
* {@code @OnEvent}, {@link OnConnect}, {@link OnDisconnect}, etc.); the base
33+
* class provides:</p>
34+
* <ul>
35+
* <li>Lifecycle callbacks that log the session id and send a {@code welcome}
36+
* event when a client connects.</li>
37+
* <li>Convenience accessors for retrieving connected clients, broadcast
38+
* operations and per-room broadcast operations from the underlying
39+
* {@link SocketIOServer}.</li>
40+
* <li>A standard {@link SocketIOServer} reference injectable via constructor
41+
* or setter so the same handler instance can be wired up by Spring or
42+
* instantiated manually.</li>
43+
* </ul>
44+
*
45+
* @author [@Loong Wan](https://github.com/loong10k)
46+
* @since 3.0.0
47+
* @see SocketIOServer
48+
* @see SocketIOClient
49+
*/
2850
@Slf4j
2951
public abstract class AbstractSocketEventHandler {
3052

53+
/**
54+
* The Socket.IO server that produced this handler. May be {@code null}
55+
* until {@link #setSocketIOServer(SocketIOServer)} or the convenience
56+
* constructor has been invoked.
57+
*/
3158
private SocketIOServer socketIOServer;
3259

60+
/**
61+
* Default constructor; useful when the Socket.IO server is supplied later
62+
* via {@link #setSocketIOServer(SocketIOServer)} or by the Spring
63+
* container during bean initialisation.
64+
*/
3365
public AbstractSocketEventHandler() {
3466
}
3567

68+
/**
69+
* Convenience constructor that wires the handler directly to a Socket.IO
70+
* server instance.
71+
*
72+
* @param socketIOServer the server to dispatch events to; must not be
73+
* {@code null} if any {@code getXxx} method is
74+
* going to be called from this handler.
75+
*/
3676
public AbstractSocketEventHandler(SocketIOServer socketIOServer) {
3777
this.socketIOServer = socketIOServer;
3878
}
3979

40-
// 添加connect事件,当客户端发起连接时调用,本文中将clientid与sessionid存入数据库
41-
// 方便后面发送消息时查找到对应的目标client,
80+
/**
81+
* Default {@code connect} callback invoked by netty-socketio.
82+
*
83+
* <p>Logs the handshake data and emits a {@code welcome} event back to the
84+
* newly connected client. Subclasses may override this method to add
85+
* custom logic but should call {@code super.onConnect(client)} first if
86+
* they want to preserve the welcome message.</p>
87+
*
88+
* @param client the client that just established a connection; never
89+
* {@code null}.
90+
*/
4291
@OnConnect
4392
public void onConnect(SocketIOClient client) {
4493
log.debug("Connect OK.");
@@ -49,35 +98,82 @@ public void onConnect(SocketIOClient client) {
4998
client.sendEvent("welcome", "ok");
5099
}
51100

52-
// 添加@OnDisconnect事件,客户端断开连接时调用,刷新客户端信息
101+
/**
102+
* Default {@code disconnect} callback invoked by netty-socketio.
103+
*
104+
* <p>Logs the leaving client. Subclasses may override this method to add
105+
* custom cleanup logic.</p>
106+
*
107+
* @param client the client that just disconnected; never {@code null}.
108+
*/
53109
@OnDisconnect
54110
public void onDisconnect(SocketIOClient client) {
55111
log.debug("Disconnect OK.");
56112
log.debug("Session ID : %s", client.getSessionId());
57113
}
58114

115+
/**
116+
* Returns every client currently connected to the given namespace.
117+
*
118+
* @param namespace the namespace name (use the empty string for the
119+
* default namespace); must not be {@code null}.
120+
* @return the live collection of clients; never {@code null}.
121+
*/
59122
public Collection<SocketIOClient> getClients(String namespace) {
60123
return getSocketIOServer().getNamespace(namespace).getAllClients();
61124
}
62125

126+
/**
127+
* Looks up a single client in the given namespace by its session id.
128+
*
129+
* @param namespace the namespace name; must not be {@code null}.
130+
* @param sessionId the session id; must not be {@code null}.
131+
* @return the matching client, or {@code null} if no client with that
132+
* session id is currently connected.
133+
*/
63134
public SocketIOClient getClient(String namespace, UUID sessionId) {
64135
return getSocketIOServer().getNamespace(namespace).getClient(sessionId);
65136
}
66137

138+
/**
139+
* Returns the {@link BroadcastOperations} for an entire namespace.
140+
*
141+
* @param namespace the namespace name; must not be {@code null}.
142+
* @return the broadcast handle; never {@code null}.
143+
*/
67144
public BroadcastOperations getBroadcastOperations(String namespace) {
68145
return getSocketIOServer().getNamespace(namespace).getBroadcastOperations();
69146
}
70147

148+
/**
149+
* Returns the {@link BroadcastOperations} scoped to a single room inside a
150+
* namespace.
151+
*
152+
* @param namespace the namespace name; must not be {@code null}.
153+
* @param room the room name; must not be {@code null}.
154+
* @return the room-scoped broadcast handle; never {@code null}.
155+
*/
71156
public BroadcastOperations getBroadcastOperations(String namespace, String room) {
72157
return getSocketIOServer().getNamespace(namespace).getRoomOperations(room);
73158
}
74159

160+
/**
161+
* Returns the Socket.IO server bound to this handler.
162+
*
163+
* @return the bound server, possibly {@code null} if none has been set.
164+
*/
75165
public SocketIOServer getSocketIOServer() {
76166
return socketIOServer;
77167
}
78168

169+
/**
170+
* Replaces the Socket.IO server bound to this handler.
171+
*
172+
* @param socketIOServer the new server; may be {@code null} to clear the
173+
* reference (not recommended for production code).
174+
*/
79175
public void setSocketIOServer(SocketIOServer socketIOServer) {
80176
this.socketIOServer = socketIOServer;
81177
}
82178

83-
}
179+
}
Lines changed: 107 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/*
2+
* Copyright (c) 2018-present, easy-4-java (https://github.com/easy-4-java).
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package com.corundumstudio.socketio.store;
217

318
import org.springframework.util.StringUtils;
@@ -6,67 +21,130 @@
621
import java.util.StringJoiner;
722
import java.util.function.Function;
823

24+
/**
25+
* Enumerates the canonical Socket.IO cache keys and offers utility helpers to
26+
* assemble them into namespaced strings.
27+
*
28+
* <p>Each enum constant bundles a human-readable description together with a
29+
* function that produces the final cache-key string given any required
30+
* arguments (e.g. a session identifier or an IP address). The static helpers
31+
* {@link #getKeyStr(Object...)} and {@link #getThreadKeyStr(String, Object...)}
32+
* perform the actual string assembly, using {@link #REDIS_PREFIX} as the global
33+
* prefix and {@link #DELIMITER} ({@code ":"}) as the separator.</p>
34+
*
35+
* <p>Null or blank segments are skipped silently during assembly so call sites
36+
* can pass optional identifiers without conditionals.</p>
37+
*
38+
* @author [@Loong Wan](https://github.com/loong10k)
39+
* @since 3.0.0
40+
* @see CacheKeyConstant
41+
*/
942
public enum CacheKey {
1043

1144
/**
12-
* Socket会话列表
45+
* Cache key for the list of all known Socket.IO sessions.
1346
*/
14-
SOCKET_IO_SESSIONS("Socket会话列表", (p1) -> {
47+
SOCKET_IO_SESSIONS("Socket session list", (p1) -> {
1548
return CacheKey.getKeyStr(CacheKeyConstant.SOCKET_IO_SESSIONS_KEY);
1649
}),
1750
/**
18-
* Socket会话信息
51+
* Cache key for an individual Socket.IO session; combined with the session
52+
* identifier passed to {@link #getKey(Object)}.
1953
*/
20-
SOCKET_IO_SESSION("Socket会话信息", (sessionId) -> {
54+
SOCKET_IO_SESSION("Socket session info", (sessionId) -> {
2155
return CacheKey.getKeyStr(CacheKeyConstant.SOCKET_IO_SESSION_KEY, sessionId);
2256
}),
2357

2458
/**
25-
* IP地区编码缓存
59+
* Cache key for the region/country code resolved from an IP address.
2660
*/
27-
SOCKET_IO_IP_REGION("用户坐标对应的地区编码缓存", (ip)->{
61+
SOCKET_IO_IP_REGION("IP-to-region code cache", (ip)->{
2862
return getKeyStr(CacheKeyConstant.SOCKET_IO_IP_REGION_KEY, ip);
2963
}),
3064
/**
31-
* IP坐标缓存
65+
* Cache key for the geographic coordinate resolved from an IP address.
3266
*/
33-
SOCKET_IO_IP_LOCATION("用户坐标对应的地理位置缓存", (ip)->{
67+
SOCKET_IO_IP_LOCATION("IP-to-location coordinate cache", (ip)->{
3468
return getKeyStr(CacheKeyConstant.SOCKET_IO_IP_LOCATION_KEY, ip);
3569
})
3670
;
3771

72+
/**
73+
* Human-readable description of this cache key, intended for logging and
74+
* debugging rather than runtime dispatch.
75+
*/
3876
private String desc;
77+
/**
78+
* Function that builds the final cache-key string when given the
79+
* context-specific identifier (or {@code null} for keys without one).
80+
*/
3981
private Function<Object, String> function;
4082

83+
/**
84+
* Creates a new enum constant.
85+
*
86+
* @param desc a short human-readable description of the key.
87+
* @param function the function that produces the final cache-key string;
88+
* must accept {@code null} for keys that take no argument.
89+
*/
4190
CacheKey(String desc, Function<Object, String> function) {
4291
this.desc = desc;
4392
this.function = function;
4493
}
4594

46-
public String getDesc() {
95+
/**
96+
* Returns the description associated with this key.
97+
*
98+
* @return the short human-readable description; never {@code null}.
99+
*/
100+
public String getDesc() {
47101
return desc;
48102
}
49103

50104
/**
51-
* 1、获取全名称key
52-
* @return 无参数组合后的redis缓存key
105+
* Returns the fully-qualified cache key (no extra arguments required).
106+
*
107+
* @return the assembled cache key with only {@link #REDIS_PREFIX} and the
108+
* constant segment(s) included.
53109
*/
54110
public String getKey() {
55111
return this.function.apply(null);
56112
}
57113

58114
/**
59-
* 1、获取全名称key
60-
* @param key 缓存key的部分值
61-
* @return key参数组合后的redis缓存key
115+
* Returns the fully-qualified cache key, combining the constant prefix with
116+
* the supplied identifier.
117+
*
118+
* @param key the context-specific identifier (e.g. session id, IP address).
119+
* May be {@code null}, in which case it is skipped during
120+
* assembly rather than rendered as the literal string
121+
* {@code "null"}.
122+
* @return the assembled cache key.
62123
*/
63124
public String getKey(Object key) {
64125
return this.function.apply(key);
65126
}
66127

128+
/**
129+
* Global prefix applied to every Redis cache key produced by this class.
130+
*/
67131
public static String REDIS_PREFIX = "rds";
132+
/**
133+
* Segment separator used by the cache-key assembly helpers.
134+
*/
68135
public final static String DELIMITER = ":";
69136

137+
/**
138+
* Assembles a cache key by concatenating {@link #REDIS_PREFIX} with each
139+
* supplied argument using {@link #DELIMITER}.
140+
*
141+
* <p>Null values and values whose {@code toString()} is blank are silently
142+
* skipped, so callers may pass optional identifiers without branching.</p>
143+
*
144+
* @param args the segments to concatenate after the prefix; may be empty
145+
* but should not be {@code null}.
146+
* @return the joined cache key string, never {@code null}.
147+
*/
70148
public static String getKeyStr(Object... args) {
71149
StringJoiner tempKey = new StringJoiner(DELIMITER);
72150
tempKey.add(REDIS_PREFIX);
@@ -79,6 +157,14 @@ public static String getKeyStr(Object... args) {
79157
return tempKey.toString();
80158
}
81159

160+
/**
161+
* Assembles a thread-scoped cache key that includes the current thread id
162+
* between the supplied {@code prefix} and the extra arguments.
163+
*
164+
* @param prefix the leading segment (added before the thread id).
165+
* @param args the additional segments; null or blank entries are skipped.
166+
* @return the joined, thread-scoped cache key string, never {@code null}.
167+
*/
82168
public static String getThreadKeyStr(String prefix, Object... args) {
83169

84170
StringJoiner tempKey = new StringJoiner(DELIMITER);
@@ -93,9 +179,15 @@ public static String getThreadKeyStr(String prefix, Object... args) {
93179
return tempKey.toString();
94180
}
95181

182+
/**
183+
* Local sanity check used during development to print a sample key.
184+
*
185+
* @param args ignored; present so this class can be executed directly via
186+
* {@code java CacheKey}.
187+
*/
96188
public static void main(String[] args) {
97189
System.out.println(getKeyStr(233,""));
98190
}
99191

100192

101-
}
193+
}

0 commit comments

Comments
 (0)