diff --git a/base-third-project/base-third-step6/pom.xml b/base-third-project/base-third-step6/pom.xml index 9f1a67cc3..de85857cc 100644 --- a/base-third-project/base-third-step6/pom.xml +++ b/base-third-project/base-third-step6/pom.xml @@ -16,7 +16,6 @@ ../../fine-druid - ../../fine-socketio ${classes-path}/base-third-step6/classes diff --git a/build.third_step6-jdk11.gradle b/build.third_step6-jdk11.gradle index 2153ca4f2..66ec5dd54 100644 --- a/build.third_step6-jdk11.gradle +++ b/build.third_step6-jdk11.gradle @@ -24,8 +24,7 @@ sourceSets{ main{ java{ srcDirs=[ - "${srcDir}/fine-druid/src/main/java", - "${srcDir}/fine-socketio/src/main/java" + "${srcDir}/fine-druid/src/main/java" ] } } @@ -35,8 +34,6 @@ sourceSets{ def resourceDirs = [ "${srcDir}/fine-druid/src/main/java", "${srcDir}/fine-druid/src/main/resources", - "${srcDir}/fine-socketio/src/main/java", - "${srcDir}/fine-socketio/src/main/resources" ] sourceSets.main.java.outputDir = file('build/classes/6') @@ -71,7 +68,6 @@ dependencies{ compileOnly "com.fr.essential:fine-essential:${essentialVersion}" compile fileTree(dir:"${srcDir}/fine-druid/lib",include:'ojdbc7-12.1.0.jar') compile fileTree(dir:"${srcDir}/fine-druid/lib",include:'**/*.jar') - compile fileTree(dir:"${srcDir}/fine-socketio/lib",include:'**/*.jar') compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar') compile fileTree(dir:System.getenv("JAVA_HOME"),include:"lib/tools.jar") compile group: "com.fr.third.server", name: "servlet-api", version: "3.0" diff --git a/build.third_step6.gradle b/build.third_step6.gradle index e7bb4bc44..597629556 100644 --- a/build.third_step6.gradle +++ b/build.third_step6.gradle @@ -24,8 +24,7 @@ sourceSets{ main{ java{ srcDirs=[ - "${srcDir}/fine-druid/src/main/java", - "${srcDir}/fine-socketio/src/main/java" + "${srcDir}/fine-druid/src/main/java" ] } } @@ -60,7 +59,6 @@ dependencies{ compileOnly "com.fr.essential:fine-essential:${essentialVersion}" compile fileTree(dir:"${srcDir}/fine-druid/lib",include:'ojdbc7-12.1.0.jar') compile fileTree(dir:"${srcDir}/fine-druid/lib",include:'**/*.jar') - compile fileTree(dir:"${srcDir}/fine-socketio/lib",include:'**/*.jar') compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar') compile fileTree(dir:System.getenv("JAVA_HOME"),include:"lib/tools.jar") compile group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1" @@ -84,8 +82,6 @@ task copyFiles(type:Copy,dependsOn:'compileJava'){ println "------------------------------------------------copyfiles" with dataContent.call("${srcDir}/fine-druid/src/main/java") with dataContent.call("${srcDir}/fine-druid/src/main/resources") - with dataContent.call("${srcDir}/fine-socketio/src/main/java") - with dataContent.call("${srcDir}/fine-socketio/src/main/resources") into "${classesDir}" } } diff --git a/fine-socketio/.gitignore b/fine-socketio/.gitignore deleted file mode 100644 index 5d453cd8b..000000000 --- a/fine-socketio/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.iml -.idea/ -.DS_Store -.project -.classpath -*.gradle \ No newline at end of file diff --git a/fine-socketio/lib/netty-all-4.1.22.Final.jar b/fine-socketio/lib/netty-all-4.1.22.Final.jar deleted file mode 100644 index 61a2dfa0b..000000000 Binary files a/fine-socketio/lib/netty-all-4.1.22.Final.jar and /dev/null differ diff --git a/fine-socketio/pom.xml b/fine-socketio/pom.xml deleted file mode 100644 index cbc6deae1..000000000 --- a/fine-socketio/pom.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - 4.0.0 - - - com.fr.third - step6 - ${revision} - ../base-third-project/base-third-step6 - - - fine-socketio - ${revision} - - - - com.fr.essential - fine-jackson - ${essentialVersion} - - - com.fr.essential - fine-slf4j-api - ${essentialVersion} - - - com.fr.third - fine-redisson - ${revision} - - - com.fr.third - fine-spring - ${revision} - - - com.fr.essential - fine-common - ${essentialVersion} - - 以下是lib的本地jar包依赖<--> - - com.fr.third - netty - local - system - ${basedir}/lib/netty-all-4.1.22.Final.jar - - - \ No newline at end of file diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/AckCallback.java b/fine-socketio/src/main/java/com/fr/third/socketio/AckCallback.java deleted file mode 100644 index 800334c80..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/AckCallback.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - - -/** - * Base ack callback class. - * - * Notifies about acknowledgement received from client - * via {@link #onSuccess} callback method. - * - * By default it may wait acknowledgement from client - * while {@link SocketIOClient} is alive. Timeout can be - * defined {@link #timeout} as constructor argument. - * - * This object is NOT actual anymore if {@link #onSuccess} or - * {@link #onTimeout} was executed. - * - * @param - any serializable type - * - * @see com.fr.third.socketio.VoidAckCallback - * @see com.fr.third.socketio.MultiTypeAckCallback - * - */ -public abstract class AckCallback { - - protected final Class resultClass; - protected final int timeout; - - /** - * Create AckCallback - * - * @param resultClass - result class - */ - public AckCallback(Class resultClass) { - this(resultClass, -1); - } - - /** - * Creates AckCallback with timeout - * - * @param resultClass - result class - * @param timeout - callback timeout in seconds - */ - public AckCallback(Class resultClass, int timeout) { - this.resultClass = resultClass; - this.timeout = timeout; - } - - public int getTimeout() { - return timeout; - } - - /** - * Executes only once when acknowledgement received from client. - * - * @param result - object sended by client - */ - public abstract void onSuccess(T result); - - /** - * Invoked only once then timeout defined - * - */ - public void onTimeout() { - - } - - /** - * Returns class of argument in {@link #onSuccess} method - * - * @return - result class - */ - public Class getResultClass() { - return resultClass; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/AckMode.java b/fine-socketio/src/main/java/com/fr/third/socketio/AckMode.java deleted file mode 100644 index 77eb27be4..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/AckMode.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -public enum AckMode { - - /** - * Send ack-response automatically on each ack-request - * skip exceptions during packet handling - */ - AUTO, - - /** - * Send ack-response automatically on each ack-request - * only after success packet handling - */ - AUTO_SUCCESS_ONLY, - - /** - * Turn off auto ack-response sending. - * Use AckRequest.sendAckData to send ack-response each time. - * - */ - MANUAL - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/AckRequest.java b/fine-socketio/src/main/java/com/fr/third/socketio/AckRequest.java deleted file mode 100644 index c341eb4f3..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/AckRequest.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import com.fr.third.socketio.listener.DataListener; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketType; - -/** - * Ack request received from Socket.IO client. - * You can always check is it true through - * {@link #isAckRequested()} method. - * - * You can call {@link #sendAckData} methods only during - * {@link DataListener#onData} invocation. If {@link #sendAckData} - * not called it will be invoked with empty arguments right after - * {@link DataListener#onData} method execution by server. - * - * This object is NOT actual anymore if {@link #sendAckData} was - * executed or {@link DataListener#onData} invocation finished. - * - */ -public class AckRequest { - - private final Packet originalPacket; - private final SocketIOClient client; - private final AtomicBoolean sended = new AtomicBoolean(); - - public AckRequest(Packet originalPacket, SocketIOClient client) { - this.originalPacket = originalPacket; - this.client = client; - } - - /** - * Check whether ack request was made - * - * @return true if ack requested by client - */ - public boolean isAckRequested() { - return originalPacket.isAckRequested(); - } - - /** - * Send ack data to client. - * Can be invoked only once during {@link DataListener#onData} - * method invocation. - * - * @param objs - ack data objects - */ - public void sendAckData(Object ... objs) { - List args = Arrays.asList(objs); - sendAckData(args); - } - - /** - * Send ack data to client. - * Can be invoked only once during {@link DataListener#onData} - * method invocation. - * - * @param objs - ack data object list - */ - public void sendAckData(List objs) { - if (!isAckRequested() || !sended.compareAndSet(false, true)) { - return; - } - Packet ackPacket = new Packet(PacketType.MESSAGE); - ackPacket.setSubType(PacketType.ACK); - ackPacket.setAckId(originalPacket.getAckId()); - ackPacket.setData(objs); - client.send(ackPacket); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/AuthorizationListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/AuthorizationListener.java deleted file mode 100644 index 21be7f735..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/AuthorizationListener.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -public interface AuthorizationListener { - - /** - * Checks is client with handshake data is authorized - * - * @param data - handshake data - * @return - true if client is authorized of false otherwise - */ - boolean isAuthorized(HandshakeData data); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/BroadcastAckCallback.java b/fine-socketio/src/main/java/com/fr/third/socketio/BroadcastAckCallback.java deleted file mode 100644 index 233b82164..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/BroadcastAckCallback.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -public class BroadcastAckCallback { - - final AtomicBoolean loopFinished = new AtomicBoolean(); - final AtomicInteger counter = new AtomicInteger(); - final AtomicBoolean successExecuted = new AtomicBoolean(); - final Class resultClass; - final int timeout; - - public BroadcastAckCallback(Class resultClass, int timeout) { - this.resultClass = resultClass; - this.timeout = timeout; - } - - public BroadcastAckCallback(Class resultClass) { - this(resultClass, -1); - } - - final AckCallback createClientCallback(final SocketIOClient client) { - counter.getAndIncrement(); - return new AckCallback(resultClass, timeout) { - @Override - public void onSuccess(T result) { - counter.getAndDecrement(); - onClientSuccess(client, result); - executeSuccess(); - } - - @Override - public void onTimeout() { - onClientTimeout(client); - } - - }; - } - - protected void onClientTimeout(SocketIOClient client) { - - } - - protected void onClientSuccess(SocketIOClient client, T result) { - - } - - protected void onAllSuccess() { - - } - - private void executeSuccess() { - if (loopFinished.get() - && counter.get() == 0 - && successExecuted.compareAndSet(false, true)) { - onAllSuccess(); - } - } - - void loopFinished() { - loopFinished.set(true); - executeSuccess(); - } - -} - diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/BroadcastOperations.java b/fine-socketio/src/main/java/com/fr/third/socketio/BroadcastOperations.java deleted file mode 100644 index b308be864..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/BroadcastOperations.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import com.fr.third.socketio.protocol.Packet; - -import java.util.Collection; - -/** - * broadcast interface - * - */ -public interface BroadcastOperations extends ClientOperations { - - Collection getClients(); - - void send(Packet packet, BroadcastAckCallback ackCallback); - - void sendEvent(String name, SocketIOClient excludedClient, Object... data); - - void sendEvent(String name, Object data, BroadcastAckCallback ackCallback); - - void sendEvent(String name, Object data, SocketIOClient excludedClient, BroadcastAckCallback ackCallback); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/ClientOperations.java b/fine-socketio/src/main/java/com/fr/third/socketio/ClientOperations.java deleted file mode 100644 index 1f2924800..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/ClientOperations.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import com.fr.third.socketio.protocol.Packet; - -/** - * Available client operations - * - */ -public interface ClientOperations { - - /** - * Send custom packet. - * But {@link ClientOperations#sendEvent} method - * usage is enough for most cases. - * - * @param packet - packet to send - */ - void send(Packet packet); - - /** - * Disconnect client - * - */ - void disconnect(); - - /** - * Send event - * - * @param name - event name - * @param data - event data - */ - void sendEvent(String name, Object ... data); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/Configuration.java b/fine-socketio/src/main/java/com/fr/third/socketio/Configuration.java deleted file mode 100644 index 8948b005e..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/Configuration.java +++ /dev/null @@ -1,656 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import com.fr.third.socketio.handler.SuccessAuthorizationListener; -import com.fr.third.socketio.listener.DefaultExceptionListener; -import com.fr.third.socketio.listener.ExceptionListener; -import com.fr.third.socketio.listener.interceptor.EventInterceptor; -import com.fr.third.socketio.listener.interceptor.Interceptor; -import com.fr.third.socketio.protocol.JsonSupport; -import com.fr.third.socketio.store.MemoryStoreFactory; -import com.fr.third.socketio.store.RedissonStoreFactory; -import com.fr.third.socketio.store.StoreFactory; - -import javax.net.ssl.KeyManagerFactory; - -public class Configuration { - - private ExceptionListener exceptionListener = new DefaultExceptionListener(); - - private String context = "/socket.io"; - - private List transports = Arrays.asList(Transport.WEBSOCKET, Transport.POLLING); - - private int bossThreads = 0; // 0 = current_processors_amount * 2 - private int workerThreads = 0; // 0 = current_processors_amount * 2 - private boolean useLinuxNativeEpoll; - - private boolean allowCustomRequests = false; - - private int upgradeTimeout = 10000; - private int pingTimeout = 60000; - private int pingInterval = 25000; - private int firstDataTimeout = 5000; - - private int maxHttpContentLength = 64 * 1024; - private int maxFramePayloadLength = 64 * 1024; - - private String packagePrefix; - private String hostname; - private int port = -1; - - private String sslProtocol = "TLSv1"; - - private String keyStoreFormat = "JKS"; - private InputStream keyStore; - private String keyStorePassword; - - private String trustStoreFormat = "JKS"; - private InputStream trustStore; - private String trustStorePassword; - - private String keyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); - - private boolean preferDirectBuffer = true; - - private SocketConfig socketConfig = new SocketConfig(); - - private StoreFactory storeFactory = new MemoryStoreFactory(); - - private JsonSupport jsonSupport; - - private AuthorizationListener authorizationListener = new SuccessAuthorizationListener(); - - private AckMode ackMode = AckMode.AUTO_SUCCESS_ONLY; - - private boolean addVersionHeader = true; - - private String origin; - - private boolean httpCompression = true; - - private boolean websocketCompression = true; - - private boolean randomSession = false; - - private String accessControlAllowHeaders = null; - - private List connectInterceptors = Collections.emptyList(); - private List disconnectInterceptors = Collections.emptyList(); - private List eventInterceptors = Collections.emptyList(); - - private String[] nettyProtocols = new String[]{}; - - private String[] nettyCiphers = new String[]{}; - - public Configuration() { - } - - /** - * Defend from further modifications by cloning - * - * @param conf - Configuration object to clone - */ - Configuration(Configuration conf) { - setBossThreads(conf.getBossThreads()); - setWorkerThreads(conf.getWorkerThreads()); - setUseLinuxNativeEpoll(conf.isUseLinuxNativeEpoll()); - - setPingInterval(conf.getPingInterval()); - setPingTimeout(conf.getPingTimeout()); - - setHostname(conf.getHostname()); - setPort(conf.getPort()); - - if (conf.getJsonSupport() == null) { - try { - getClass().getClassLoader().loadClass("com.fr.third.fasterxml.jackson.databind.ObjectMapper"); - try { - Class jjs = getClass().getClassLoader().loadClass("com.fr.third.socketio.protocol.JacksonJsonSupport"); - JsonSupport js = (JsonSupport) jjs.getConstructor().newInstance(); - conf.setJsonSupport(js); - } catch (Exception e) { - throw new IllegalArgumentException(e); - } - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Can't find jackson lib in classpath", e); - } - } - - setJsonSupport(new JsonSupportWrapper(conf.getJsonSupport())); - setContext(conf.getContext()); - setAllowCustomRequests(conf.isAllowCustomRequests()); - - setKeyStorePassword(conf.getKeyStorePassword()); - setKeyStore(conf.getKeyStore()); - setKeyStoreFormat(conf.getKeyStoreFormat()); - setTrustStore(conf.getTrustStore()); - setTrustStoreFormat(conf.getTrustStoreFormat()); - setTrustStorePassword(conf.getTrustStorePassword()); - setKeyManagerFactoryAlgorithm(conf.getKeyManagerFactoryAlgorithm()); - - setTransports(conf.getTransports().toArray(new Transport[conf.getTransports().size()])); - setMaxHttpContentLength(conf.getMaxHttpContentLength()); - setPackagePrefix(conf.getPackagePrefix()); - - setPreferDirectBuffer(conf.isPreferDirectBuffer()); - setStoreFactory(conf.getStoreFactory()); - setAuthorizationListener(conf.getAuthorizationListener()); - setExceptionListener(conf.getExceptionListener()); - setSocketConfig(conf.getSocketConfig()); - setAckMode(conf.getAckMode()); - setMaxFramePayloadLength(conf.getMaxFramePayloadLength()); - setUpgradeTimeout(conf.getUpgradeTimeout()); - - setAddVersionHeader(conf.isAddVersionHeader()); - setOrigin(conf.getOrigin()); - setSSLProtocol(conf.getSSLProtocol()); - - setHttpCompression(conf.isHttpCompression()); - setWebsocketCompression(conf.isWebsocketCompression()); - setRandomSession(conf.randomSession); - - setAccessControlAllowHeaders(conf.getAccessControlAllowHeaders()); - setConnectInterceptors(conf.getConnectInterceptors().toArray(new Interceptor[0])); - setDisconnectInterceptors(conf.getDisconnectInterceptors().toArray(new Interceptor[0])); - setEventInterceptors(conf.getEventInterceptors().toArray(new EventInterceptor[0])); - - setNettyProtocols(conf.getNettyProtocols()); - setNettyCiphers(conf.getNettyCiphers()); - } - - public JsonSupport getJsonSupport() { - return jsonSupport; - } - - /** - * Allows to setup custom implementation of - * JSON serialization/deserialization - * - * @param jsonSupport - json mapper - * - * @see JsonSupport - */ - public void setJsonSupport(JsonSupport jsonSupport) { - this.jsonSupport = jsonSupport; - } - - public String getHostname() { - return hostname; - } - - /** - * Optional parameter. If not set then bind address - * will be 0.0.0.0 or ::0 - * - * @param hostname - name of host - */ - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public int getPort() { - return port; - } - public void setPort(int port) { - this.port = port; - } - - public int getBossThreads() { - return bossThreads; - } - public void setBossThreads(int bossThreads) { - this.bossThreads = bossThreads; - } - - public int getWorkerThreads() { - return workerThreads; - } - public void setWorkerThreads(int workerThreads) { - this.workerThreads = workerThreads; - } - - /** - * Ping interval - * - * @param heartbeatIntervalSecs - time in milliseconds - */ - public void setPingInterval(int heartbeatIntervalSecs) { - this.pingInterval = heartbeatIntervalSecs; - } - public int getPingInterval() { - return pingInterval; - } - - /** - * Ping timeout - * Use 0 to disable it - * - * @param heartbeatTimeoutSecs - time in milliseconds - */ - public void setPingTimeout(int heartbeatTimeoutSecs) { - this.pingTimeout = heartbeatTimeoutSecs; - } - public int getPingTimeout() { - return pingTimeout; - } - public boolean isHeartbeatsEnabled() { - return pingTimeout > 0; - } - - public String getContext() { - return context; - } - public void setContext(String context) { - this.context = context; - } - - public boolean isAllowCustomRequests() { - return allowCustomRequests; - } - - /** - * Allow to service custom requests differs from socket.io protocol. - * In this case it's necessary to add own handler which handle them - * to avoid hang connections. - * Default is {@code false} - * - * @param allowCustomRequests - {@code true} to allow - */ - public void setAllowCustomRequests(boolean allowCustomRequests) { - this.allowCustomRequests = allowCustomRequests; - } - - /** - * SSL key store password - * - * @param keyStorePassword - password of key store - */ - public void setKeyStorePassword(String keyStorePassword) { - this.keyStorePassword = keyStorePassword; - } - public String getKeyStorePassword() { - return keyStorePassword; - } - - /** - * SSL key store stream, maybe appointed to any source - * - * @param keyStore - key store input stream - */ - public void setKeyStore(InputStream keyStore) { - this.keyStore = keyStore; - } - public InputStream getKeyStore() { - return keyStore; - } - - /** - * Key store format - * - * @param keyStoreFormat - key store format - */ - public void setKeyStoreFormat(String keyStoreFormat) { - this.keyStoreFormat = keyStoreFormat; - } - public String getKeyStoreFormat() { - return keyStoreFormat; - } - - /** - * Set maximum http content length limit - * - * @param value - * the maximum length of the aggregated http content. - */ - public void setMaxHttpContentLength(int value) { - this.maxHttpContentLength = value; - } - public int getMaxHttpContentLength() { - return maxHttpContentLength; - } - - /** - * Transports supported by server - * - * @param transports - list of transports - */ - public void setTransports(Transport ... transports) { - if (transports.length == 0) { - throw new IllegalArgumentException("Transports list can't be empty"); - } - this.transports = Arrays.asList(transports); - } - public List getTransports() { - return transports; - } - - /** - * Package prefix for sending json-object from client - * without full class name. - * - * With defined package prefix socket.io client - * just need to define '@class: 'SomeType'' in json object - * instead of '@class: 'com.full.package.name.SomeType'' - * - * @param packagePrefix - prefix string - * - */ - public void setPackagePrefix(String packagePrefix) { - this.packagePrefix = packagePrefix; - } - public String getPackagePrefix() { - return packagePrefix; - } - - /** - * Buffer allocation method used during packet encoding. - * Default is {@code true} - * - * @param preferDirectBuffer {@code true} if a direct buffer should be tried to be used as target for - * the encoded messages. If {@code false} is used it will allocate a heap - * buffer, which is backed by an byte array. - */ - public void setPreferDirectBuffer(boolean preferDirectBuffer) { - this.preferDirectBuffer = preferDirectBuffer; - } - public boolean isPreferDirectBuffer() { - return preferDirectBuffer; - } - - /** - * Data store - used to store session data and implements distributed pubsub. - * Default is {@code MemoryStoreFactory} - * - * @param clientStoreFactory - implements StoreFactory - * - * @see MemoryStoreFactory - * @see RedissonStoreFactory - */ - public void setStoreFactory(StoreFactory clientStoreFactory) { - this.storeFactory = clientStoreFactory; - } - public StoreFactory getStoreFactory() { - return storeFactory; - } - - /** - * Authorization listener invoked on every handshake. - * Accepts or denies a client by {@code AuthorizationListener.isAuthorized} method. - * Accepts all clients by default. - * - * @param authorizationListener - authorization listener itself - * - * @see AuthorizationListener - */ - public void setAuthorizationListener(AuthorizationListener authorizationListener) { - this.authorizationListener = authorizationListener; - } - public AuthorizationListener getAuthorizationListener() { - return authorizationListener; - } - - /** - * Exception listener invoked on any exception in - * SocketIO listener - * - * @param exceptionListener - listener - * - * @see ExceptionListener - */ - public void setExceptionListener(ExceptionListener exceptionListener) { - this.exceptionListener = exceptionListener; - } - public ExceptionListener getExceptionListener() { - return exceptionListener; - } - - public SocketConfig getSocketConfig() { - return socketConfig; - } - /** - * TCP socket configuration - * - * @param socketConfig - config - */ - public void setSocketConfig(SocketConfig socketConfig) { - this.socketConfig = socketConfig; - } - - /** - * Auto ack-response mode - * Default is {@code AckMode.AUTO_SUCCESS_ONLY} - * - * @see AckMode - * - * @param ackMode - ack mode - */ - public void setAckMode(AckMode ackMode) { - this.ackMode = ackMode; - } - public AckMode getAckMode() { - return ackMode; - } - - - public String getTrustStoreFormat() { - return trustStoreFormat; - } - public void setTrustStoreFormat(String trustStoreFormat) { - this.trustStoreFormat = trustStoreFormat; - } - - public InputStream getTrustStore() { - return trustStore; - } - public void setTrustStore(InputStream trustStore) { - this.trustStore = trustStore; - } - - public String getTrustStorePassword() { - return trustStorePassword; - } - public void setTrustStorePassword(String trustStorePassword) { - this.trustStorePassword = trustStorePassword; - } - - public String getKeyManagerFactoryAlgorithm() { - return keyManagerFactoryAlgorithm; - } - public void setKeyManagerFactoryAlgorithm(String keyManagerFactoryAlgorithm) { - this.keyManagerFactoryAlgorithm = keyManagerFactoryAlgorithm; - } - - - /** - * Set maximum websocket frame content length limit - * - * @param maxFramePayloadLength - length - */ - public void setMaxFramePayloadLength(int maxFramePayloadLength) { - this.maxFramePayloadLength = maxFramePayloadLength; - } - public int getMaxFramePayloadLength() { - return maxFramePayloadLength; - } - - /** - * Transport upgrade timeout in milliseconds - * - * @param upgradeTimeout - upgrade timeout - */ - public void setUpgradeTimeout(int upgradeTimeout) { - this.upgradeTimeout = upgradeTimeout; - } - public int getUpgradeTimeout() { - return upgradeTimeout; - } - - /** - * Adds Server header with lib version to http response. - *

- * Default is true - * - * @param addVersionHeader - true to add header - */ - public void setAddVersionHeader(boolean addVersionHeader) { - this.addVersionHeader = addVersionHeader; - } - public boolean isAddVersionHeader() { - return addVersionHeader; - } - - /** - * Set Access-Control-Allow-Origin header value for http each - * response. - * Default is null - * - * If value is null then request ORIGIN header value used. - * - * @param origin - origin - */ - public void setOrigin(String origin) { - this.origin = origin; - } - public String getOrigin() { - return origin; - } - - public boolean isUseLinuxNativeEpoll() { - return useLinuxNativeEpoll; - } - public void setUseLinuxNativeEpoll(boolean useLinuxNativeEpoll) { - this.useLinuxNativeEpoll = useLinuxNativeEpoll; - } - - /** - * Set the name of the requested SSL protocol - * - * @param sslProtocol - name of protocol - */ - public void setSSLProtocol(String sslProtocol) { - this.sslProtocol = sslProtocol; - } - public String getSSLProtocol() { - return sslProtocol; - } - - /** - * Timeout between channel opening and first data transfer - * Helps to avoid 'silent channel' attack and prevents - * 'Too many open files' problem in this case - * - * @param firstDataTimeout - timeout value - */ - public void setFirstDataTimeout(int firstDataTimeout) { - this.firstDataTimeout = firstDataTimeout; - } - public int getFirstDataTimeout() { - return firstDataTimeout; - } - - /** - * Activate http protocol compression. Uses {@code gzip} or - * {@code deflate} encoding choice depends on the {@code "Accept-Encoding"} header value. - *

- * Default is true - * - * @param httpCompression - true to use http compression - */ - public void setHttpCompression(boolean httpCompression) { - this.httpCompression = httpCompression; - } - public boolean isHttpCompression() { - return httpCompression; - } - - /** - * Activate websocket protocol compression. - * Uses {@code permessage-deflate} encoding only. - *

- * Default is true - * - * @param websocketCompression - true to use websocket compression - */ - public void setWebsocketCompression(boolean websocketCompression) { - this.websocketCompression = websocketCompression; - } - public boolean isWebsocketCompression() { - return websocketCompression; - } - - public boolean isRandomSession() { - return randomSession; - } - - public void setRandomSession(boolean randomSession) { - this.randomSession = randomSession; - } - - public String getAccessControlAllowHeaders() { - return accessControlAllowHeaders; - } - - public void setAccessControlAllowHeaders(String accessControlAllowHeaders) { - this.accessControlAllowHeaders = accessControlAllowHeaders; - } - - public List getConnectInterceptors() { - return connectInterceptors; - } - - public void setConnectInterceptors(Interceptor[] connectInterceptors) { - this.connectInterceptors = Arrays.asList(connectInterceptors); - } - - public List getDisconnectInterceptors() { - return disconnectInterceptors; - } - - public void setDisconnectInterceptors(Interceptor[] disconnectInterceptors) { - this.disconnectInterceptors = Arrays.asList(disconnectInterceptors); - } - - public List getEventInterceptors() { - return eventInterceptors; - } - - public void setEventInterceptors(EventInterceptor[] eventInterceptors) { - this.eventInterceptors = Arrays.asList(eventInterceptors); - } - - public String[] getNettyProtocols() { - return nettyProtocols; - } - - public void setNettyProtocols(String[] nettyProtocols) { - this.nettyProtocols = nettyProtocols; - } - - public String[] getNettyCiphers() { - return nettyCiphers; - } - - public void setNettyCiphers(String[] nettyCiphers) { - this.nettyCiphers = nettyCiphers; - } -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/Disconnectable.java b/fine-socketio/src/main/java/com/fr/third/socketio/Disconnectable.java deleted file mode 100644 index 644c18e2b..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/Disconnectable.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import com.fr.third.socketio.handler.ClientHead; - - - -public interface Disconnectable { - - void onDisconnect(ClientHead client); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/DisconnectableHub.java b/fine-socketio/src/main/java/com/fr/third/socketio/DisconnectableHub.java deleted file mode 100644 index 2fe1acb2a..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/DisconnectableHub.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -public interface DisconnectableHub extends Disconnectable { - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/HandshakeData.java b/fine-socketio/src/main/java/com/fr/third/socketio/HandshakeData.java deleted file mode 100644 index 48a87e9f5..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/HandshakeData.java +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import java.io.Serializable; -import java.net.InetSocketAddress; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import io.netty.handler.codec.http.HttpHeaders; - -public class HandshakeData implements Serializable { - - private static final long serialVersionUID = 1196350300161819978L; - - private HttpHeaders headers; - private InetSocketAddress address; - private Date time = new Date(); - private InetSocketAddress local; - private String url; - private Map> urlParams; - private boolean xdomain; - - // needed for correct deserialization - public HandshakeData() { - } - - public HandshakeData(HttpHeaders headers, Map> urlParams, InetSocketAddress address, String url, boolean xdomain) { - this(headers, urlParams, address, null, url, xdomain); - } - - public HandshakeData(HttpHeaders headers, Map> urlParams, InetSocketAddress address, InetSocketAddress local, String url, boolean xdomain) { - super(); - this.headers = headers; - this.urlParams = urlParams; - this.address = address; - this.local = local; - this.url = url; - this.xdomain = xdomain; - } - - /** - * Client network address - * - * @return network address - */ - public InetSocketAddress getAddress() { - return address; - } - - /** - * Connection local address - * - * @return local address - */ - public InetSocketAddress getLocal() { - return local; - } - - /** - * Http headers sent during first client request - * - * @return headers - */ - public HttpHeaders getHttpHeaders() { - return headers; - } - - /** - * Client connection date - * - * @return date - */ - public Date getTime() { - return time; - } - - /** - * Url used by client during first request - * - * @return url - */ - public String getUrl() { - return url; - } - - public boolean isXdomain() { - return xdomain; - } - - /** - * Url params stored in url used by client during first request - * - * @return map - */ - public Map> getUrlParams() { - return urlParams; - } - - public String getSingleUrlParam(String name) { - List values = urlParams.get(name); - if (values != null && values.size() == 1) { - return values.iterator().next(); - } - return null; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/JsonSupportWrapper.java b/fine-socketio/src/main/java/com/fr/third/socketio/JsonSupportWrapper.java deleted file mode 100644 index ff9c8509b..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/JsonSupportWrapper.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import io.netty.buffer.ByteBufInputStream; -import io.netty.buffer.ByteBufOutputStream; - -import java.io.IOException; -import java.util.List; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.protocol.AckArgs; -import com.fr.third.socketio.protocol.JsonSupport; - -class JsonSupportWrapper implements JsonSupport { - - private static final Logger log = LoggerFactory.getLogger(JsonSupportWrapper.class); - - private final JsonSupport delegate; - - JsonSupportWrapper(JsonSupport delegate) { - this.delegate = delegate; - } - - @Override - public AckArgs readAckArgs(ByteBufInputStream src, AckCallback callback) throws IOException { - try { - return delegate.readAckArgs(src, callback); - } catch (Exception e) { - src.reset(); - log.error("Can't read ack args: " + src.readLine() + " for type: " + callback.getResultClass(), e); - throw new IOException(e); - } - } - - @Override - public T readValue(String namespaceName, ByteBufInputStream src, Class valueType) throws IOException { - try { - return delegate.readValue(namespaceName, src, valueType); - } catch (Exception e) { - src.reset(); - log.error("Can't read value: " + src.readLine() + " for type: " + valueType, e); - throw new IOException(e); - } - } - - @Override - public void writeValue(ByteBufOutputStream out, Object value) throws IOException { - try { - delegate.writeValue(out, value); - } catch (Exception e) { - log.error("Can't write value: " + value, e); - throw new IOException(e); - } - } - - @Override - public void addEventMapping(String namespaceName, String eventName, Class ... eventClass) { - delegate.addEventMapping(namespaceName, eventName, eventClass); - } - - @Override - public void removeEventMapping(String namespaceName, String eventName) { - delegate.removeEventMapping(namespaceName, eventName); - } - - @Override - public List getArrays() { - return delegate.getArrays(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/MultiRoomBroadcastOperations.java b/fine-socketio/src/main/java/com/fr/third/socketio/MultiRoomBroadcastOperations.java deleted file mode 100644 index f31e73c09..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/MultiRoomBroadcastOperations.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import com.fr.third.socketio.protocol.Packet; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -/** - * author: liangjiaqi - * date: 2020/8/8 6:02 PM - */ -public class MultiRoomBroadcastOperations implements BroadcastOperations { - - private Collection broadcastOperations; - - public MultiRoomBroadcastOperations(Collection broadcastOperations) { - this.broadcastOperations = broadcastOperations; - } - - @Override - public Collection getClients() { - Set clients = new HashSet(); - if( this.broadcastOperations == null || this.broadcastOperations.size() == 0 ) { - return clients; - } - for( BroadcastOperations b : this.broadcastOperations ) { - clients.addAll( b.getClients() ); - } - return clients; - } - - @Override - public void send(Packet packet, BroadcastAckCallback ackCallback) { - if( this.broadcastOperations == null || this.broadcastOperations.size() == 0 ) { - return; - } - for( BroadcastOperations b : this.broadcastOperations ) { - b.send( packet, ackCallback ); - } - } - - @Override - public void sendEvent(String name, SocketIOClient excludedClient, Object... data) { - if( this.broadcastOperations == null || this.broadcastOperations.size() == 0 ) { - return; - } - for( BroadcastOperations b : this.broadcastOperations ) { - b.sendEvent( name, excludedClient, data ); - } - } - - @Override - public void sendEvent(String name, Object data, BroadcastAckCallback ackCallback) { - if( this.broadcastOperations == null || this.broadcastOperations.size() == 0 ) { - return; - } - for( BroadcastOperations b : this.broadcastOperations ) { - b.sendEvent( name, data, ackCallback ); - } - } - - @Override - public void sendEvent(String name, Object data, SocketIOClient excludedClient, BroadcastAckCallback ackCallback) { - if( this.broadcastOperations == null || this.broadcastOperations.size() == 0 ) { - return; - } - for( BroadcastOperations b : this.broadcastOperations ) { - b.sendEvent( name, data, excludedClient, ackCallback ); - } - } - - @Override - public void send(Packet packet) { - if( this.broadcastOperations == null || this.broadcastOperations.size() == 0 ) { - return; - } - for( BroadcastOperations b : this.broadcastOperations ) { - b.send( packet ); - } - } - - @Override - public void disconnect() { - if( this.broadcastOperations == null || this.broadcastOperations.size() == 0 ) { - return; - } - for( BroadcastOperations b : this.broadcastOperations ) { - b.disconnect(); - } - } - - @Override - public void sendEvent(String name, Object... data) { - if( this.broadcastOperations == null || this.broadcastOperations.size() == 0 ) { - return; - } - for( BroadcastOperations b : this.broadcastOperations ) { - b.sendEvent( name, data ); - } - } -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/MultiTypeAckCallback.java b/fine-socketio/src/main/java/com/fr/third/socketio/MultiTypeAckCallback.java deleted file mode 100644 index 975a2f7b2..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/MultiTypeAckCallback.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -/** - * Multi type ack callback used in case of multiple ack arguments - * - */ -public abstract class MultiTypeAckCallback extends AckCallback { - - private Class[] resultClasses; - - public MultiTypeAckCallback(Class ... resultClasses) { - super(MultiTypeArgs.class); - this.resultClasses = resultClasses; - } - - public Class[] getResultClasses() { - return resultClasses; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/MultiTypeArgs.java b/fine-socketio/src/main/java/com/fr/third/socketio/MultiTypeArgs.java deleted file mode 100644 index 591b33c85..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/MultiTypeArgs.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import java.util.Iterator; -import java.util.List; - -public class MultiTypeArgs implements Iterable { - - private final List args; - - public MultiTypeArgs(List args) { - super(); - this.args = args; - } - - public boolean isEmpty() { - return size() == 0; - } - - public int size() { - return args.size(); - } - - public List getArgs() { - return args; - } - - public T first() { - return get(0); - } - - public T second() { - return get(1); - } - - /** - * "index out of bounds"-safe method for getting elements - * - * @param type of argument - * @param index to get - * @return argument - */ - public T get(int index) { - if (size() <= index) { - return null; - } - return (T) args.get(index); - } - - @Override - public Iterator iterator() { - return args.iterator(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/SingleRoomBroadcastOperations.java b/fine-socketio/src/main/java/com/fr/third/socketio/SingleRoomBroadcastOperations.java deleted file mode 100644 index 317458e2f..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/SingleRoomBroadcastOperations.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import com.fr.third.socketio.misc.IterableCollection; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketType; -import com.fr.third.socketio.store.StoreFactory; -import com.fr.third.socketio.store.pubsub.DispatchMessage; -import com.fr.third.socketio.store.pubsub.PubSubType; - -import java.util.Arrays; -import java.util.Collection; - -/** - * Author: liangjiaqi - * Date: 2020/8/8 6:08 PM - */ -public class SingleRoomBroadcastOperations implements BroadcastOperations { - private final String namespace; - private final String room; - private final Iterable clients; - private final StoreFactory storeFactory; - - public SingleRoomBroadcastOperations(String namespace, String room, Iterable clients, StoreFactory storeFactory) { - super(); - this.namespace = namespace; - this.room = room; - this.clients = clients; - this.storeFactory = storeFactory; - } - - private void dispatch(Packet packet) { - this.storeFactory.pubSubStore().publish( - PubSubType.DISPATCH, - new DispatchMessage(this.room, packet, this.namespace)); - } - - @Override - public Collection getClients() { - return new IterableCollection(clients); - } - - @Override - public void send(Packet packet) { - for (SocketIOClient client : clients) { - client.send(packet); - } - dispatch(packet); - } - - @Override - public void send(Packet packet, BroadcastAckCallback ackCallback) { - for (SocketIOClient client : clients) { - client.send(packet, ackCallback.createClientCallback(client)); - } - ackCallback.loopFinished(); - } - - @Override - public void disconnect() { - for (SocketIOClient client : clients) { - client.disconnect(); - } - } - - @Override - public void sendEvent(String name, SocketIOClient excludedClient, Object... data) { - Packet packet = new Packet(PacketType.MESSAGE); - packet.setSubType(PacketType.EVENT); - packet.setName(name); - packet.setData(Arrays.asList(data)); - - for (SocketIOClient client : clients) { - if (client.getSessionId().equals(excludedClient.getSessionId())) { - continue; - } - client.send(packet); - } - dispatch(packet); - } - - @Override - public void sendEvent(String name, Object... data) { - Packet packet = new Packet(PacketType.MESSAGE); - packet.setSubType(PacketType.EVENT); - packet.setName(name); - packet.setData(Arrays.asList(data)); - send(packet); - } - - @Override - public void sendEvent(String name, Object data, BroadcastAckCallback ackCallback) { - for (SocketIOClient client : clients) { - client.sendEvent(name, ackCallback.createClientCallback(client), data); - } - ackCallback.loopFinished(); - } - - @Override - public void sendEvent(String name, Object data, SocketIOClient excludedClient, BroadcastAckCallback ackCallback) { - for (SocketIOClient client : clients) { - if (client.getSessionId().equals(excludedClient.getSessionId())) { - continue; - } - client.sendEvent(name, ackCallback.createClientCallback(client), data); - } - ackCallback.loopFinished(); - } -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/SocketConfig.java b/fine-socketio/src/main/java/com/fr/third/socketio/SocketConfig.java deleted file mode 100644 index a1ea9f5a7..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/SocketConfig.java +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -/** - * TCP socket configuration contains configuration for main server channel - * and client channels - * - * @see java.net.SocketOptions - */ -public class SocketConfig { - - private boolean tcpNoDelay = true; - - private int tcpSendBufferSize = -1; - - private int tcpReceiveBufferSize = -1; - - private boolean tcpKeepAlive = false; - - private int soLinger = -1; - - private boolean reuseAddress = false; - - private int acceptBackLog = 1024; - - public boolean isTcpNoDelay() { - return tcpNoDelay; - } - public void setTcpNoDelay(boolean tcpNoDelay) { - this.tcpNoDelay = tcpNoDelay; - } - - public int getTcpSendBufferSize() { - return tcpSendBufferSize; - } - public void setTcpSendBufferSize(int tcpSendBufferSize) { - this.tcpSendBufferSize = tcpSendBufferSize; - } - - public int getTcpReceiveBufferSize() { - return tcpReceiveBufferSize; - } - public void setTcpReceiveBufferSize(int tcpReceiveBufferSize) { - this.tcpReceiveBufferSize = tcpReceiveBufferSize; - } - - public boolean isTcpKeepAlive() { - return tcpKeepAlive; - } - public void setTcpKeepAlive(boolean tcpKeepAlive) { - this.tcpKeepAlive = tcpKeepAlive; - } - - public int getSoLinger() { - return soLinger; - } - public void setSoLinger(int soLinger) { - this.soLinger = soLinger; - } - - public boolean isReuseAddress() { - return reuseAddress; - } - public void setReuseAddress(boolean reuseAddress) { - this.reuseAddress = reuseAddress; - } - - public int getAcceptBackLog() { - return acceptBackLog; - } - public void setAcceptBackLog(int acceptBackLog) { - this.acceptBackLog = acceptBackLog; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOChannelInitializer.java b/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOChannelInitializer.java deleted file mode 100644 index 0ea37272d..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOChannelInitializer.java +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import java.security.KeyStore; - -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; - -import com.fr.stable.ArrayUtils; -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.ack.AckManager; -import com.fr.third.socketio.handler.AuthorizeHandler; -import com.fr.third.socketio.handler.ClientHead; -import com.fr.third.socketio.handler.ClientsBox; -import com.fr.third.socketio.handler.EncoderHandler; -import com.fr.third.socketio.handler.InPacketHandler; -import com.fr.third.socketio.handler.PacketListener; -import com.fr.third.socketio.handler.WrongUrlHandler; -import com.fr.third.socketio.namespace.NamespacesHub; -import com.fr.third.socketio.protocol.JsonSupport; -import com.fr.third.socketio.protocol.PacketDecoder; -import com.fr.third.socketio.protocol.PacketEncoder; -import com.fr.third.socketio.scheduler.CancelableScheduler; -import com.fr.third.socketio.scheduler.HashedWheelTimeoutScheduler; -import com.fr.third.socketio.store.StoreFactory; -import com.fr.third.socketio.store.pubsub.DisconnectMessage; -import com.fr.third.socketio.store.pubsub.PubSubType; -import com.fr.third.socketio.transport.PollingTransport; -import com.fr.third.socketio.transport.WebSocketTransport; - -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.handler.codec.http.HttpContentCompressor; -import io.netty.handler.codec.http.HttpMessage; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseEncoder; -import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler; -import io.netty.handler.ssl.SslHandler; - -public class SocketIOChannelInitializer extends ChannelInitializer implements DisconnectableHub { - - public static final String SOCKETIO_ENCODER = "socketioEncoder"; - public static final String WEB_SOCKET_TRANSPORT_COMPRESSION = "webSocketTransportCompression"; - public static final String WEB_SOCKET_TRANSPORT = "webSocketTransport"; - public static final String WEB_SOCKET_AGGREGATOR = "webSocketAggregator"; - public static final String XHR_POLLING_TRANSPORT = "xhrPollingTransport"; - public static final String AUTHORIZE_HANDLER = "authorizeHandler"; - public static final String PACKET_HANDLER = "packetHandler"; - public static final String HTTP_ENCODER = "httpEncoder"; - public static final String HTTP_COMPRESSION = "httpCompression"; - public static final String HTTP_AGGREGATOR = "httpAggregator"; - public static final String HTTP_REQUEST_DECODER = "httpDecoder"; - public static final String SSL_HANDLER = "ssl"; - - public static final String RESOURCE_HANDLER = "resourceHandler"; - public static final String WRONG_URL_HANDLER = "wrongUrlBlocker"; - - private static final Logger log = LoggerFactory.getLogger(SocketIOChannelInitializer.class); - - private AckManager ackManager; - - private ClientsBox clientsBox = new ClientsBox(); - private AuthorizeHandler authorizeHandler; - private PollingTransport xhrPollingTransport; - private WebSocketTransport webSocketTransport; - private WebSocketServerCompressionHandler webSocketTransportCompression = new WebSocketServerCompressionHandler(); - private EncoderHandler encoderHandler; - private WrongUrlHandler wrongUrlHandler; - - private CancelableScheduler scheduler = new HashedWheelTimeoutScheduler(); - - private InPacketHandler packetHandler; - private SSLContext sslContext; - private Configuration configuration; - - @Override - public void handlerAdded(ChannelHandlerContext ctx) { - scheduler.update(ctx); - } - - public void start(Configuration configuration, NamespacesHub namespacesHub) { - this.configuration = configuration; - - ackManager = new AckManager(scheduler); - - JsonSupport jsonSupport = configuration.getJsonSupport(); - PacketEncoder encoder = new PacketEncoder(configuration, jsonSupport); - PacketDecoder decoder = new PacketDecoder(jsonSupport, ackManager); - - String connectPath = configuration.getContext() + "/"; - - boolean isSsl = configuration.getKeyStore() != null; - if (isSsl) { - try { - sslContext = createSSLContext(configuration); - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - - StoreFactory factory = configuration.getStoreFactory(); - authorizeHandler = new AuthorizeHandler(connectPath, scheduler, configuration, namespacesHub, factory, this, ackManager, clientsBox); - factory.init(namespacesHub, authorizeHandler, jsonSupport); - xhrPollingTransport = new PollingTransport(decoder, authorizeHandler, clientsBox); - webSocketTransport = new WebSocketTransport(isSsl, authorizeHandler, configuration, scheduler, clientsBox); - - PacketListener packetListener = new PacketListener(ackManager, namespacesHub, xhrPollingTransport, scheduler); - - - packetHandler = new InPacketHandler(packetListener, decoder, namespacesHub, configuration.getExceptionListener()); - - try { - encoderHandler = new EncoderHandler(configuration, encoder); - } catch (Exception e) { - throw new IllegalStateException(e); - } - - wrongUrlHandler = new WrongUrlHandler(); - } - - @Override - protected void initChannel(Channel ch) throws Exception { - ChannelPipeline pipeline = ch.pipeline(); - addSslHandler(pipeline); - addSocketioHandlers(pipeline); - } - - /** - * Adds the ssl handler - * - * @param pipeline - channel pipeline - */ - protected void addSslHandler(ChannelPipeline pipeline) { - if (sslContext != null) { - SSLEngine engine = sslContext.createSSLEngine(); - engine.setUseClientMode(false); - - if (ArrayUtils.isNotEmpty(configuration.getNettyProtocols())) { - engine.setEnabledProtocols(configuration.getNettyProtocols()); - } - - if (ArrayUtils.isNotEmpty(configuration.getNettyCiphers())) { - engine.setEnabledCipherSuites(configuration.getNettyCiphers()); - } - - pipeline.addLast(SSL_HANDLER, new SslHandler(engine)); - } - } - - /** - * Adds the socketio channel handlers - * - * @param pipeline - channel pipeline - */ - protected void addSocketioHandlers(ChannelPipeline pipeline) { - pipeline.addLast(HTTP_REQUEST_DECODER, new HttpRequestDecoder()); - pipeline.addLast(HTTP_AGGREGATOR, new HttpObjectAggregator(configuration.getMaxHttpContentLength()) { - @Override - protected Object newContinueResponse(HttpMessage start, int maxContentLength, - ChannelPipeline pipeline) { - return null; - } - - }); - pipeline.addLast(HTTP_ENCODER, new HttpResponseEncoder()); - - if (configuration.isHttpCompression()) { - pipeline.addLast(HTTP_COMPRESSION, new HttpContentCompressor()); - } - - pipeline.addLast(PACKET_HANDLER, packetHandler); - - pipeline.addLast(AUTHORIZE_HANDLER, authorizeHandler); - pipeline.addLast(XHR_POLLING_TRANSPORT, xhrPollingTransport); - // TODO use single instance when https://github.com/netty/netty/issues/4755 will be resolved - if (configuration.isWebsocketCompression()) { - pipeline.addLast(WEB_SOCKET_TRANSPORT_COMPRESSION, new WebSocketServerCompressionHandler()); - } - pipeline.addLast(WEB_SOCKET_TRANSPORT, webSocketTransport); - - pipeline.addLast(SOCKETIO_ENCODER, encoderHandler); - - pipeline.addLast(WRONG_URL_HANDLER, wrongUrlHandler); - } - - private SSLContext createSSLContext(Configuration configuration) throws Exception { - TrustManager[] managers = null; - if (configuration.getTrustStore() != null) { - KeyStore ts = KeyStore.getInstance(configuration.getTrustStoreFormat()); - ts.load(configuration.getTrustStore(), configuration.getTrustStorePassword().toCharArray()); - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(ts); - managers = tmf.getTrustManagers(); - } - - KeyStore ks = KeyStore.getInstance(configuration.getKeyStoreFormat()); - ks.load(configuration.getKeyStore(), configuration.getKeyStorePassword().toCharArray()); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance(configuration.getKeyManagerFactoryAlgorithm()); - kmf.init(ks, configuration.getKeyStorePassword().toCharArray()); - - SSLContext serverContext = SSLContext.getInstance(configuration.getSSLProtocol()); - serverContext.init(kmf.getKeyManagers(), managers, null); - return serverContext; - } - - @Override - public void onDisconnect(ClientHead client) { - ackManager.onDisconnect(client); - authorizeHandler.onDisconnect(client); - configuration.getStoreFactory().onDisconnect(client); - - configuration.getStoreFactory().pubSubStore().publish(PubSubType.DISCONNECT, new DisconnectMessage(client.getSessionId())); - - log.debug("Client with sessionId: {} disconnected", client.getSessionId()); - } - - public void stop() { - StoreFactory factory = configuration.getStoreFactory(); - factory.shutdown(); - scheduler.shutdown(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOClient.java b/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOClient.java deleted file mode 100644 index a56d2ffe0..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOClient.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import java.net.SocketAddress; -import java.util.Set; -import java.util.UUID; - -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.store.Store; - - -/** - * Fully thread-safe. - * - */ -public interface SocketIOClient extends ClientOperations, Store { - - /** - * Handshake data used during client connection - * - * @return HandshakeData - */ - HandshakeData getHandshakeData(); - - /** - * Current client transport protocol - * - * @return transport protocol - */ - Transport getTransport(); - - /** - * Send event with ack callback - * - * @param name - event name - * @param data - event data - * @param ackCallback - ack callback - */ - void sendEvent(String name, AckCallback ackCallback, Object ... data); - - /** - * Send packet with ack callback - * - * @param packet - packet to send - * @param ackCallback - ack callback - */ - void send(Packet packet, AckCallback ackCallback); - - /** - * Client namespace - * - * @return - namespace - */ - SocketIONamespace getNamespace(); - - /** - * Client session id, uses {@link UUID} object - * - * @return - session id - */ - UUID getSessionId(); - - /** - * Get client remote address - * - * @return remote address - */ - SocketAddress getRemoteAddress(); - - /** - * Check is underlying channel open - * - * @return true if channel open, otherwise false - */ - boolean isChannelOpen(); - - /** - * Join client to room - * - * @param room - name of room - */ - void joinRoom(String room); - - /** - * Join client to room - * - * @param room - name of room - */ - void leaveRoom(String room); - - /** - * Get all rooms a client is joined in. - * - * @return name of rooms - */ - Set getAllRooms(); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/SocketIONamespace.java b/fine-socketio/src/main/java/com/fr/third/socketio/SocketIONamespace.java deleted file mode 100644 index 892331fcc..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/SocketIONamespace.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import java.util.Collection; -import java.util.UUID; - -import com.fr.third.socketio.listener.ClientListeners; - -/** - * Fully thread-safe. - * - */ -public interface SocketIONamespace extends ClientListeners { - - String getName(); - - BroadcastOperations getBroadcastOperations(); - - BroadcastOperations getRoomOperations(String room); - - /** - * Get all clients connected to namespace - * - * @return collection of clients - */ - Collection getAllClients(); - - /** - * Get client by uuid connected to namespace - * - * @param uuid - id of client - * @return client - */ - SocketIOClient getClient(UUID uuid); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOServer.java b/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOServer.java deleted file mode 100644 index 5c5128b72..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/SocketIOServer.java +++ /dev/null @@ -1,307 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import com.fr.third.socketio.listener.*; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.ChannelOption; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.FixedRecvByteBufAllocator; -import io.netty.channel.ServerChannel; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.epoll.EpollServerSocketChannel; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; - -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -import io.netty.util.concurrent.GenericFutureListener; -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.namespace.Namespace; -import com.fr.third.socketio.namespace.NamespacesHub; - -/** - * Fully thread-safe. - * - */ -public class SocketIOServer implements ClientListeners { - - private static final Logger log = LoggerFactory.getLogger(SocketIOServer.class); - - private final Configuration configCopy; - private final Configuration configuration; - - private final NamespacesHub namespacesHub; - private final SocketIONamespace mainNamespace; - - private SocketIOChannelInitializer pipelineFactory = new SocketIOChannelInitializer(); - - private EventLoopGroup bossGroup; - private EventLoopGroup workerGroup; - - public SocketIOServer(Configuration configuration) { - this.configuration = configuration; - this.configCopy = new Configuration(configuration); - namespacesHub = new NamespacesHub(configCopy); - mainNamespace = addNamespace(Namespace.DEFAULT_NAME); - } - - public void setPipelineFactory(SocketIOChannelInitializer pipelineFactory) { - this.pipelineFactory = pipelineFactory; - } - - /** - * Get all clients connected to default namespace - * - * @return clients collection - */ - public Collection getAllClients() { - return namespacesHub.get(Namespace.DEFAULT_NAME).getAllClients(); - } - - /** - * Get client by uuid from default namespace - * - * @param uuid - id of client - * @return client - */ - public SocketIOClient getClient(UUID uuid) { - return namespacesHub.get(Namespace.DEFAULT_NAME).getClient(uuid); - } - - /** - * Get all namespaces - * - * @return namespaces collection - */ - public Collection getAllNamespaces() { - return namespacesHub.getAllNamespaces(); - } - - public BroadcastOperations getBroadcastOperations() { - Collection namespaces = namespacesHub.getAllNamespaces(); - List list = new ArrayList(); - BroadcastOperations broadcast = null; - if( namespaces != null && namespaces.size() > 0 ) { - for( SocketIONamespace n : namespaces ) { - broadcast = n.getBroadcastOperations(); - list.add( broadcast ); - } - } - return new MultiRoomBroadcastOperations( list ); - } - - /** - * Get broadcast operations for clients within - * room by room name - * - * @param room - name of room - * @return broadcast operations - */ - public BroadcastOperations getRoomOperations(String room) { - Collection namespaces = namespacesHub.getAllNamespaces(); - List list = new ArrayList(); - BroadcastOperations broadcast = null; - if( namespaces != null && namespaces.size() > 0 ) { - for( SocketIONamespace n : namespaces ) { - broadcast = n.getRoomOperations( room ); - list.add( broadcast ); - } - } - return new MultiRoomBroadcastOperations( list ); - } - - /** - * Start server - */ - public void start() { - startAsync().syncUninterruptibly(); - } - - public void start(GenericFutureListener> listener) { - startAsync(listener).syncUninterruptibly(); - } - - /** - * Start server asynchronously - * - * @return void - */ - public Future startAsync() { - return startAsync(new FutureListener() { - - @Override - public void operationComplete(Future future) throws Exception { - - if (future.isSuccess()) { - log.info("SocketIO server started at port: {}", configCopy.getPort()); - } else { - log.error("SocketIO server start failed at port: {}!", configCopy.getPort()); - } - } - }); - } - - /** - * Start server asynchronously - * - * @return void - */ - public Future startAsync(GenericFutureListener> listener) { - - log.info("Session store / pubsub factory used: {}", configCopy.getStoreFactory()); - initGroups(); - - pipelineFactory.start(configCopy, namespacesHub); - - Class channelClass = NioServerSocketChannel.class; - if (configCopy.isUseLinuxNativeEpoll()) { - channelClass = EpollServerSocketChannel.class; - } - - ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup) - .channel(channelClass) - .childHandler(pipelineFactory); - applyConnectionOptions(b); - - InetSocketAddress addr = new InetSocketAddress(configCopy.getPort()); - if (configCopy.getHostname() != null) { - addr = new InetSocketAddress(configCopy.getHostname(), configCopy.getPort()); - } - - return b.bind(addr).addListener(listener); - } - - protected void applyConnectionOptions(ServerBootstrap bootstrap) { - SocketConfig config = configCopy.getSocketConfig(); - bootstrap.childOption(ChannelOption.TCP_NODELAY, config.isTcpNoDelay()); - if (config.getTcpSendBufferSize() != -1) { - bootstrap.childOption(ChannelOption.SO_SNDBUF, config.getTcpSendBufferSize()); - } - if (config.getTcpReceiveBufferSize() != -1) { - bootstrap.childOption(ChannelOption.SO_RCVBUF, config.getTcpReceiveBufferSize()); - bootstrap.childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(config.getTcpReceiveBufferSize())); - } - bootstrap.childOption(ChannelOption.SO_KEEPALIVE, config.isTcpKeepAlive()); - bootstrap.childOption(ChannelOption.SO_LINGER, config.getSoLinger()); - - bootstrap.option(ChannelOption.SO_REUSEADDR, config.isReuseAddress()); - bootstrap.option(ChannelOption.SO_BACKLOG, config.getAcceptBackLog()); - } - - protected void initGroups() { - if (configCopy.isUseLinuxNativeEpoll()) { - bossGroup = new EpollEventLoopGroup(configCopy.getBossThreads()); - workerGroup = new EpollEventLoopGroup(configCopy.getWorkerThreads()); - } else { - bossGroup = new NioEventLoopGroup(configCopy.getBossThreads()); - workerGroup = new NioEventLoopGroup(configCopy.getWorkerThreads()); - } - } - - /** - * Stop server - */ - public void stop() { - bossGroup.shutdownGracefully().syncUninterruptibly(); - workerGroup.shutdownGracefully().syncUninterruptibly(); - - pipelineFactory.stop(); - log.info("SocketIO server stopped"); - } - - public void stopImmediately() { - this.bossGroup.shutdownGracefully(0L, 1L, TimeUnit.SECONDS).syncUninterruptibly(); - this.workerGroup.shutdownGracefully(0L, 1L, TimeUnit.SECONDS).syncUninterruptibly(); - this.pipelineFactory.stop(); - log.info("SocketIO server stopped"); - } - - public SocketIONamespace addNamespace(String name) { - return namespacesHub.create(name); - } - - public SocketIONamespace getNamespace(String name) { - return namespacesHub.get(name); - } - - public void removeNamespace(String name) { - namespacesHub.remove(name); - } - - /** - * Allows to get configuration provided - * during server creation. Further changes on - * this object not affect server. - * - * @return Configuration object - */ - public Configuration getConfiguration() { - return configuration; - } - - @Override - public void addMultiTypeEventListener(String eventName, MultiTypeEventListener listener, Class... eventClass) { - mainNamespace.addMultiTypeEventListener(eventName, listener, eventClass); - } - - @Override - public void addEventListener(String eventName, Class eventClass, DataListener listener) { - mainNamespace.addEventListener(eventName, eventClass, listener); - } - - @Override - public void removeAllListeners(String eventName) { - mainNamespace.removeAllListeners(eventName); - } - - @Override - public void addDisconnectListener(DisconnectListener listener) { - mainNamespace.addDisconnectListener(listener); - } - - @Override - public void addConnectListener(ConnectListener listener) { - mainNamespace.addConnectListener(listener); - } - - @Override - public void addPingListener(PingListener listener) { - mainNamespace.addPingListener(listener); - } - - @Override - public void addListeners(Object listeners) { - mainNamespace.addListeners(listeners); - } - - @Override - public void addListeners(Object listeners, Class listenersClass) { - mainNamespace.addListeners(listeners, listenersClass); - } - - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/Transport.java b/fine-socketio/src/main/java/com/fr/third/socketio/Transport.java deleted file mode 100644 index a2dc635a0..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/Transport.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -import com.fr.third.socketio.transport.WebSocketTransport; -import com.fr.third.socketio.transport.PollingTransport; - -public enum Transport { - - WEBSOCKET(WebSocketTransport.NAME), - POLLING(PollingTransport.NAME); - - private final String value; - - Transport(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - public static Transport byName(String value) { - for (Transport t : Transport.values()) { - if (t.getValue().equals(value)) { - return t; - } - } - throw new IllegalArgumentException("Can't find " + value + " transport"); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/VoidAckCallback.java b/fine-socketio/src/main/java/com/fr/third/socketio/VoidAckCallback.java deleted file mode 100644 index de5e30589..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/VoidAckCallback.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio; - -/** - * Base ack callback with {@link Void} class as type. - * - */ -public abstract class VoidAckCallback extends AckCallback { - - public VoidAckCallback() { - super(Void.class); - } - - public VoidAckCallback(int timeout) { - super(Void.class, timeout); - } - - @Override - public final void onSuccess(Void result) { - onSuccess(); - } - - protected abstract void onSuccess(); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/ack/AckManager.java b/fine-socketio/src/main/java/com/fr/third/socketio/ack/AckManager.java deleted file mode 100644 index 40aa49bda..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/ack/AckManager.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.ack; - -import com.fr.third.socketio.*; -import com.fr.third.socketio.handler.ClientHead; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.scheduler.CancelableScheduler; -import com.fr.third.socketio.scheduler.SchedulerKey; -import com.fr.third.socketio.scheduler.SchedulerKey.Type; -import io.netty.util.internal.PlatformDependent; -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -public class AckManager implements Disconnectable { - - class AckEntry { - - final Map> ackCallbacks = PlatformDependent.newConcurrentHashMap(); - final AtomicLong ackIndex = new AtomicLong(-1); - - public long addAckCallback(AckCallback callback) { - long index = ackIndex.incrementAndGet(); - ackCallbacks.put(index, callback); - return index; - } - - public Set getAckIndexes() { - return ackCallbacks.keySet(); - } - - public AckCallback getAckCallback(long index) { - return ackCallbacks.get(index); - } - - public AckCallback removeCallback(long index) { - return ackCallbacks.remove(index); - } - - public void initAckIndex(long index) { - ackIndex.compareAndSet(-1, index); - } - - } - - private static final Logger log = LoggerFactory.getLogger(AckManager.class); - - private final ConcurrentMap ackEntries = PlatformDependent.newConcurrentHashMap(); - - private final CancelableScheduler scheduler; - - public AckManager(CancelableScheduler scheduler) { - super(); - this.scheduler = scheduler; - } - - public void initAckIndex(UUID sessionId, long index) { - AckEntry ackEntry = getAckEntry(sessionId); - ackEntry.initAckIndex(index); - } - - private AckEntry getAckEntry(UUID sessionId) { - AckEntry ackEntry = ackEntries.get(sessionId); - if (ackEntry == null) { - ackEntry = new AckEntry(); - AckEntry oldAckEntry = ackEntries.putIfAbsent(sessionId, ackEntry); - if (oldAckEntry != null) { - ackEntry = oldAckEntry; - } - } - return ackEntry; - } - - @SuppressWarnings("unchecked") - public void onAck(SocketIOClient client, Packet packet) { - AckSchedulerKey key = new AckSchedulerKey(Type.ACK_TIMEOUT, client.getSessionId(), packet.getAckId()); - scheduler.cancel(key); - - AckCallback callback = removeCallback(client.getSessionId(), packet.getAckId()); - if (callback == null) { - return; - } - if (callback instanceof MultiTypeAckCallback) { - callback.onSuccess(new MultiTypeArgs(packet.>getData())); - } else { - Object param = null; - List args = packet.getData(); - if (!args.isEmpty()) { - param = args.get(0); - } - if (args.size() > 1) { - log.error("Wrong ack args amount. Should be only one argument, but current amount is: {}. Ack id: {}, sessionId: {}", - args.size(), packet.getAckId(), client.getSessionId()); - } - callback.onSuccess(param); - } - } - - private AckCallback removeCallback(UUID sessionId, long index) { - AckEntry ackEntry = ackEntries.get(sessionId); - // may be null if client disconnected - // before timeout occurs - if (ackEntry != null) { - return ackEntry.removeCallback(index); - } - return null; - } - - public AckCallback getCallback(UUID sessionId, long index) { - AckEntry ackEntry = getAckEntry(sessionId); - return ackEntry.getAckCallback(index); - } - - public long registerAck(UUID sessionId, AckCallback callback) { - AckEntry ackEntry = getAckEntry(sessionId); - ackEntry.initAckIndex(0); - long index = ackEntry.addAckCallback(callback); - - if (log.isDebugEnabled()) { - log.debug("AckCallback registered with id: {} for client: {}", index, sessionId); - } - - scheduleTimeout(index, sessionId, callback); - - return index; - } - - private void scheduleTimeout(final long index, final UUID sessionId, AckCallback callback) { - if (callback.getTimeout() == -1) { - return; - } - SchedulerKey key = new AckSchedulerKey(Type.ACK_TIMEOUT, sessionId, index); - scheduler.scheduleCallback(key, new Runnable() { - @Override - public void run() { - AckCallback cb = removeCallback(sessionId, index); - if (cb != null) { - cb.onTimeout(); - } - } - }, callback.getTimeout(), TimeUnit.SECONDS); - } - - @Override - public void onDisconnect(ClientHead client) { - AckEntry e = ackEntries.remove(client.getSessionId()); - if (e == null) { - return; - } - - Set indexes = e.getAckIndexes(); - for (Long index : indexes) { - AckCallback callback = e.getAckCallback(index); - if (callback != null) { - callback.onTimeout(); - } - SchedulerKey key = new AckSchedulerKey(Type.ACK_TIMEOUT, client.getSessionId(), index); - scheduler.cancel(key); - } - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/ack/AckSchedulerKey.java b/fine-socketio/src/main/java/com/fr/third/socketio/ack/AckSchedulerKey.java deleted file mode 100644 index 5cc8ddb6b..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/ack/AckSchedulerKey.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.ack; - -import java.util.UUID; - -import com.fr.third.socketio.scheduler.SchedulerKey; - -public class AckSchedulerKey extends SchedulerKey { - - private final long index; - - public AckSchedulerKey(Type type, UUID sessionId, long index) { - super(type, sessionId); - this.index = index; - } - - public long getIndex() { - return index; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + (int) (index ^ (index >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - AckSchedulerKey other = (AckSchedulerKey) obj; - if (index != other.index) - return false; - return true; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/AnnotationScanner.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/AnnotationScanner.java deleted file mode 100644 index 9110a24a7..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/AnnotationScanner.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; - -import com.fr.third.socketio.namespace.Namespace; - -public interface AnnotationScanner { - - Class getScanAnnotation(); - - void addListener(Namespace namespace, Object object, Method method, Annotation annotation); - - void validate(Method method, Class clazz); - -} \ No newline at end of file diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnConnect.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnConnect.java deleted file mode 100644 index fcbb357f1..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnConnect.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotation that defines Connect handler. - * - * Arguments in method: - * - * - SocketIOClient (required) - * - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface OnConnect { - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnConnectScanner.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnConnectScanner.java deleted file mode 100644 index 3c9bcf1f4..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnConnectScanner.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.fr.third.socketio.SocketIOClient; -import com.fr.third.socketio.handler.SocketIOException; -import com.fr.third.socketio.listener.ConnectListener; -import com.fr.third.socketio.namespace.Namespace; - -public class OnConnectScanner implements AnnotationScanner { - - @Override - public Class getScanAnnotation() { - return OnConnect.class; - } - - @Override - public void addListener(Namespace namespace, final Object object, final Method method, Annotation annotation) { - namespace.addConnectListener(new ConnectListener() { - @Override - public void onConnect(SocketIOClient client) { - try { - method.invoke(object, client); - } catch (InvocationTargetException e) { - throw new SocketIOException(e.getCause()); - } catch (Exception e) { - throw new SocketIOException(e); - } - } - }); - } - - @Override - public void validate(Method method, Class clazz) { - if (method.getParameterTypes().length != 1) { - throw new IllegalArgumentException("Wrong OnConnect listener signature: " + clazz + "." + method.getName()); - } - boolean valid = false; - for (Class eventType : method.getParameterTypes()) { - if (eventType.equals(SocketIOClient.class)) { - valid = true; - } - } - if (!valid) { - throw new IllegalArgumentException("Wrong OnConnect listener signature: " + clazz + "." + method.getName()); - } - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnDisconnect.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnDisconnect.java deleted file mode 100644 index 0a26baa90..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnDisconnect.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that defines Disconnect handler. - * - * Arguments in method: - * - * - SocketIOClient (required) - * - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface OnDisconnect { - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnDisconnectScanner.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnDisconnectScanner.java deleted file mode 100644 index 378bf49ba..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnDisconnectScanner.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.fr.third.socketio.SocketIOClient; -import com.fr.third.socketio.handler.SocketIOException; -import com.fr.third.socketio.listener.DisconnectListener; -import com.fr.third.socketio.namespace.Namespace; - -public class OnDisconnectScanner implements AnnotationScanner { - - @Override - public Class getScanAnnotation() { - return OnDisconnect.class; - } - - @Override - public void addListener(Namespace namespace, final Object object, final Method method, Annotation annotation) { - namespace.addDisconnectListener(new DisconnectListener() { - @Override - public void onDisconnect(SocketIOClient client) { - try { - method.invoke(object, client); - } catch (InvocationTargetException e) { - throw new SocketIOException(e.getCause()); - } catch (Exception e) { - throw new SocketIOException(e); - } - } - }); - } - - @Override - public void validate(Method method, Class clazz) { - if (method.getParameterTypes().length != 1) { - throw new IllegalArgumentException("Wrong OnDisconnect listener signature: " + clazz + "." + method.getName()); - } - boolean valid = false; - for (Class eventType : method.getParameterTypes()) { - if (eventType.equals(SocketIOClient.class)) { - valid = true; - } - } - if (!valid) { - throw new IllegalArgumentException("Wrong OnDisconnect listener signature: " + clazz + "." + method.getName()); - } - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnEvent.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnEvent.java deleted file mode 100644 index e245132e7..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnEvent.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that defines Event handler. - * The value is required, and represents event name. - * - * Arguments in method: - * - * - SocketIOClient (optional) - * - AckRequest (optional) - * - Event data (optional) - * - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface OnEvent { - - /** - * Event name - * - * @return value - */ - String value(); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnEventScanner.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnEventScanner.java deleted file mode 100644 index 1f682fc14..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/OnEventScanner.java +++ /dev/null @@ -1,154 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -import com.fr.third.socketio.AckRequest; -import com.fr.third.socketio.MultiTypeArgs; -import com.fr.third.socketio.SocketIOClient; -import com.fr.third.socketio.handler.SocketIOException; -import com.fr.third.socketio.listener.DataListener; -import com.fr.third.socketio.listener.MultiTypeEventListener; -import com.fr.third.socketio.namespace.Namespace; - -public class OnEventScanner implements AnnotationScanner { - - @Override - public Class getScanAnnotation() { - return OnEvent.class; - } - - @Override - @SuppressWarnings("unchecked") - public void addListener(Namespace namespace, final Object object, final Method method, Annotation annot) { - OnEvent annotation = (OnEvent) annot; - if (annotation.value() == null || annotation.value().trim().length() == 0) { - throw new IllegalArgumentException("OnEvent \"value\" parameter is required"); - } - final int socketIOClientIndex = paramIndex(method, SocketIOClient.class); - final int ackRequestIndex = paramIndex(method, AckRequest.class); - final List dataIndexes = dataIndexes(method); - - if (dataIndexes.size() > 1) { - List> classes = new ArrayList>(); - for (int index : dataIndexes) { - Class param = method.getParameterTypes()[index]; - classes.add(param); - } - - namespace.addMultiTypeEventListener(annotation.value(), new MultiTypeEventListener() { - @Override - public void onData(SocketIOClient client, MultiTypeArgs data, AckRequest ackSender) { - try { - Object[] args = new Object[method.getParameterTypes().length]; - if (socketIOClientIndex != -1) { - args[socketIOClientIndex] = client; - } - if (ackRequestIndex != -1) { - args[ackRequestIndex] = ackSender; - } - int i = 0; - for (int index : dataIndexes) { - args[index] = data.get(i); - i++; - } - method.invoke(object, args); - } catch (InvocationTargetException e) { - throw new SocketIOException(e.getCause()); - } catch (Exception e) { - throw new SocketIOException(e); - } - } - }, classes.toArray(new Class[classes.size()])); - } else { - Class objectType = Void.class; - if (!dataIndexes.isEmpty()) { - objectType = method.getParameterTypes()[dataIndexes.iterator().next()]; - } - - namespace.addEventListener(annotation.value(), objectType, new DataListener() { - @Override - public void onData(SocketIOClient client, Object data, AckRequest ackSender) { - try { - Object[] args = new Object[method.getParameterTypes().length]; - if (socketIOClientIndex != -1) { - args[socketIOClientIndex] = client; - } - if (ackRequestIndex != -1) { - args[ackRequestIndex] = ackSender; - } - if (!dataIndexes.isEmpty()) { - int dataIndex = dataIndexes.iterator().next(); - args[dataIndex] = data; - } - method.invoke(object, args); - } catch (InvocationTargetException e) { - throw new SocketIOException(e.getCause()); - } catch (Exception e) { - throw new SocketIOException(e); - } - } - }); - } - } - - private List dataIndexes(Method method) { - List result = new ArrayList(); - int index = 0; - for (Class type : method.getParameterTypes()) { - if (!type.equals(AckRequest.class) && !type.equals(SocketIOClient.class)) { - result.add(index); - } - index++; - } - return result; - } - - private int paramIndex(Method method, Class clazz) { - int index = 0; - for (Class type : method.getParameterTypes()) { - if (type.equals(clazz)) { - return index; - } - index++; - } - return -1; - } - - @Override - public void validate(Method method, Class clazz) { - int paramsCount = method.getParameterTypes().length; - final int socketIOClientIndex = paramIndex(method, SocketIOClient.class); - final int ackRequestIndex = paramIndex(method, AckRequest.class); - List dataIndexes = dataIndexes(method); - paramsCount -= dataIndexes.size(); - if (socketIOClientIndex != -1) { - paramsCount--; - } - if (ackRequestIndex != -1) { - paramsCount--; - } - if (paramsCount != 0) { - throw new IllegalArgumentException("Wrong OnEvent listener signature: " + clazz + "." + method.getName()); - } - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/ScannerEngine.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/ScannerEngine.java deleted file mode 100644 index 796f8017e..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/ScannerEngine.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.List; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.namespace.Namespace; - -public class ScannerEngine { - - private static final Logger log = LoggerFactory.getLogger(ScannerEngine.class); - - private static final List annotations = - Arrays.asList(new OnConnectScanner(), new OnDisconnectScanner(), new OnEventScanner()); - - private Method findSimilarMethod(Class objectClazz, Method method) { - Method[] methods = objectClazz.getDeclaredMethods(); - for (Method m : methods) { - if (isEquals(m, method)) { - return m; - } - } - return null; - } - - public void scan(Namespace namespace, Object object, Class clazz) - throws IllegalArgumentException { - Method[] methods = clazz.getDeclaredMethods(); - - if (!clazz.isAssignableFrom(object.getClass())) { - for (Method method : methods) { - for (AnnotationScanner annotationScanner : annotations) { - Annotation ann = method.getAnnotation(annotationScanner.getScanAnnotation()); - if (ann != null) { - annotationScanner.validate(method, clazz); - - Method m = findSimilarMethod(object.getClass(), method); - if (m != null) { - annotationScanner.addListener(namespace, object, m, ann); - } else { - log.warn("Method similar to " + method.getName() + " can't be found in " + object.getClass()); - } - } - } - } - } else { - for (Method method : methods) { - for (AnnotationScanner annotationScanner : annotations) { - Annotation ann = method.getAnnotation(annotationScanner.getScanAnnotation()); - if (ann != null) { - annotationScanner.validate(method, clazz); - makeAccessible(method); - annotationScanner.addListener(namespace, object, method, ann); - } - } - } - - if (clazz.getSuperclass() != null) { - scan(namespace, object, clazz.getSuperclass()); - } else if (clazz.isInterface()) { - for (Class superIfc : clazz.getInterfaces()) { - scan(namespace, object, superIfc); - } - } - } - - } - - private boolean isEquals(Method method1, Method method2) { - if (!method1.getName().equals(method2.getName()) - || !method1.getReturnType().equals(method2.getReturnType())) { - return false; - } - - return Arrays.equals(method1.getParameterTypes(), method2.getParameterTypes()); - } - - private void makeAccessible(Method method) { - if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) - && !method.isAccessible()) { - method.setAccessible(true); - } - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/SpringAnnotationScanner.java b/fine-socketio/src/main/java/com/fr/third/socketio/annotation/SpringAnnotationScanner.java deleted file mode 100644 index 7a2916c87..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/annotation/SpringAnnotationScanner.java +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; -import com.fr.third.springframework.beans.BeansException; -import com.fr.third.springframework.beans.factory.config.BeanPostProcessor; -import com.fr.third.springframework.util.ReflectionUtils; -import com.fr.third.springframework.util.ReflectionUtils.MethodCallback; -import com.fr.third.springframework.util.ReflectionUtils.MethodFilter; - -import com.fr.third.socketio.SocketIOServer; - -public class SpringAnnotationScanner implements BeanPostProcessor { - - private static final Logger log = LoggerFactory.getLogger(SpringAnnotationScanner.class); - - private final List> annotations = - Arrays.asList(OnConnect.class, OnDisconnect.class, OnEvent.class); - - private final SocketIOServer socketIOServer; - - private Class originalBeanClass; - - public SpringAnnotationScanner(SocketIOServer socketIOServer) { - super(); - this.socketIOServer = socketIOServer; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (originalBeanClass != null) { - socketIOServer.addListeners(bean, originalBeanClass); - log.info("{} bean listeners added", beanName); - originalBeanClass = null; - } - return bean; - } - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - final AtomicBoolean add = new AtomicBoolean(); - ReflectionUtils.doWithMethods(bean.getClass(), - new MethodCallback() { - @Override - public void doWith(Method method) throws IllegalArgumentException, - IllegalAccessException { - add.set(true); - } - }, - new MethodFilter() { - @Override - public boolean matches(Method method) { - for (Class annotationClass : annotations) { - if (method.isAnnotationPresent(annotationClass)) { - return true; - } - } - return false; - } - }); - - if (add.get()) { - originalBeanClass = bean.getClass(); - } - return bean; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/AuthorizeHandler.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/AuthorizeHandler.java deleted file mode 100644 index 634f7ae45..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/AuthorizeHandler.java +++ /dev/null @@ -1,272 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.Configuration; -import com.fr.third.socketio.Disconnectable; -import com.fr.third.socketio.DisconnectableHub; -import com.fr.third.socketio.HandshakeData; -import com.fr.third.socketio.SocketIOClient; -import com.fr.third.socketio.Transport; -import com.fr.third.socketio.ack.AckManager; -import com.fr.third.socketio.messages.HttpErrorMessage; -import com.fr.third.socketio.namespace.Namespace; -import com.fr.third.socketio.namespace.NamespacesHub; -import com.fr.third.socketio.protocol.AuthPacket; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketType; -import com.fr.third.socketio.scheduler.CancelableScheduler; -import com.fr.third.socketio.scheduler.SchedulerKey; -import com.fr.third.socketio.scheduler.SchedulerKey.Type; -import com.fr.third.socketio.store.StoreFactory; -import com.fr.third.socketio.store.pubsub.ConnectMessage; -import com.fr.third.socketio.store.pubsub.PubSubType; - -import io.netty.channel.Channel; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.QueryStringDecoder; -import io.netty.handler.codec.http.cookie.Cookie; -import io.netty.handler.codec.http.cookie.ServerCookieDecoder; - -@Sharable -public class AuthorizeHandler extends ChannelInboundHandlerAdapter implements Disconnectable { - - private static final Logger log = LoggerFactory.getLogger(AuthorizeHandler.class); - - private final CancelableScheduler disconnectScheduler; - - private final String connectPath; - private final Configuration configuration; - private final NamespacesHub namespacesHub; - private final StoreFactory storeFactory; - private final DisconnectableHub disconnectable; - private final AckManager ackManager; - private final ClientsBox clientsBox; - - public AuthorizeHandler(String connectPath, CancelableScheduler scheduler, Configuration configuration, NamespacesHub namespacesHub, StoreFactory storeFactory, - DisconnectableHub disconnectable, AckManager ackManager, ClientsBox clientsBox) { - super(); - this.connectPath = connectPath; - this.configuration = configuration; - this.disconnectScheduler = scheduler; - this.namespacesHub = namespacesHub; - this.storeFactory = storeFactory; - this.disconnectable = disconnectable; - this.ackManager = ackManager; - this.clientsBox = clientsBox; - } - - @Override - public void channelActive(final ChannelHandlerContext ctx) throws Exception { - SchedulerKey key = new SchedulerKey(Type.PING_TIMEOUT, ctx.channel()); - disconnectScheduler.schedule(key, new Runnable() { - @Override - public void run() { - ctx.channel().close(); - log.debug("Client with ip {} opened channel but doesn't send any data! Channel closed!", ctx.channel().remoteAddress()); - } - }, configuration.getFirstDataTimeout(), TimeUnit.MILLISECONDS); - super.channelActive(ctx); - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - SchedulerKey key = new SchedulerKey(Type.PING_TIMEOUT, ctx.channel()); - disconnectScheduler.cancel(key); - - if (msg instanceof FullHttpRequest) { - FullHttpRequest req = (FullHttpRequest) msg; - Channel channel = ctx.channel(); - QueryStringDecoder queryDecoder = new QueryStringDecoder(req.uri()); - - if (!configuration.isAllowCustomRequests() - && !queryDecoder.path().startsWith(connectPath)) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.BAD_REQUEST); - channel.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE); - req.release(); - return; - } - - List sid = queryDecoder.parameters().get("sid"); - if (queryDecoder.path().equals(connectPath) - && sid == null) { - String origin = req.headers().get(HttpHeaderNames.ORIGIN); - if (!authorize(ctx, channel, origin, queryDecoder.parameters(), req)) { - req.release(); - return; - } - // forward message to polling or websocket handler to bind channel - } - } - ctx.fireChannelRead(msg); - } - - private boolean authorize(ChannelHandlerContext ctx, Channel channel, String origin, Map> params, FullHttpRequest req) - throws IOException { - Map> headers = new HashMap>(req.headers().names().size()); - for (String name : req.headers().names()) { - List values = req.headers().getAll(name); - headers.put(name, values); - } - - HandshakeData data = new HandshakeData(req.headers(), params, - (InetSocketAddress)channel.remoteAddress(), - (InetSocketAddress)channel.localAddress(), - req.uri(), origin != null && !origin.equalsIgnoreCase("null")); - - boolean result = false; - try { - result = configuration.getAuthorizationListener().isAuthorized(data); - } catch (Exception e) { - log.error("Authorization error", e); - } - - if (!result) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.UNAUTHORIZED); - channel.writeAndFlush(res) - .addListener(ChannelFutureListener.CLOSE); - log.debug("Handshake unauthorized, query params: {} headers: {}", params, headers); - return false; - } - - UUID sessionId = null; - if (configuration.isRandomSession()) { - sessionId = UUID.randomUUID(); - } else { - sessionId = this.generateOrGetSessionIdFromRequest(req.headers()); - } - - List transportValue = params.get("transport"); - if (transportValue == null) { - log.error("Got no transports for request {}", req.uri()); - - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.UNAUTHORIZED); - channel.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE); - return false; - } - - Transport transport = Transport.byName(transportValue.get(0)); - if (!configuration.getTransports().contains(transport)) { - Map errorData = new HashMap(); - errorData.put("code", 0); - errorData.put("message", "Transport unknown"); - - channel.attr(EncoderHandler.ORIGIN).set(origin); - channel.writeAndFlush(new HttpErrorMessage(errorData)); - return false; - } - - ClientHead client = new ClientHead(sessionId, ackManager, disconnectable, storeFactory, data, clientsBox, transport, disconnectScheduler, configuration); - channel.attr(ClientHead.CLIENT).set(client); - clientsBox.addClient(client); - - String[] transports = {}; - if (configuration.getTransports().contains(Transport.WEBSOCKET)) { - transports = new String[]{"websocket"}; - } - - AuthPacket authPacket = new AuthPacket(sessionId, transports, configuration.getPingInterval(), - configuration.getPingTimeout()); - Packet packet = new Packet(PacketType.OPEN); - packet.setData(authPacket); - client.send(packet); - - client.schedulePingTimeout(); - log.debug("Handshake authorized for sessionId: {}, query params: {} headers: {}", sessionId, params, headers); - return true; - } - - /** - * This method will either generate a new random sessionId or will retrieve the value stored - * in the "io" cookie. Failures to parse will cause a logging warning to be generated and a - * random uuid to be generated instead (same as not passing a cookie in the first place). - */ - private UUID generateOrGetSessionIdFromRequest(HttpHeaders headers) { - List values = headers.getAll("io"); - if (values.size() == 1) { - try { - return UUID.fromString(values.get(0)); - } catch (IllegalArgumentException iaex) { - log.warn("Malformed UUID received for session! io=" + values.get(0)); - } - } - - for (String cookieHeader : headers.getAll(HttpHeaderNames.COOKIE)) { - Set cookies = ServerCookieDecoder.LAX.decode(cookieHeader); - - for (Cookie cookie : cookies) { - if (cookie.name().equals("io")) { - try { - return UUID.fromString(cookie.value()); - } catch (IllegalArgumentException iaex) { - log.warn("Malformed UUID received for session! io=" + cookie.value()); - } - } - } - } - - return UUID.randomUUID(); - } - - public void connect(UUID sessionId) { - SchedulerKey key = new SchedulerKey(Type.PING_TIMEOUT, sessionId); - disconnectScheduler.cancel(key); - } - - public void connect(ClientHead client) { - Namespace ns = namespacesHub.get(Namespace.DEFAULT_NAME); - - if (!client.getNamespaces().contains(ns)) { - Packet packet = new Packet(PacketType.MESSAGE); - packet.setSubType(PacketType.CONNECT); - client.send(packet); - - configuration.getStoreFactory().pubSubStore().publish(PubSubType.CONNECT, new ConnectMessage(client.getSessionId())); - - SocketIOClient nsClient = client.addNamespaceClient(ns); - ns.onConnect(nsClient); - } - } - - @Override - public void onDisconnect(ClientHead client) { - clientsBox.removeClient(client.getSessionId()); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/ClientHead.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/ClientHead.java deleted file mode 100644 index 285274a3b..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/ClientHead.java +++ /dev/null @@ -1,298 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import com.fr.third.socketio.Configuration; -import com.fr.third.socketio.DisconnectableHub; -import com.fr.third.socketio.HandshakeData; -import com.fr.third.socketio.Transport; -import com.fr.third.socketio.ack.AckManager; -import com.fr.third.socketio.messages.OutPacketMessage; -import com.fr.third.socketio.namespace.Namespace; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketType; -import com.fr.third.socketio.scheduler.CancelableScheduler; -import com.fr.third.socketio.scheduler.SchedulerKey; -import com.fr.third.socketio.scheduler.SchedulerKey.Type; -import com.fr.third.socketio.store.Store; -import com.fr.third.socketio.store.StoreFactory; -import com.fr.third.socketio.transport.NamespaceClient; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.util.AttributeKey; -import io.netty.util.internal.PlatformDependent; -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import java.net.SocketAddress; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -public class ClientHead { - - private static final Logger log = LoggerFactory.getLogger(ClientHead.class); - - public static final AttributeKey CLIENT = AttributeKey.valueOf("client"); - - private final AtomicBoolean disconnected = new AtomicBoolean(); - private final Map namespaceClients = PlatformDependent.newConcurrentHashMap(); - private final Map channels = new HashMap(2); - private final HandshakeData handshakeData; - private final UUID sessionId; - - private final Store store; - private final DisconnectableHub disconnectableHub; - private final AckManager ackManager; - private ClientsBox clientsBox; - private final CancelableScheduler disconnectScheduler; - private final Configuration configuration; - - private Packet lastBinaryPacket; - - // TODO use lazy set - private volatile Transport currentTransport; - - public ClientHead(UUID sessionId, AckManager ackManager, DisconnectableHub disconnectable, - StoreFactory storeFactory, HandshakeData handshakeData, ClientsBox clientsBox, Transport transport, CancelableScheduler disconnectScheduler, - Configuration configuration) { - this.sessionId = sessionId; - this.ackManager = ackManager; - this.disconnectableHub = disconnectable; - this.store = storeFactory.createStore(sessionId); - this.handshakeData = handshakeData; - this.clientsBox = clientsBox; - this.currentTransport = transport; - this.disconnectScheduler = disconnectScheduler; - this.configuration = configuration; - - channels.put(Transport.POLLING, new TransportState()); - channels.put(Transport.WEBSOCKET, new TransportState()); - } - - - /** - * 这里多线程下,会有问题, - * 因为 channel 不会变, 但是 state 可能因为多线程下调用 bindChannel - * 从而导致 state.update , 致使真正 add() 时, - * channel 和 state 得数据不一致。 - * - * 解决方法 - * 1. 加锁 - * 2. 为 clientbox 加一个子线程, 定时清除 disconnected 为 true 的值。 - * - * @param channel 频道 - * @param transport 协议 - */ - public synchronized void bindChannel(Channel channel, Transport transport) { - log.debug("binding channel: {} to transport: {}", channel, transport); - - TransportState state = channels.get(transport); - Channel prevChannel = state.update(channel); - if (prevChannel != null) { - clientsBox.remove(prevChannel); - prevChannel.disconnect(); - } - clientsBox.add(channel, this); - - sendPackets(transport, channel); - } - - public void releasePollingChannel(Channel channel) { - TransportState state = channels.get(Transport.POLLING); - if(channel.equals(state.getChannel())) { - clientsBox.remove(channel); - state.update(null); - } - } - - public String getOrigin() { - return handshakeData.getHttpHeaders().get(HttpHeaderNames.ORIGIN); - } - - public ChannelFuture send(Packet packet) { - return send(packet, getCurrentTransport()); - } - - public void cancelPingTimeout() { - SchedulerKey key = new SchedulerKey(Type.PING_TIMEOUT, sessionId); - disconnectScheduler.cancel(key); - } - - public void schedulePingTimeout() { - SchedulerKey key = new SchedulerKey(Type.PING_TIMEOUT, sessionId); - disconnectScheduler.schedule(key, new TimeOutTask(this), configuration.getPingTimeout() + configuration.getPingInterval(), TimeUnit.MILLISECONDS); - } - - public ChannelFuture send(Packet packet, Transport transport) { - TransportState state = channels.get(transport); - state.getPacketsQueue().add(packet); - - Channel channel = state.getChannel(); - if (channel == null - || (transport == Transport.POLLING && channel.attr(EncoderHandler.WRITE_ONCE).get() != null)) { - return null; - } - return sendPackets(transport, channel); - } - - private ChannelFuture sendPackets(Transport transport, Channel channel) { - return channel.writeAndFlush(new OutPacketMessage(this, transport)); - } - - public void removeNamespaceClient(NamespaceClient client) { - namespaceClients.remove(client.getNamespace()); - - // 清空到最后一个的时候, 断开连接。 调用 initializer.disconnect - if (namespaceClients.isEmpty()) { - disconnectableHub.onDisconnect(this); - } - } - - public NamespaceClient getChildClient(Namespace namespace) { - return namespaceClients.get(namespace); - } - - public NamespaceClient addNamespaceClient(Namespace namespace) { - NamespaceClient client = new NamespaceClient(this, namespace); - namespaceClients.put(namespace, client); - return client; - } - - public Set getNamespaces() { - return namespaceClients.keySet(); - } - - public boolean isConnected() { - return !disconnected.get(); - } - - public void onChannelDisconnect() { - cancelPingTimeout(); - - disconnected.set(true); - for (NamespaceClient client : namespaceClients.values()) { - client.onDisconnect(); - } - for (TransportState state : channels.values()) { - if (state.getChannel() != null) { - clientsBox.remove(state.getChannel()); - } - } - } - - public HandshakeData getHandshakeData() { - return handshakeData; - } - - public AckManager getAckManager() { - return ackManager; - } - - public UUID getSessionId() { - return sessionId; - } - - public SocketAddress getRemoteAddress() { - return handshakeData.getAddress(); - } - - public void disconnect() { - ChannelFuture future = send(new Packet(PacketType.DISCONNECT)); - if(future != null) { - future.addListener(ChannelFutureListener.CLOSE); - } - - onChannelDisconnect(); - } - - public boolean isChannelOpen() { - for (TransportState state : channels.values()) { - if (state.getChannel() != null - && state.getChannel().isActive()) { - return true; - } - } - return false; - } - - public Store getStore() { - return store; - } - - public boolean isTransportChannel(Channel channel, Transport transport) { - TransportState state = channels.get(transport); - if (state.getChannel() == null) { - return false; - } - return state.getChannel().equals(channel); - } - - public void upgradeCurrentTransport(Transport currentTransport) { - TransportState state = channels.get(currentTransport); - - for (Entry entry : channels.entrySet()) { - if (!entry.getKey().equals(currentTransport)) { - - Queue queue = entry.getValue().getPacketsQueue(); - state.setPacketsQueue(queue); - - sendPackets(currentTransport, state.getChannel()); - this.currentTransport = currentTransport; - log.debug("Transport upgraded to: {} for: {}", currentTransport, sessionId); - break; - } - } - } - - public Transport getCurrentTransport() { - return currentTransport; - } - - public Queue getPacketsQueue(Transport transport) { - return channels.get(transport).getPacketsQueue(); - } - - public void setLastBinaryPacket(Packet lastBinaryPacket) { - this.lastBinaryPacket = lastBinaryPacket; - } - public Packet getLastBinaryPacket() { - return lastBinaryPacket; - } - - private class TimeOutTask implements Runnable{ - - ClientHead client; - - public TimeOutTask(ClientHead client) { - - assert client != null; - this.client = client; - } - - @Override - public void run() { - - if (client != null && !client.disconnected.get()) { - client.disconnect(); - log.debug("{} removed due to ping timeout", client.getSessionId()); - } - } - } -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/ClientsBox.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/ClientsBox.java deleted file mode 100644 index d45667fb4..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/ClientsBox.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import io.netty.channel.Channel; -import io.netty.util.internal.PlatformDependent; - -import java.util.Map; -import java.util.UUID; - -import com.fr.third.socketio.HandshakeData; - -public class ClientsBox { - - private final Map uuid2clients = PlatformDependent.newConcurrentHashMap(); - private final Map channel2clients = PlatformDependent.newConcurrentHashMap(); - - // TODO use storeFactory - public HandshakeData getHandshakeData(UUID sessionId) { - ClientHead client = uuid2clients.get(sessionId); - if (client == null) { - return null; - } - - return client.getHandshakeData(); - } - - public void addClient(ClientHead clientHead) { - uuid2clients.put(clientHead.getSessionId(), clientHead); - } - - public void removeClient(UUID sessionId) { - uuid2clients.remove(sessionId); - } - - public ClientHead get(UUID sessionId) { - return uuid2clients.get(sessionId); - } - - public void add(Channel channel, ClientHead clientHead) { - channel2clients.put(channel, clientHead); - } - - public void remove(Channel channel) { - channel2clients.remove(channel); - } - - - public ClientHead get(Channel channel) { - return channel2clients.get(channel); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/EncoderHandler.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/EncoderHandler.java deleted file mode 100644 index 656f2ccb7..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/EncoderHandler.java +++ /dev/null @@ -1,361 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import static com.fr.third.springframework.util.StringUtils.isEmpty; -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Queue; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -import com.fr.third.socketio.Configuration; -import com.fr.third.socketio.Transport; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.messages.HttpErrorMessage; -import com.fr.third.socketio.messages.HttpMessage; -import com.fr.third.socketio.messages.OutPacketMessage; -import com.fr.third.socketio.messages.XHROptionsMessage; -import com.fr.third.socketio.messages.XHRPostMessage; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketEncoder; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufOutputStream; -import io.netty.buffer.ByteBufUtil; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpContent; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaderValues; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpUtil; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketFrame; -import io.netty.util.Attribute; -import io.netty.util.AttributeKey; -import io.netty.util.CharsetUtil; - -@Sharable -public class EncoderHandler extends ChannelOutboundHandlerAdapter { - - private static final byte[] OK = "ok".getBytes(CharsetUtil.UTF_8); - - public static final AttributeKey ORIGIN = AttributeKey.valueOf("origin"); - public static final AttributeKey USER_AGENT = AttributeKey.valueOf("userAgent"); - public static final AttributeKey B64 = AttributeKey.valueOf("b64"); - public static final AttributeKey JSONP_INDEX = AttributeKey.valueOf("jsonpIndex"); - public static final AttributeKey WRITE_ONCE = AttributeKey.valueOf("writeOnce"); - - private static final Logger log = LoggerFactory.getLogger(EncoderHandler.class); - - private static final String SEPARATOR_COMMA = ","; - - private final PacketEncoder encoder; - - private String version; - private Configuration configuration; - - public EncoderHandler(Configuration configuration, PacketEncoder encoder) throws IOException { - this.encoder = encoder; - this.configuration = configuration; - - if (configuration.isAddVersionHeader()) { - readVersion(); - } - } - - private void readVersion() throws IOException { - Enumeration resources = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF"); - while (resources.hasMoreElements()) { - try { - Manifest manifest = new Manifest(resources.nextElement().openStream()); - Attributes attrs = manifest.getMainAttributes(); - if (attrs == null) { - continue; - } - String name = attrs.getValue("Bundle-Name"); - if (name != null && name.equals("netty-socketio")) { - version = name + "/" + attrs.getValue("Bundle-Version"); - break; - } - } catch (IOException E) { - // skip it - } - } - } - - private void write(XHROptionsMessage msg, ChannelHandlerContext ctx, ChannelPromise promise) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.OK); - - res.headers().add(HttpHeaderNames.SET_COOKIE, "io=" + msg.getSessionId()) - .add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE) - .add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, HttpHeaderNames.CONTENT_TYPE); - - String origin = ctx.channel().attr(ORIGIN).get(); - addOriginAndAllowHeaders(origin, res); - - ByteBuf out = encoder.allocateBuffer(ctx.alloc()); - sendMessage(msg, ctx.channel(), out, res, promise); - } - - private void write(XHRPostMessage msg, ChannelHandlerContext ctx, ChannelPromise promise) { - ByteBuf out = encoder.allocateBuffer(ctx.alloc()); - out.writeBytes(OK); - sendMessage(msg, ctx.channel(), out, "text/html", promise, HttpResponseStatus.OK); - } - - private void sendMessage(HttpMessage msg, Channel channel, ByteBuf out, String type, ChannelPromise promise, HttpResponseStatus status) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, status); - - res.headers().add(HttpHeaderNames.CONTENT_TYPE, type) - .add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); - if (msg.getSessionId() != null) { - res.headers().add(HttpHeaderNames.SET_COOKIE, "io=" + msg.getSessionId()); - } - - String origin = channel.attr(ORIGIN).get(); - addOriginAndAllowHeaders(origin, res); - - HttpUtil.setContentLength(res, out.readableBytes()); - - // prevent XSS warnings on IE - // https://github.com/LearnBoost/socket.io/pull/1333 - String userAgent = channel.attr(EncoderHandler.USER_AGENT).get(); - if (userAgent != null && (userAgent.contains(";MSIE") || userAgent.contains("Trident/"))) { - res.headers().add("X-XSS-Protection", "0"); - } - - sendMessage(msg, channel, out, res, promise); - } - - private void sendMessage(HttpMessage msg, Channel channel, ByteBuf out, HttpResponse res, ChannelPromise promise) { - channel.write(res); - - if (log.isTraceEnabled()) { - if (msg.getSessionId() != null) { - log.trace("Out message: {} - sessionId: {}", out.toString(CharsetUtil.UTF_8), msg.getSessionId()); - } else { - log.trace("Out message: {}", out.toString(CharsetUtil.UTF_8)); - } - } - - if (out.isReadable()) { - channel.write(new DefaultHttpContent(out)); - } else { - out.release(); - } - - channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT, promise).addListener(ChannelFutureListener.CLOSE); - } - - private void sendError(HttpErrorMessage errorMsg, ChannelHandlerContext ctx, ChannelPromise promise) throws IOException { - final ByteBuf encBuf = encoder.allocateBuffer(ctx.alloc()); - ByteBufOutputStream out = new ByteBufOutputStream(encBuf); - encoder.getJsonSupport().writeValue(out, errorMsg.getData()); - - sendMessage(errorMsg, ctx.channel(), encBuf, "application/json", promise, HttpResponseStatus.BAD_REQUEST); - } - - private void addOriginAndAllowHeaders(String origin, HttpResponse res) { - - if (version != null) { - res.headers().add(HttpHeaderNames.SERVER, version); - } - - if (origin != null) { - String configOrigin = configuration.getOrigin(); - if (!isEmpty(configOrigin) && !configOrigin.contains(origin)) { - throw new IllegalArgumentException(); - } - res.headers().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, origin); - res.headers().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.TRUE); - } - - // 使websocket请求可携带特定header - String allowHeaders = configuration.getAccessControlAllowHeaders(); - // 取出现有access-control-allow-headers,去掉空格并拼接新的header到末尾。直接addHeader时IE 10/11会找不到。 - if (!isEmpty(allowHeaders)) { - String header = res.headers().get(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS); - if (!isEmpty(header)) { - header = header.trim() + SEPARATOR_COMMA + configuration.getAccessControlAllowHeaders(); - res.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, header); - } else { - res.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, configuration.getAccessControlAllowHeaders()); - } - } - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (!(msg instanceof HttpMessage)) { - super.write(ctx, msg, promise); - return; - } - - if (msg instanceof OutPacketMessage) { - OutPacketMessage m = (OutPacketMessage) msg; - if (m.getTransport() == Transport.WEBSOCKET) { - handleWebsocket((OutPacketMessage) msg, ctx, promise); - } - if (m.getTransport() == Transport.POLLING) { - handleHTTP((OutPacketMessage) msg, ctx, promise); - } - } else if (msg instanceof XHROptionsMessage) { - write((XHROptionsMessage) msg, ctx, promise); - } else if (msg instanceof XHRPostMessage) { - write((XHRPostMessage) msg, ctx, promise); - } else if (msg instanceof HttpErrorMessage) { - sendError((HttpErrorMessage) msg, ctx, promise); - } - } - - private void handleWebsocket(final OutPacketMessage msg, ChannelHandlerContext ctx, ChannelPromise promise) throws IOException { - ChannelFutureList writeFutureList = new ChannelFutureList(); - - while (true) { - Queue queue = msg.getClientHead().getPacketsQueue(msg.getTransport()); - Packet packet = queue.poll(); - if (packet == null) { - writeFutureList.setChannelPromise(promise); - break; - } - - final ByteBuf out = encoder.allocateBuffer(ctx.alloc()); - encoder.encodePacket(packet, out, ctx.alloc(), true); - - WebSocketFrame res = new TextWebSocketFrame(out); - if (log.isTraceEnabled()) { - log.trace("Out message: {} sessionId: {}", out.toString(CharsetUtil.UTF_8), msg.getSessionId()); - } - - if (out.isReadable()) { - writeFutureList.add(ctx.channel().writeAndFlush(res)); - } else { - out.release(); - } - - for (ByteBuf buf : packet.getAttachments()) { - ByteBuf outBuf = encoder.allocateBuffer(ctx.alloc()); - outBuf.writeByte(4); - outBuf.writeBytes(buf); - if (log.isTraceEnabled()) { - log.trace("Out attachment: {} sessionId: {}", ByteBufUtil.hexDump(outBuf), msg.getSessionId()); - } - writeFutureList.add(ctx.channel().writeAndFlush(new BinaryWebSocketFrame(outBuf))); - } - } - } - - private void handleHTTP(OutPacketMessage msg, ChannelHandlerContext ctx, ChannelPromise promise) throws IOException { - Channel channel = ctx.channel(); - Attribute attr = channel.attr(WRITE_ONCE); - - Queue queue = msg.getClientHead().getPacketsQueue(msg.getTransport()); - - if (!channel.isActive() || queue.isEmpty() || !attr.compareAndSet(null, true)) { - promise.trySuccess(); - return; - } - - ByteBuf out = encoder.allocateBuffer(ctx.alloc()); - Boolean b64 = ctx.channel().attr(EncoderHandler.B64).get(); - if (b64 != null && b64) { - Integer jsonpIndex = ctx.channel().attr(EncoderHandler.JSONP_INDEX).get(); - encoder.encodeJsonP(jsonpIndex, queue, out, ctx.alloc(), 50); - String type = "application/javascript"; - if (jsonpIndex == null) { - type = "text/plain"; - } - sendMessage(msg, channel, out, type, promise, HttpResponseStatus.OK); - } else { - encoder.encodePackets(queue, out, ctx.alloc(), 50); - sendMessage(msg, channel, out, "application/octet-stream", promise, HttpResponseStatus.OK); - } - } - - /** - * Helper class for the handleWebsocket method, handles a list of ChannelFutures and - * sets the status of a promise when - * - any of the operations fail - * - all of the operations succeed - * The setChannelPromise method should be called after all the futures are added - */ - private class ChannelFutureList implements GenericFutureListener> { - - private List futureList = new ArrayList(); - private ChannelPromise promise = null; - - private void cleanup() { - promise = null; - for (ChannelFuture f : futureList) f.removeListener(this); - } - - private void validate() { - boolean allSuccess = true; - for (ChannelFuture f : futureList) { - if (f.isDone()) { - if (!f.isSuccess()) { - promise.tryFailure(f.cause()); - cleanup(); - return; - } - } - else { - allSuccess = false; - } - } - if (allSuccess) { - promise.trySuccess(); - cleanup(); - } - } - - public void add(ChannelFuture f) { - futureList.add(f); - f.addListener(this); - } - - public void setChannelPromise(ChannelPromise p) { - promise = p; - validate(); - } - - @Override - public void operationComplete(Future voidFuture) throws Exception { - if (promise != null) validate(); - } - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/InPacketHandler.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/InPacketHandler.java deleted file mode 100644 index 0ad437c87..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/InPacketHandler.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.util.CharsetUtil; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.listener.ExceptionListener; -import com.fr.third.socketio.messages.PacketsMessage; -import com.fr.third.socketio.namespace.Namespace; -import com.fr.third.socketio.namespace.NamespacesHub; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketDecoder; -import com.fr.third.socketio.protocol.PacketType; -import com.fr.third.socketio.transport.NamespaceClient; - -@Sharable -public class InPacketHandler extends SimpleChannelInboundHandler { - - private static final Logger log = LoggerFactory.getLogger(InPacketHandler.class); - - private final PacketListener packetListener; - private final PacketDecoder decoder; - private final NamespacesHub namespacesHub; - private final ExceptionListener exceptionListener; - - public InPacketHandler(PacketListener packetListener, PacketDecoder decoder, NamespacesHub namespacesHub, ExceptionListener exceptionListener) { - super(); - this.packetListener = packetListener; - this.decoder = decoder; - this.namespacesHub = namespacesHub; - this.exceptionListener = exceptionListener; - } - - @Override - protected void channelRead0(io.netty.channel.ChannelHandlerContext ctx, PacketsMessage message) - throws Exception { - ByteBuf content = message.getContent(); - ClientHead client = message.getClient(); - - if (log.isTraceEnabled()) { - log.trace("In message: {} sessionId: {}", content.toString(CharsetUtil.UTF_8), client.getSessionId()); - } - while (content.isReadable()) { - try { - Packet packet = decoder.decodePackets(content, client); - if (packet.hasAttachments() && !packet.isAttachmentsLoaded()) { - return; - } - Namespace ns = namespacesHub.get(packet.getNsp()); - if (ns == null) { - if (packet.getSubType() == PacketType.CONNECT) { - Packet p = new Packet(PacketType.MESSAGE); - p.setSubType(PacketType.ERROR); - p.setNsp(packet.getNsp()); - p.setData("Invalid namespace"); - client.send(p); - return; - } - log.debug("Can't find namespace for endpoint: {}, sessionId: {} probably it was removed.", packet.getNsp(), client.getSessionId()); - return; - } - - if (packet.getSubType() == PacketType.CONNECT) { - client.addNamespaceClient(ns); - } - - NamespaceClient nClient = client.getChildClient(ns); - if (nClient == null) { - log.debug("Can't find namespace client in namespace: {}, sessionId: {} probably it was disconnected.", ns.getName(), client.getSessionId()); - return; - } - packetListener.onPacket(packet, nClient, message.getTransport()); - } catch (Exception ex) { - String c = content.toString(CharsetUtil.UTF_8); - log.error("Error during data processing. Client sessionId: " + client.getSessionId() + ", data: " + c, ex); - throw ex; - } - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception { - if (!exceptionListener.exceptionCaught(ctx, e)) { - super.exceptionCaught(ctx, e); - } - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/PacketListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/PacketListener.java deleted file mode 100644 index 7eb0099d8..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/PacketListener.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import java.util.Collections; -import java.util.List; - -import com.fr.third.socketio.AckRequest; -import com.fr.third.socketio.Transport; -import com.fr.third.socketio.ack.AckManager; -import com.fr.third.socketio.namespace.Namespace; -import com.fr.third.socketio.namespace.NamespacesHub; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketType; -import com.fr.third.socketio.scheduler.CancelableScheduler; -import com.fr.third.socketio.scheduler.SchedulerKey; -import com.fr.third.socketio.transport.NamespaceClient; -import com.fr.third.socketio.transport.PollingTransport; - -public class PacketListener { - - private final NamespacesHub namespacesHub; - private final AckManager ackManager; - private final CancelableScheduler scheduler; - - public PacketListener(AckManager ackManager, NamespacesHub namespacesHub, PollingTransport xhrPollingTransport, - CancelableScheduler scheduler) { - this.ackManager = ackManager; - this.namespacesHub = namespacesHub; - this.scheduler = scheduler; - } - - public void onPacket(Packet packet, NamespaceClient client, Transport transport) { - final AckRequest ackRequest = new AckRequest(packet, client); - - if (packet.isAckRequested()) { - ackManager.initAckIndex(client.getSessionId(), packet.getAckId()); - } - - switch (packet.getType()) { - case PING: { - Packet outPacket = new Packet(PacketType.PONG); - outPacket.setData(packet.getData()); - // TODO use future - client.getBaseClient().send(outPacket, transport); - - if ("probe".equals(packet.getData())) { - client.getBaseClient().send(new Packet(PacketType.NOOP), Transport.POLLING); - } else { - client.getBaseClient().schedulePingTimeout(); - } - Namespace namespace = namespacesHub.get(packet.getNsp()); - namespace.onPing(client); - break; - } - - case UPGRADE: { - client.getBaseClient().schedulePingTimeout(); - - SchedulerKey key = new SchedulerKey(SchedulerKey.Type.UPGRADE_TIMEOUT, client.getSessionId()); - scheduler.cancel(key); - - client.getBaseClient().upgradeCurrentTransport(transport); - break; - } - - case MESSAGE: { - client.getBaseClient().schedulePingTimeout(); - - if (packet.getSubType() == PacketType.DISCONNECT) { - client.onDisconnect(); - } - - if (packet.getSubType() == PacketType.CONNECT) { - Namespace namespace = namespacesHub.get(packet.getNsp()); - namespace.onConnect(client); - // send connect handshake packet back to client - client.getBaseClient().send(packet, transport); - } - - if (packet.getSubType() == PacketType.ACK - || packet.getSubType() == PacketType.BINARY_ACK) { - ackManager.onAck(client, packet); - } - - if (packet.getSubType() == PacketType.EVENT - || packet.getSubType() == PacketType.BINARY_EVENT) { - Namespace namespace = namespacesHub.get(packet.getNsp()); - List args = Collections.emptyList(); - if (packet.getData() != null) { - args = packet.getData(); - } - namespace.onEvent(client, packet.getName(), args, ackRequest); - } - break; - } - - case CLOSE: - client.getBaseClient().onChannelDisconnect(); - break; - - default: - break; - } - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/SocketIOException.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/SocketIOException.java deleted file mode 100644 index 78bd1da2b..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/SocketIOException.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -public class SocketIOException extends RuntimeException { - - private static final long serialVersionUID = -9218908839842557188L; - - public SocketIOException(String message, Throwable cause) { - super(message, cause); - } - - public SocketIOException(String message) { - super(message); - } - - public SocketIOException(Throwable cause) { - super(cause); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/SuccessAuthorizationListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/SuccessAuthorizationListener.java deleted file mode 100644 index 44683d8c4..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/SuccessAuthorizationListener.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import com.fr.third.socketio.AuthorizationListener; -import com.fr.third.socketio.HandshakeData; - -public class SuccessAuthorizationListener implements AuthorizationListener { - - @Override - public boolean isAuthorized(HandshakeData data) { - return true; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/TransportState.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/TransportState.java deleted file mode 100644 index c26607138..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/TransportState.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -import com.fr.third.socketio.protocol.Packet; - -import io.netty.channel.Channel; - -public class TransportState { - - private Queue packetsQueue = new ConcurrentLinkedQueue(); - private Channel channel; - - public void setPacketsQueue(Queue packetsQueue) { - this.packetsQueue = packetsQueue; - } - - public Queue getPacketsQueue() { - return packetsQueue; - } - - public Channel getChannel() { - return channel; - } - - public Channel update(Channel channel) { - Channel prevChannel = this.channel; - this.channel = channel; - return prevChannel; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/handler/WrongUrlHandler.java b/fine-socketio/src/main/java/com/fr/third/socketio/handler/WrongUrlHandler.java deleted file mode 100644 index 2906a886e..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/handler/WrongUrlHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.handler; - -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.QueryStringDecoder; - -@Sharable -public class WrongUrlHandler extends ChannelInboundHandlerAdapter { - - private static final Logger log = LoggerFactory.getLogger(WrongUrlHandler.class); - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof FullHttpRequest) { - FullHttpRequest req = (FullHttpRequest) msg; - Channel channel = ctx.channel(); - QueryStringDecoder queryDecoder = new QueryStringDecoder(req.uri()); - - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.BAD_REQUEST); - ChannelFuture f = channel.writeAndFlush(res); - f.addListener(ChannelFutureListener.CLOSE); - req.release(); - log.warn("Blocked wrong socket.io-context request! url: {}, params: {}, ip: {}", queryDecoder.path(), queryDecoder.parameters(), channel.remoteAddress()); - return; - } - super.channelRead(ctx, msg); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/ClientListeners.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/ClientListeners.java deleted file mode 100644 index ffeb16f69..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/ClientListeners.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -public interface ClientListeners { - - void addMultiTypeEventListener(String eventName, MultiTypeEventListener listener, Class ... eventClass); - - void addEventListener(String eventName, Class eventClass, DataListener listener); - - void addDisconnectListener(DisconnectListener listener); - - void addConnectListener(ConnectListener listener); - - void addPingListener(PingListener listener); - - void addListeners(Object listeners); - - void addListeners(Object listeners, Class listenersClass); - - void removeAllListeners(String eventName); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/ConnectListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/ConnectListener.java deleted file mode 100644 index ba83eba58..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/ConnectListener.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -import com.fr.third.socketio.SocketIOClient; - -public interface ConnectListener { - - void onConnect(SocketIOClient client); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/DataListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/DataListener.java deleted file mode 100644 index cd5b6e2a9..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/DataListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -import com.fr.third.socketio.AckRequest; -import com.fr.third.socketio.SocketIOClient; - -public interface DataListener { - - /** - * Invokes when data object received from client - * - * @param client - receiver - * @param data - received object - * @param ackSender - ack request - * - */ - void onData(SocketIOClient client, T data, AckRequest ackSender) throws Exception; - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/DefaultExceptionListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/DefaultExceptionListener.java deleted file mode 100644 index 0b94c8fc1..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/DefaultExceptionListener.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -import io.netty.channel.ChannelHandlerContext; - -import java.util.List; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.SocketIOClient; - -public class DefaultExceptionListener extends ExceptionListenerAdapter { - - private static final Logger log = LoggerFactory.getLogger(DefaultExceptionListener.class); - - @Override - public void onEventException(Exception e, List args, SocketIOClient client) { - log.error(e.getMessage(), e); - } - - @Override - public void onDisconnectException(Exception e, SocketIOClient client) { - log.error(e.getMessage(), e); - } - - @Override - public void onConnectException(Exception e, SocketIOClient client) { - log.error(e.getMessage(), e); - } - - @Override - public void onPingException(Exception e, SocketIOClient client) { - log.error(e.getMessage(), e); - } - - @Override - public boolean exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception { - log.error(e.getMessage(), e); - return true; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/DisconnectListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/DisconnectListener.java deleted file mode 100644 index f73798f21..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/DisconnectListener.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -import com.fr.third.socketio.SocketIOClient; - -public interface DisconnectListener { - - void onDisconnect(SocketIOClient client); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/ExceptionListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/ExceptionListener.java deleted file mode 100644 index f0e65a459..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/ExceptionListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -import io.netty.channel.ChannelHandlerContext; - -import java.util.List; - -import com.fr.third.socketio.SocketIOClient; - -public interface ExceptionListener { - - void onEventException(Exception e, List args, SocketIOClient client); - - void onDisconnectException(Exception e, SocketIOClient client); - - void onConnectException(Exception e, SocketIOClient client); - - void onPingException(Exception e, SocketIOClient client); - - boolean exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception; - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/ExceptionListenerAdapter.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/ExceptionListenerAdapter.java deleted file mode 100644 index dbf07edf7..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/ExceptionListenerAdapter.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -import io.netty.channel.ChannelHandlerContext; - -import java.util.List; - -import com.fr.third.socketio.SocketIOClient; - -/** - * Base callback exceptions listener - * - * - */ -public abstract class ExceptionListenerAdapter implements ExceptionListener { - - @Override - public void onEventException(Exception e, List data, SocketIOClient client) { - } - - @Override - public void onDisconnectException(Exception e, SocketIOClient client) { - } - - @Override - public void onConnectException(Exception e, SocketIOClient client) { - } - - @Override - public boolean exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception { - return false; - } - - @Override - public void onPingException(Exception e, SocketIOClient client) { - - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/MultiTypeEventListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/MultiTypeEventListener.java deleted file mode 100644 index d750f70ac..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/MultiTypeEventListener.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -import com.fr.third.socketio.MultiTypeArgs; - -/** - * Multi type args event listener - * - */ -public interface MultiTypeEventListener extends DataListener { - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/PingListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/PingListener.java deleted file mode 100644 index c9f33d6b5..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/PingListener.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.listener; - -import com.fr.third.socketio.SocketIOClient; - -public interface PingListener { - - void onPing(SocketIOClient client); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/interceptor/EventInterceptor.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/interceptor/EventInterceptor.java deleted file mode 100644 index 4970b0ea8..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/interceptor/EventInterceptor.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.fr.third.socketio.listener.interceptor; - -import com.fr.third.socketio.AckRequest; -import com.fr.third.socketio.SocketIOClient; - -import java.util.List; - -/** - * Desc - * - * @author Elijah - * created on 2021-04-26 - */ -public interface EventInterceptor extends Interceptor { - default void before(SocketIOClient client, List params, AckRequest ackRequest){ - before(client); - } - - default void after(SocketIOClient client, List params, AckRequest ackRequest){ - after(client); - } - - default boolean accept(String eventName, SocketIOClient client, List param){ - return accept(client); - } - -} \ No newline at end of file diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/listener/interceptor/Interceptor.java b/fine-socketio/src/main/java/com/fr/third/socketio/listener/interceptor/Interceptor.java deleted file mode 100644 index 501a9825f..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/listener/interceptor/Interceptor.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.fr.third.socketio.listener.interceptor; - -import com.fr.third.socketio.SocketIOClient; - -/** - * Desc - * - * @author Elijah - * created on 2021-05-06 - */ -public interface Interceptor { - default void before(SocketIOClient client){ - - } - - default void after(SocketIOClient client){ - - } - - default boolean accept(SocketIOClient client){ - return true; - } -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/messages/HttpErrorMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/messages/HttpErrorMessage.java deleted file mode 100644 index 7be5e8639..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/messages/HttpErrorMessage.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.messages; - -import java.util.Map; - -public class HttpErrorMessage extends HttpMessage { - - private final Map data; - - public HttpErrorMessage(Map data) { - super(null, null); - this.data = data; - } - - public Map getData() { - return data; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/messages/HttpMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/messages/HttpMessage.java deleted file mode 100644 index 5c9858e40..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/messages/HttpMessage.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.messages; - -import java.util.UUID; - -public abstract class HttpMessage { - - private final String origin; - private final UUID sessionId; - - public HttpMessage(String origin, UUID sessionId) { - this.origin = origin; - this.sessionId = sessionId; - } - - public String getOrigin() { - return origin; - } - - public UUID getSessionId() { - return sessionId; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/messages/OutPacketMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/messages/OutPacketMessage.java deleted file mode 100644 index 363cf55a1..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/messages/OutPacketMessage.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.messages; - -import com.fr.third.socketio.Transport; -import com.fr.third.socketio.handler.ClientHead; - -public class OutPacketMessage extends HttpMessage { - - private final ClientHead clientHead; - private final Transport transport; - - public OutPacketMessage(ClientHead clientHead, Transport transport) { - super(clientHead.getOrigin(), clientHead.getSessionId()); - - this.clientHead = clientHead; - this.transport = transport; - } - - public Transport getTransport() { - return transport; - } - - public ClientHead getClientHead() { - return clientHead; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/messages/PacketsMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/messages/PacketsMessage.java deleted file mode 100644 index 7a98e6211..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/messages/PacketsMessage.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.messages; - -import io.netty.buffer.ByteBuf; - -import com.fr.third.socketio.Transport; -import com.fr.third.socketio.handler.ClientHead; - -public class PacketsMessage { - - private final ClientHead client; - private final ByteBuf content; - private final Transport transport; - - public PacketsMessage(ClientHead client, ByteBuf content, Transport transport) { - this.client = client; - this.content = content; - this.transport = transport; - } - - public Transport getTransport() { - return transport; - } - - public ClientHead getClient() { - return client; - } - - public ByteBuf getContent() { - return content; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/messages/XHROptionsMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/messages/XHROptionsMessage.java deleted file mode 100644 index bacc716bb..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/messages/XHROptionsMessage.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.messages; - -import java.util.UUID; - -public class XHROptionsMessage extends XHRPostMessage { - - public XHROptionsMessage(String origin, UUID sessionId) { - super(origin, sessionId); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/messages/XHRPostMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/messages/XHRPostMessage.java deleted file mode 100644 index 54e5129bb..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/messages/XHRPostMessage.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.messages; - -import java.util.UUID; - -public class XHRPostMessage extends HttpMessage { - - public XHRPostMessage(String origin, UUID sessionId) { - super(origin, sessionId); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/misc/CompositeIterable.java b/fine-socketio/src/main/java/com/fr/third/socketio/misc/CompositeIterable.java deleted file mode 100644 index 76fedc7a3..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/misc/CompositeIterable.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.misc; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class CompositeIterable implements Iterable { - - private List> iterablesList; - private Iterable[] iterables; - - public CompositeIterable(List> iterables) { - this.iterablesList = iterables; - } - - public CompositeIterable(Iterable ... iterables) { - this.iterables = iterables; - } - - public CompositeIterable(CompositeIterable iterable) { - this.iterables = iterable.iterables; - this.iterablesList = iterable.iterablesList; - } - - @Override - public Iterator iterator() { - List> iterators = new ArrayList>(); - if (iterables != null) { - for (Iterable iterable : iterables) { - iterators.add(iterable.iterator()); - } - } else { - for (Iterable iterable : iterablesList) { - iterators.add(iterable.iterator()); - } - } - return new CompositeIterator(iterators.iterator()); - } - - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/misc/CompositeIterator.java b/fine-socketio/src/main/java/com/fr/third/socketio/misc/CompositeIterator.java deleted file mode 100644 index f891c2670..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/misc/CompositeIterator.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.misc; - -import java.util.Iterator; - -public class CompositeIterator implements Iterator { - - private Iterator> listIterator; - private Iterator currentIterator; - - public CompositeIterator(Iterator> listIterator) { - this.currentIterator = null; - this.listIterator = listIterator; - } - - @Override - public boolean hasNext() { - if (currentIterator == null || !currentIterator.hasNext()) { - while (listIterator.hasNext()) { - Iterator iterator = listIterator.next(); - if (iterator.hasNext()) { - currentIterator = iterator; - return true; - } - } - return false; - } - return currentIterator.hasNext(); - } - - @Override - public T next() { - hasNext(); - return currentIterator.next(); - } - - @Override - public void remove() { - currentIterator.remove(); - } -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/misc/IterableCollection.java b/fine-socketio/src/main/java/com/fr/third/socketio/misc/IterableCollection.java deleted file mode 100644 index ef65dabc5..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/misc/IterableCollection.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.misc; - -import java.util.AbstractCollection; -import java.util.Iterator; - -public class IterableCollection extends AbstractCollection { - - private final CompositeIterable iterable; - - public IterableCollection(Iterable iterable) { - this(new CompositeIterable(iterable)); - } - - public IterableCollection(CompositeIterable iterable) { - this.iterable = iterable; - } - - @Override - public Iterator iterator() { - return new CompositeIterable(iterable).iterator(); - } - - @Override - public int size() { - Iterator iterator = new CompositeIterable(iterable).iterator(); - int count = 0; - while (iterator.hasNext()) { - iterator.next(); - count++; - } - return count; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/namespace/EventEntry.java b/fine-socketio/src/main/java/com/fr/third/socketio/namespace/EventEntry.java deleted file mode 100644 index ba9e8dcf3..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/namespace/EventEntry.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.namespace; - -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -import com.fr.third.socketio.listener.DataListener; - -public class EventEntry { - - private final Queue> listeners = new ConcurrentLinkedQueue>();; - - public EventEntry() { - super(); - } - - public void addListener(DataListener listener) { - listeners.add(listener); - } - - public Queue> getListeners() { - return listeners; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/namespace/Namespace.java b/fine-socketio/src/main/java/com/fr/third/socketio/namespace/Namespace.java deleted file mode 100644 index a8fa9b5f0..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/namespace/Namespace.java +++ /dev/null @@ -1,431 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.namespace; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; - -import com.fr.third.socketio.AckMode; -import com.fr.third.socketio.AckRequest; -import com.fr.third.socketio.BroadcastOperations; -import com.fr.third.socketio.Configuration; -import com.fr.third.socketio.MultiTypeArgs; -import com.fr.third.socketio.SingleRoomBroadcastOperations; -import com.fr.third.socketio.SocketIOClient; -import com.fr.third.socketio.SocketIONamespace; -import com.fr.third.socketio.annotation.ScannerEngine; -import com.fr.third.socketio.listener.interceptor.EventInterceptor; -import com.fr.third.socketio.listener.interceptor.Interceptor; -import com.fr.third.socketio.protocol.JsonSupport; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.store.StoreFactory; -import com.fr.third.socketio.store.pubsub.JoinLeaveMessage; -import com.fr.third.socketio.store.pubsub.PubSubType; -import com.fr.third.socketio.transport.NamespaceClient; - -import com.fr.third.socketio.listener.ConnectListener; -import com.fr.third.socketio.listener.DataListener; -import com.fr.third.socketio.listener.DisconnectListener; -import com.fr.third.socketio.listener.ExceptionListener; -import com.fr.third.socketio.listener.MultiTypeEventListener; -import com.fr.third.socketio.listener.PingListener; -import io.netty.util.internal.PlatformDependent; - -/** - * Hub object for all clients in one namespace. - * Namespace shares by different namespace-clients. - * - * @see NamespaceClient - */ -public class Namespace implements SocketIONamespace { - - public static final String DEFAULT_NAME = ""; - - private final ScannerEngine engine = new ScannerEngine(); - private final ConcurrentMap> eventListeners = PlatformDependent.newConcurrentHashMap(); - private final Queue connectListeners = new ConcurrentLinkedQueue(); - private final Queue disconnectListeners = new ConcurrentLinkedQueue(); - private final Queue pingListeners = new ConcurrentLinkedQueue(); - - private final Map allClients = PlatformDependent.newConcurrentHashMap(); - private final ConcurrentMap> roomClients = PlatformDependent.newConcurrentHashMap(); - private final ConcurrentMap> clientRooms = PlatformDependent.newConcurrentHashMap(); - - private final String name; - private final AckMode ackMode; - private final JsonSupport jsonSupport; - private final StoreFactory storeFactory; - private final ExceptionListener exceptionListener; - private final Configuration configuration; - - public Namespace(String name, Configuration configuration) { - super(); - this.name = name; - this.jsonSupport = configuration.getJsonSupport(); - this.storeFactory = configuration.getStoreFactory(); - this.exceptionListener = configuration.getExceptionListener(); - this.ackMode = configuration.getAckMode(); - this.configuration = configuration; - } - - public void addClient(SocketIOClient client) { - allClients.put(client.getSessionId(), client); - } - - @Override - public String getName() { - return name; - } - - @Override - public void addMultiTypeEventListener(String eventName, MultiTypeEventListener listener, - Class... eventClass) { - EventEntry entry = eventListeners.get(eventName); - if (entry == null) { - entry = new EventEntry(); - EventEntry oldEntry = eventListeners.putIfAbsent(eventName, entry); - if (oldEntry != null) { - entry = oldEntry; - } - } - entry.addListener(listener); - jsonSupport.addEventMapping(name, eventName, eventClass); - } - - @Override - public void removeAllListeners(String eventName) { - EventEntry entry = eventListeners.remove(eventName); - if (entry != null) { - jsonSupport.removeEventMapping(name, eventName); - } - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) - public void addEventListener(String eventName, Class eventClass, DataListener listener) { - EventEntry entry = eventListeners.get(eventName); - if (entry == null) { - entry = new EventEntry(); - EventEntry oldEntry = eventListeners.putIfAbsent(eventName, entry); - if (oldEntry != null) { - entry = oldEntry; - } - } - entry.addListener(listener); - jsonSupport.addEventMapping(name, eventName, eventClass); - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - public void onEvent(NamespaceClient client, String eventName, List args, AckRequest ackRequest) { - EventEntry entry = eventListeners.get(eventName); - if (entry == null) { - return; - } - for (EventInterceptor eventInterceptor: configuration.getEventInterceptors()) { - try { - //不影响后续执行 - if (eventInterceptor.accept(eventName, client, args)) { - eventInterceptor.before(client, args, ackRequest); - } - } catch (Exception e) { - exceptionListener.onEventException(e, args, client); - } - } - try { - Queue listeners = entry.getListeners(); - for (DataListener dataListener : listeners) { - Object data = getEventData(args, dataListener); - dataListener.onData(client, data, ackRequest); - } - } catch (Exception e) { - exceptionListener.onEventException(e, args, client); - if (ackMode == AckMode.AUTO_SUCCESS_ONLY) { - return; - } - } finally { - for (EventInterceptor eventInterceptor: configuration.getEventInterceptors()) { - try { - //不影响后续执行 - if (eventInterceptor.accept(eventName, client, args)) { - eventInterceptor.after(client, args, ackRequest); - } - } catch (Exception e) { - exceptionListener.onEventException(e, args, client); - } - } - } - - sendAck(ackRequest); - } - - private void sendAck(AckRequest ackRequest) { - if (ackMode == AckMode.AUTO || ackMode == AckMode.AUTO_SUCCESS_ONLY) { - // send ack response if it not executed - // during {@link DataListener#onData} invocation - ackRequest.sendAckData(Collections.emptyList()); - } - } - - private Object getEventData(List args, DataListener dataListener) { - if (dataListener instanceof MultiTypeEventListener) { - return new MultiTypeArgs(args); - } else { - if (!args.isEmpty()) { - return args.get(0); - } - } - return null; - } - - @Override - public void addDisconnectListener(DisconnectListener listener) { - disconnectListeners.add(listener); - } - - public void onDisconnect(SocketIOClient client) { - Set joinedRooms = client.getAllRooms(); - allClients.remove(client.getSessionId()); - - // client must leave all rooms and publish the leave msg one by one on disconnect. - for (String joinedRoom : joinedRooms) { - leave(roomClients, joinedRoom, client.getSessionId()); - storeFactory.pubSubStore().publish(PubSubType.LEAVE, new JoinLeaveMessage(client.getSessionId(), joinedRoom, getName())); - } - clientRooms.remove(client.getSessionId()); - - callInterceptor(client, false, true); - try { - for (DisconnectListener listener : disconnectListeners) { - listener.onDisconnect(client); - } - } catch (Exception e) { - exceptionListener.onDisconnectException(e, client); - } finally { - callInterceptor(client, false, false); - } - } - - @Override - public void addConnectListener(ConnectListener listener) { - connectListeners.add(listener); - } - - public void onConnect(SocketIOClient client) { - join(getName(), client.getSessionId()); - storeFactory.pubSubStore().publish(PubSubType.JOIN, new JoinLeaveMessage(client.getSessionId(), getName(), getName())); - - callInterceptor(client, true, true); - try { - for (ConnectListener listener : connectListeners) { - listener.onConnect(client); - } - } catch (Exception e) { - exceptionListener.onConnectException(e, client); - } finally { - callInterceptor(client, true, false); - } - } - - private void callInterceptor(SocketIOClient client, boolean connect, boolean before) { - List interceptors = connect ? configuration.getConnectInterceptors() : configuration.getDisconnectInterceptors(); - for (Interceptor interceptor: interceptors) { - try{ - if (interceptor.accept(client)) { - if (before) { - interceptor.before(client); - } else { - interceptor.after(client); - } - } - } catch (Exception e) { - if (connect) { - exceptionListener.onConnectException(e, client); - } else { - exceptionListener.onDisconnectException(e, client); - } - } - - } - } - @Override - public void addPingListener(PingListener listener) { - pingListeners.add(listener); - } - - public void onPing(SocketIOClient client) { - try { - for (PingListener listener : pingListeners) { - listener.onPing(client); - } - } catch (Exception e) { - exceptionListener.onPingException(e, client); - } - } - - @Override - public BroadcastOperations getBroadcastOperations() { - return new SingleRoomBroadcastOperations(getName(), getName(), allClients.values(), storeFactory); - } - - @Override - public BroadcastOperations getRoomOperations(String room) { - return new SingleRoomBroadcastOperations(getName(), room, getRoomClients(room), storeFactory); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Namespace other = (Namespace) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } - - @Override - public void addListeners(Object listeners) { - addListeners(listeners, listeners.getClass()); - } - - @Override - public void addListeners(Object listeners, Class listenersClass) { - engine.scan(this, listeners, listenersClass); - } - - public void joinRoom(String room, UUID sessionId) { - join(room, sessionId); - storeFactory.pubSubStore().publish(PubSubType.JOIN, new JoinLeaveMessage(sessionId, room, getName())); - } - - public void dispatch(String room, Packet packet) { - Iterable clients = getRoomClients(room); - - for (SocketIOClient socketIOClient : clients) { - socketIOClient.send(packet); - } - } - - private void join(ConcurrentMap> map, K key, V value) { - Set clients = map.get(key); - if (clients == null) { - clients = Collections.newSetFromMap(PlatformDependent.newConcurrentHashMap()); - Set oldClients = map.putIfAbsent(key, clients); - if (oldClients != null) { - clients = oldClients; - } - } - clients.add(value); - // object may be changed due to other concurrent call - if (clients != map.get(key)) { - // re-join if queue has been replaced - join(map, key, value); - } - } - - public void join(String room, UUID sessionId) { - join(roomClients, room, sessionId); - join(clientRooms, sessionId, room); - } - - public void leaveRoom(String room, UUID sessionId) { - leave(room, sessionId); - storeFactory.pubSubStore().publish(PubSubType.LEAVE, new JoinLeaveMessage(sessionId, room, getName())); - } - - private void leave(ConcurrentMap> map, K room, V sessionId) { - Set clients = map.get(room); - if (clients == null) { - return; - } - clients.remove(sessionId); - - if (clients.isEmpty()) { - map.remove(room, Collections.emptySet()); - } - } - - public void leave(String room, UUID sessionId) { - leave(roomClients, room, sessionId); - leave(clientRooms, sessionId, room); - } - - public Set getRooms(SocketIOClient client) { - Set res = clientRooms.get(client.getSessionId()); - if (res == null) { - return Collections.emptySet(); - } - return Collections.unmodifiableSet(res); - } - - public Set getRooms() { - return roomClients.keySet(); - } - - public Iterable getRoomClients(String room) { - Set sessionIds = roomClients.get(room); - - if (sessionIds == null) { - return Collections.emptyList(); - } - - List result = new ArrayList(); - for (UUID sessionId : sessionIds) { - SocketIOClient client = allClients.get(sessionId); - if(client != null) { - result.add(client); - } - } - return result; - } - - @Override - public Collection getAllClients() { - return Collections.unmodifiableCollection(allClients.values()); - } - - public JsonSupport getJsonSupport() { - return jsonSupport; - } - - @Override - public SocketIOClient getClient(UUID uuid) { - return allClients.get(uuid); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/namespace/NamespacesHub.java b/fine-socketio/src/main/java/com/fr/third/socketio/namespace/NamespacesHub.java deleted file mode 100644 index 6ba5b5ed3..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/namespace/NamespacesHub.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.namespace; - -import io.netty.util.internal.PlatformDependent; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ConcurrentMap; - -import com.fr.third.socketio.Configuration; -import com.fr.third.socketio.SocketIOClient; -import com.fr.third.socketio.SocketIONamespace; -import com.fr.third.socketio.misc.CompositeIterable; - -public class NamespacesHub { - - private final ConcurrentMap namespaces = PlatformDependent.newConcurrentHashMap(); - private final Configuration configuration; - - public NamespacesHub(Configuration configuration) { - this.configuration = configuration; - } - - public Namespace create(String name) { - Namespace namespace = (Namespace) namespaces.get(name); - if (namespace == null) { - namespace = new Namespace(name, configuration); - Namespace oldNamespace = (Namespace) namespaces.putIfAbsent(name, namespace); - if (oldNamespace != null) { - namespace = oldNamespace; - } - } - return namespace; - } - - public Iterable getRoomClients(String room) { - List> allClients = new ArrayList>(); - for (SocketIONamespace namespace : namespaces.values()) { - Iterable clients = ((Namespace)namespace).getRoomClients(room); - allClients.add(clients); - } - return new CompositeIterable(allClients); - } - - public Namespace get(String name) { - return (Namespace) namespaces.get(name); - } - - public void remove(String name) { - SocketIONamespace namespace = namespaces.remove(name); - if (namespace != null) { - namespace.getBroadcastOperations().disconnect(); - } - } - - public Collection getAllNamespaces() { - return namespaces.values(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/AckArgs.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/AckArgs.java deleted file mode 100644 index e04542821..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/AckArgs.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import java.util.List; - -public class AckArgs { - - private List args; - - public AckArgs(List args) { - super(); - this.args = args; - } - - public List getArgs() { - return args; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/AuthPacket.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/AuthPacket.java deleted file mode 100644 index 5192ee43d..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/AuthPacket.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import java.util.UUID; - - -public class AuthPacket { - - private final UUID sid; - private final String[] upgrades; - private final int pingInterval; - private final int pingTimeout; - - public AuthPacket(UUID sid, String[] upgrades, int pingInterval, int pingTimeout) { - super(); - this.sid = sid; - this.upgrades = upgrades; - this.pingInterval = pingInterval; - this.pingTimeout = pingTimeout; - } - - public int getPingInterval() { - return pingInterval; - } - - public int getPingTimeout() { - return pingTimeout; - } - - public UUID getSid() { - return sid; - } - - public String[] getUpgrades() { - return upgrades; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/Event.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/Event.java deleted file mode 100644 index 7a2ba2adf..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/Event.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import java.util.List; - -public class Event { - - private String name; - private List args; - - public Event() { - } - - public Event(String name, List args) { - super(); - this.name = name; - this.args = args; - } - - public List getArgs() { - return args; - } - - public String getName() { - return name; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/JacksonJsonSupport.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/JacksonJsonSupport.java deleted file mode 100644 index f4be84adf..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/JacksonJsonSupport.java +++ /dev/null @@ -1,366 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.AckCallback; -import com.fr.third.socketio.MultiTypeAckCallback; -import com.fr.third.socketio.namespace.Namespace; -import com.fr.third.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fr.third.fasterxml.jackson.core.JsonGenerationException; -import com.fr.third.fasterxml.jackson.core.JsonGenerator; -import com.fr.third.fasterxml.jackson.core.JsonParser; -import com.fr.third.fasterxml.jackson.core.JsonProcessingException; -import com.fr.third.fasterxml.jackson.core.JsonToken; -import com.fr.third.fasterxml.jackson.databind.BeanDescription; -import com.fr.third.fasterxml.jackson.databind.DeserializationContext; -import com.fr.third.fasterxml.jackson.databind.DeserializationFeature; -import com.fr.third.fasterxml.jackson.databind.JavaType; -import com.fr.third.fasterxml.jackson.databind.JsonMappingException; -import com.fr.third.fasterxml.jackson.databind.JsonNode; -import com.fr.third.fasterxml.jackson.databind.JsonSerializer; -import com.fr.third.fasterxml.jackson.databind.Module; -import com.fr.third.fasterxml.jackson.databind.ObjectMapper; -import com.fr.third.fasterxml.jackson.databind.SerializationConfig; -import com.fr.third.fasterxml.jackson.databind.SerializationFeature; -import com.fr.third.fasterxml.jackson.databind.SerializerProvider; -import com.fr.third.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fr.third.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor; -import com.fr.third.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; -import com.fr.third.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; -import com.fr.third.fasterxml.jackson.databind.jsontype.TypeSerializer; -import com.fr.third.fasterxml.jackson.databind.module.SimpleModule; -import com.fr.third.fasterxml.jackson.databind.node.ObjectNode; -import com.fr.third.fasterxml.jackson.databind.ser.BeanSerializerModifier; -import com.fr.third.fasterxml.jackson.databind.ser.std.StdSerializer; -import com.fr.third.fasterxml.jackson.databind.type.ArrayType; - -import io.netty.buffer.ByteBufInputStream; -import io.netty.buffer.ByteBufOutputStream; -import io.netty.util.internal.PlatformDependent; - -public class JacksonJsonSupport implements JsonSupport { - - private class AckArgsDeserializer extends StdDeserializer { - - private static final long serialVersionUID = 7810461017389946707L; - - protected AckArgsDeserializer() { - super(AckArgs.class); - } - - @Override - public AckArgs deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, - JsonProcessingException { - List args = new ArrayList(); - AckArgs result = new AckArgs(args); - - ObjectMapper mapper = (ObjectMapper) jp.getCodec(); - JsonNode root = mapper.readTree(jp); - AckCallback callback = currentAckClass.get(); - Iterator iter = root.iterator(); - int i = 0; - while (iter.hasNext()) { - Object val; - - Class clazz = callback.getResultClass(); - if (callback instanceof MultiTypeAckCallback) { - MultiTypeAckCallback multiTypeAckCallback = (MultiTypeAckCallback) callback; - clazz = multiTypeAckCallback.getResultClasses()[i]; - } - - JsonNode arg = iter.next(); - if (arg.isTextual() || arg.isBoolean()) { - clazz = Object.class; - } - - val = mapper.treeToValue(arg, clazz); - args.add(val); - i++; - } - return result; - } - - } - - public static class EventKey { - - private String namespaceName; - private String eventName; - - public EventKey(String namespaceName, String eventName) { - super(); - this.namespaceName = namespaceName; - this.eventName = eventName; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((eventName == null) ? 0 : eventName.hashCode()); - result = prime * result + ((namespaceName == null) ? 0 : namespaceName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - EventKey other = (EventKey) obj; - if (eventName == null) { - if (other.eventName != null) - return false; - } else if (!eventName.equals(other.eventName)) - return false; - if (namespaceName == null) { - if (other.namespaceName != null) - return false; - } else if (!namespaceName.equals(other.namespaceName)) - return false; - return true; - } - - } - - private class EventDeserializer extends StdDeserializer { - - private static final long serialVersionUID = 8178797221017768689L; - - final Map>> eventMapping = PlatformDependent.newConcurrentHashMap(); - - - protected EventDeserializer() { - super(Event.class); - } - - @Override - public Event deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, - JsonProcessingException { - ObjectMapper mapper = (ObjectMapper) jp.getCodec(); - String eventName = jp.nextTextValue(); - - EventKey ek = new EventKey(namespaceClass.get(), eventName); - if (!eventMapping.containsKey(ek)) { - ek = new EventKey(Namespace.DEFAULT_NAME, eventName); - if (!eventMapping.containsKey(ek)) { - return new Event(eventName, Collections.emptyList()); - } - } - - List eventArgs = new ArrayList(); - Event event = new Event(eventName, eventArgs); - List> eventClasses = eventMapping.get(ek); - int i = 0; - while (true) { - JsonToken token = jp.nextToken(); - if (token == JsonToken.END_ARRAY) { - break; - } - if (i > eventClasses.size() - 1) { - log.debug("Event {} has more args than declared in handler: {}", eventName, null); - break; - } - Class eventClass = eventClasses.get(i); - Object arg = mapper.readValue(jp, eventClass); - eventArgs.add(arg); - i++; - } - return event; - } - - } - - public static class ByteArraySerializer extends StdSerializer - { - - private static final long serialVersionUID = 3420082888596468148L; - - private final ThreadLocal> arrays = new ThreadLocal>() { - @Override - protected List initialValue() { - return new ArrayList(); - }; - }; - - public ByteArraySerializer() { - super(byte[].class); - } - - @Override - public boolean isEmpty(byte[] value) { - return (value == null) || (value.length == 0); - } - - @Override - public void serialize(byte[] value, JsonGenerator jgen, SerializerProvider provider) - throws IOException, JsonGenerationException - { - Map map = new HashMap(); - map.put("num", arrays.get().size()); - map.put("_placeholder", true); - jgen.writeObject(map); - arrays.get().add(value); - } - - @Override - public void serializeWithType(byte[] value, JsonGenerator jgen, SerializerProvider provider, - TypeSerializer typeSer) - throws IOException, JsonGenerationException - { - serialize(value, jgen, provider); - } - - @Override - public JsonNode getSchema(SerializerProvider provider, Type typeHint) - { - ObjectNode o = createSchemaNode("array", true); - ObjectNode itemSchema = createSchemaNode("string"); //binary values written as strings? - return o.set("items", itemSchema); - } - - @Override - public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) - throws JsonMappingException - { - if (visitor != null) { - JsonArrayFormatVisitor v2 = visitor.expectArrayFormat(typeHint); - if (v2 != null) { - v2.itemsFormat(JsonFormatTypes.STRING); - } - } - } - - public List getArrays() { - return arrays.get(); - } - - public void clear() { - arrays.set(new ArrayList()); - } - - } - - - private class ExBeanSerializerModifier extends BeanSerializerModifier { - - private final ByteArraySerializer serializer = new ByteArraySerializer(); - - @Override - public JsonSerializer modifyArraySerializer(SerializationConfig config, ArrayType valueType, - BeanDescription beanDesc, JsonSerializer serializer) { - if (valueType.getRawClass().equals(byte[].class)) { - return this.serializer; - } - - return super.modifyArraySerializer(config, valueType, beanDesc, serializer); - } - - public ByteArraySerializer getSerializer() { - return serializer; - } - - } - - protected final ExBeanSerializerModifier modifier = new ExBeanSerializerModifier(); - protected final ThreadLocal namespaceClass = new ThreadLocal(); - protected final ThreadLocal> currentAckClass = new ThreadLocal>(); - protected final ObjectMapper objectMapper = new ObjectMapper(); - protected final EventDeserializer eventDeserializer = new EventDeserializer(); - protected final AckArgsDeserializer ackArgsDeserializer = new AckArgsDeserializer(); - - protected static final Logger log = LoggerFactory.getLogger(JacksonJsonSupport.class); - - public JacksonJsonSupport() { - this(new Module[] {}); - } - - public JacksonJsonSupport(Module... modules) { - if (modules != null && modules.length > 0) { - objectMapper.registerModules(modules); - } - init(objectMapper); - } - - protected void init(ObjectMapper objectMapper) { - SimpleModule module = new SimpleModule(); - module.setSerializerModifier(modifier); - module.addDeserializer(Event.class, eventDeserializer); - module.addDeserializer(AckArgs.class, ackArgsDeserializer); - objectMapper.registerModule(module); - - objectMapper.setSerializationInclusion(Include.NON_NULL); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - objectMapper.configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN, true); - objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - - //时区设置,防止含有Data类型变量时序列化后,前台显示的data内时间不准确 - objectMapper.setTimeZone(TimeZone.getDefault()); - } - - @Override - public void addEventMapping(String namespaceName, String eventName, Class ... eventClass) { - eventDeserializer.eventMapping.put(new EventKey(namespaceName, eventName), Arrays.asList(eventClass)); - } - - @Override - public void removeEventMapping(String namespaceName, String eventName) { - eventDeserializer.eventMapping.remove(new EventKey(namespaceName, eventName)); - } - - @Override - public T readValue(String namespaceName, ByteBufInputStream src, Class valueType) throws IOException { - namespaceClass.set(namespaceName); - return objectMapper.readValue((InputStream)src, valueType); - } - - @Override - public AckArgs readAckArgs(ByteBufInputStream src, AckCallback callback) throws IOException { - currentAckClass.set(callback); - return objectMapper.readValue((InputStream)src, AckArgs.class); - } - - @Override - public void writeValue(ByteBufOutputStream out, Object value) throws IOException { - modifier.getSerializer().clear(); - objectMapper.writeValue((OutputStream)out, value); - } - - @Override - public List getArrays() { - return modifier.getSerializer().getArrays(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/JsonSupport.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/JsonSupport.java deleted file mode 100644 index bc72326bc..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/JsonSupport.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import io.netty.buffer.ByteBufInputStream; -import io.netty.buffer.ByteBufOutputStream; - -import java.io.IOException; -import java.util.List; - -import com.fr.third.socketio.AckCallback; - -/** - * JSON infrastructure interface. - * Allows to implement custom realizations - * to JSON support operations. - * - */ -public interface JsonSupport { - - AckArgs readAckArgs(ByteBufInputStream src, AckCallback callback) throws IOException; - - T readValue(String namespaceName, ByteBufInputStream src, Class valueType) throws IOException; - - void writeValue(ByteBufOutputStream out, Object value) throws IOException; - - void addEventMapping(String namespaceName, String eventName, Class ... eventClass); - - void removeEventMapping(String namespaceName, String eventName); - - List getArrays(); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/Packet.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/Packet.java deleted file mode 100644 index 0d1314cf6..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/Packet.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import io.netty.buffer.ByteBuf; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.fr.third.socketio.namespace.Namespace; - -public class Packet implements Serializable { - - private static final long serialVersionUID = 4560159536486711426L; - - private PacketType type; - private PacketType subType; - private Long ackId; - private String name; - private String nsp = Namespace.DEFAULT_NAME; - private Object data; - - private ByteBuf dataSource; - private int attachmentsCount; - private List attachments = Collections.emptyList(); - - protected Packet() { - } - - public Packet(PacketType type) { - super(); - this.type = type; - } - - public PacketType getSubType() { - return subType; - } - - public void setSubType(PacketType subType) { - this.subType = subType; - } - - public PacketType getType() { - return type; - } - - public void setData(Object data) { - this.data = data; - } - - /** - * Get packet data - * - * @param the type data - * - *
-     * @return json object for PacketType.JSON type
-     * message for PacketType.MESSAGE type
-     * 
- */ - public T getData() { - return (T)data; - } - - /** - * Creates a copy of #{@link Packet} with new namespace set - * if it differs from current namespace. - * Otherwise, returns original object unchanged - * - * @param namespace - * @return packet - */ - public Packet withNsp(String namespace) { - if (this.nsp.equalsIgnoreCase(namespace)) { - return this; - } else { - Packet newPacket = new Packet(this.type); - newPacket.setAckId(this.ackId); - newPacket.setData(this.data); - newPacket.setDataSource(this.dataSource); - newPacket.setName(this.name); - newPacket.setSubType(this.subType); - newPacket.setNsp(namespace); - newPacket.attachments = this.attachments; - newPacket.attachmentsCount = this.attachmentsCount; - return newPacket; - } - } - - public void setNsp(String endpoint) { - this.nsp = endpoint; - } - - public String getNsp() { - return nsp; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Long getAckId() { - return ackId; - } - - public void setAckId(Long ackId) { - this.ackId = ackId; - } - - public boolean isAckRequested() { - return getAckId() != null; - } - - public void initAttachments(int attachmentsCount) { - this.attachmentsCount = attachmentsCount; - this.attachments = new ArrayList(attachmentsCount); - } - public void addAttachment(ByteBuf attachment) { - if (this.attachments.size() < attachmentsCount) { - this.attachments.add(attachment); - } - } - public List getAttachments() { - return attachments; - } - public boolean hasAttachments() { - return attachmentsCount != 0; - } - public boolean isAttachmentsLoaded() { - return this.attachments.size() == attachmentsCount; - } - - public ByteBuf getDataSource() { - return dataSource; - } - public void setDataSource(ByteBuf dataSource) { - this.dataSource = dataSource; - } - - @Override - public String toString() { - return "Packet [type=" + type + ", ackId=" + ackId + "]"; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketDecoder.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketDecoder.java deleted file mode 100644 index 36e7df43a..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketDecoder.java +++ /dev/null @@ -1,326 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import com.fr.third.socketio.AckCallback; -import com.fr.third.socketio.ack.AckManager; -import com.fr.third.socketio.handler.ClientHead; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufInputStream; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; -import io.netty.handler.codec.base64.Base64; -import io.netty.util.CharsetUtil; - -import java.io.IOException; -import java.net.URLDecoder; -import java.util.LinkedList; -import java.util.UUID; - -public class PacketDecoder { - - private final UTF8CharsScanner utf8scanner = new UTF8CharsScanner(); - - private final ByteBuf QUOTES = Unpooled.copiedBuffer("\"", CharsetUtil.UTF_8); - - private final JsonSupport jsonSupport; - private final AckManager ackManager; - - public PacketDecoder(JsonSupport jsonSupport, AckManager ackManager) { - this.jsonSupport = jsonSupport; - this.ackManager = ackManager; - } - - private boolean isStringPacket(ByteBuf content) { - return content.getByte(content.readerIndex()) == 0x0; - } - - // TODO optimize - public ByteBuf preprocessJson(Integer jsonIndex, ByteBuf content) throws IOException { - String packet = URLDecoder.decode(content.toString(CharsetUtil.UTF_8), CharsetUtil.UTF_8.name()); - - if (jsonIndex != null) { - /** - * double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side - * (c) socket.io.js - * - * @see https://github.com/Automattic/socket.io-client/blob/1.3.3/socket.io.js#L2682 - */ - packet = packet.replace("\\\\n", "\\n"); - - // skip "d=" - packet = packet.substring(2); - } - - return Unpooled.wrappedBuffer(packet.getBytes(CharsetUtil.UTF_8)); - } - - // fastest way to parse chars to int - private long readLong(ByteBuf chars, int length) { - long result = 0; - for (int i = chars.readerIndex(); i < chars.readerIndex() + length; i++) { - int digit = ((int)chars.getByte(i) & 0xF); - for (int j = 0; j < chars.readerIndex() + length-1-i; j++) { - digit *= 10; - } - result += digit; - } - chars.readerIndex(chars.readerIndex() + length); - return result; - } - - private PacketType readType(ByteBuf buffer) { - int typeId = buffer.readByte() & 0xF; - return PacketType.valueOf(typeId); - } - - private PacketType readInnerType(ByteBuf buffer) { - int typeId = buffer.readByte() & 0xF; - return PacketType.valueOfInner(typeId); - } - - private boolean hasLengthHeader(ByteBuf buffer) { - for (int i = 0; i < Math.min(buffer.readableBytes(), 10); i++) { - byte b = buffer.getByte(buffer.readerIndex() + i); - if (b == (byte)':' && i > 0) { - return true; - } - if (b > 57 || b < 48) { - return false; - } - } - return false; - } - - public Packet decodePackets(ByteBuf buffer, ClientHead client) throws IOException { - if (isStringPacket(buffer)) { - // TODO refactor - int maxLength = Math.min(buffer.readableBytes(), 10); - int headEndIndex = buffer.bytesBefore(maxLength, (byte)-1); - if (headEndIndex == -1) { - headEndIndex = buffer.bytesBefore(maxLength, (byte)0x3f); - } - int len = (int) readLong(buffer, headEndIndex); - - ByteBuf frame = buffer.slice(buffer.readerIndex() + 1, len); - // skip this frame - buffer.readerIndex(buffer.readerIndex() + 1 + len); - return decode(client, frame); - } else if (hasLengthHeader(buffer)) { - // TODO refactor - int lengthEndIndex = buffer.bytesBefore((byte)':'); - int lenHeader = (int) readLong(buffer, lengthEndIndex); - int len = utf8scanner.getActualLength(buffer, lenHeader); - - ByteBuf frame = buffer.slice(buffer.readerIndex() + 1, len); - // skip this frame - buffer.readerIndex(buffer.readerIndex() + 1 + len); - return decode(client, frame); - } - return decode(client, buffer); - } - - private String readString(ByteBuf frame) { - return readString(frame, frame.readableBytes()); - } - - private String readString(ByteBuf frame, int size) { - byte[] bytes = new byte[size]; - frame.readBytes(bytes); - return new String(bytes, CharsetUtil.UTF_8); - } - - private Packet decode(ClientHead head, ByteBuf frame) throws IOException { - if ((frame.getByte(0) == 'b' && frame.getByte(1) == '4') - || frame.getByte(0) == 4 || frame.getByte(0) == 1) { - return parseBinary(head, frame); - } - PacketType type = readType(frame); - Packet packet = new Packet(type); - - if (type == PacketType.PING) { - packet.setData(readString(frame)); - return packet; - } - - if (!frame.isReadable()) { - return packet; - } - - PacketType innerType = readInnerType(frame); - packet.setSubType(innerType); - - parseHeader(frame, packet, innerType); - parseBody(head, frame, packet); - return packet; - } - - private void parseHeader(ByteBuf frame, Packet packet, PacketType innerType) { - int endIndex = frame.bytesBefore((byte)'['); - if (endIndex <= 0) { - return; - } - - int attachmentsDividerIndex = frame.bytesBefore(endIndex, (byte)'-'); - boolean hasAttachments = attachmentsDividerIndex != -1; - if (hasAttachments && (PacketType.BINARY_EVENT.equals(innerType) - || PacketType.BINARY_ACK.equals(innerType))) { - int attachments = (int) readLong(frame, attachmentsDividerIndex); - packet.initAttachments(attachments); - frame.readerIndex(frame.readerIndex() + 1); - - endIndex -= attachmentsDividerIndex + 1; - } - if (endIndex == 0) { - return; - } - - // TODO optimize - boolean hasNsp = frame.bytesBefore(endIndex, (byte)',') != -1; - if (hasNsp) { - String nspAckId = readString(frame, endIndex); - String[] parts = nspAckId.split(","); - String nsp = parts[0]; - packet.setNsp(nsp); - if (parts.length > 1) { - String ackId = parts[1]; - packet.setAckId(Long.valueOf(ackId)); - } - } else { - long ackId = readLong(frame, endIndex); - packet.setAckId(ackId); - } - } - - private Packet parseBinary(ClientHead head, ByteBuf frame) throws IOException { - if (frame.getByte(0) == 1) { - frame.readByte(); - int headEndIndex = frame.bytesBefore((byte)-1); - int len = (int) readLong(frame, headEndIndex); - ByteBuf oldFrame = frame; - frame = frame.slice(oldFrame.readerIndex() + 1, len); - oldFrame.readerIndex(oldFrame.readerIndex() + 1 + len); - } - - if (frame.getByte(0) == 'b' && frame.getByte(1) == '4') { - frame.readShort(); - } else if (frame.getByte(0) == 4) { - frame.readByte(); - } - - Packet binaryPacket = head.getLastBinaryPacket(); - if (binaryPacket != null) { - if (frame.getByte(0) == 'b' && frame.getByte(1) == '4') { - binaryPacket.addAttachment(Unpooled.copiedBuffer(frame)); - } else { - ByteBuf attachBuf = Base64.encode(frame); - binaryPacket.addAttachment(Unpooled.copiedBuffer(attachBuf)); - attachBuf.release(); - } - frame.readerIndex(frame.readerIndex() + frame.readableBytes()); - - if (binaryPacket.isAttachmentsLoaded()) { - LinkedList slices = new LinkedList(); - ByteBuf source = binaryPacket.getDataSource(); - for (int i = 0; i < binaryPacket.getAttachments().size(); i++) { - ByteBuf attachment = binaryPacket.getAttachments().get(i); - ByteBuf scanValue = Unpooled.copiedBuffer("{\"_placeholder\":true,\"num\":" + i + "}", CharsetUtil.UTF_8); - int pos = PacketEncoder.find(source, scanValue); - if (pos == -1) { - scanValue = Unpooled.copiedBuffer("{\"num\":" + i + ",\"_placeholder\":true}", CharsetUtil.UTF_8); - pos = PacketEncoder.find(source, scanValue); - if (pos == -1) { - throw new IllegalStateException("Can't find attachment by index: " + i + " in packet source"); - } - } - - ByteBuf prefixBuf = source.slice(source.readerIndex(), pos - source.readerIndex()); - slices.add(prefixBuf); - slices.add(QUOTES); - slices.add(attachment); - slices.add(QUOTES); - - source.readerIndex(pos + scanValue.readableBytes()); - } - slices.add(source.slice()); - - ByteBuf compositeBuf = Unpooled.wrappedBuffer(slices.toArray(new ByteBuf[slices.size()])); - parseBody(head, compositeBuf, binaryPacket); - head.setLastBinaryPacket(null); - return binaryPacket; - } - } - return new Packet(PacketType.MESSAGE); - } - - private void parseBody(ClientHead head, ByteBuf frame, Packet packet) throws IOException { - if (packet.getType() == PacketType.MESSAGE) { - if (packet.getSubType() == PacketType.CONNECT - || packet.getSubType() == PacketType.DISCONNECT) { - packet.setNsp(readNamespace(frame)); - } - - if (packet.hasAttachments() && !packet.isAttachmentsLoaded()) { - packet.setDataSource(Unpooled.copiedBuffer(frame)); - frame.readerIndex(frame.readableBytes()); - head.setLastBinaryPacket(packet); - } - - if (packet.hasAttachments() && !packet.isAttachmentsLoaded()) { - return; - } - - if (packet.getSubType() == PacketType.ACK - || packet.getSubType() == PacketType.BINARY_ACK) { - ByteBufInputStream in = new ByteBufInputStream(frame); - AckCallback callback = ackManager.getCallback(head.getSessionId(), packet.getAckId()); - AckArgs args = jsonSupport.readAckArgs(in, callback); - packet.setData(args.getArgs()); - } - - if (packet.getSubType() == PacketType.EVENT - || packet.getSubType() == PacketType.BINARY_EVENT) { - ByteBufInputStream in = new ByteBufInputStream(frame); - Event event = jsonSupport.readValue(packet.getNsp(), in, Event.class); - packet.setName(event.getName()); - packet.setData(event.getArgs()); - } - } - } - - private String readNamespace(ByteBuf frame) { - - /** - * namespace post request with url queryString, like - * /message?a=1, - * /message, - */ - ByteBuf buffer = frame.slice(); - // skip this frame - frame.readerIndex(frame.readerIndex() + frame.readableBytes()); - - int endIndex = buffer.bytesBefore((byte) '?'); - if (endIndex > 0) { - return readString(buffer, endIndex); - } - endIndex = buffer.bytesBefore((byte) ','); - if (endIndex > 0) { - return readString(buffer, endIndex); - } - return readString(buffer); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketEncoder.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketEncoder.java deleted file mode 100644 index abdfe439c..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketEncoder.java +++ /dev/null @@ -1,353 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.ByteBufOutputStream; -import io.netty.buffer.Unpooled; -import io.netty.handler.codec.base64.Base64; -import io.netty.handler.codec.base64.Base64Dialect; -import io.netty.util.CharsetUtil; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Queue; - -import com.fr.third.socketio.Configuration; - -public class PacketEncoder { - - private static final byte[] BINARY_HEADER = "b4".getBytes(CharsetUtil.UTF_8); - private static final byte[] B64_DELIMITER = new byte[] {':'}; - private static final byte[] JSONP_HEAD = "___eio[".getBytes(CharsetUtil.UTF_8); - private static final byte[] JSONP_START = "]('".getBytes(CharsetUtil.UTF_8); - private static final byte[] JSONP_END = "');".getBytes(CharsetUtil.UTF_8); - - private final JsonSupport jsonSupport; - private final Configuration configuration; - - public PacketEncoder(Configuration configuration, JsonSupport jsonSupport) { - this.jsonSupport = jsonSupport; - this.configuration = configuration; - } - - public JsonSupport getJsonSupport() { - return jsonSupport; - } - - public ByteBuf allocateBuffer(ByteBufAllocator allocator) { - if (configuration.isPreferDirectBuffer()) { - return allocator.ioBuffer(); - } - - return allocator.heapBuffer(); - } - - public void encodeJsonP(Integer jsonpIndex, Queue packets, ByteBuf out, ByteBufAllocator allocator, int limit) throws IOException { - boolean jsonpMode = jsonpIndex != null; - - ByteBuf buf = allocateBuffer(allocator); - - int i = 0; - while (true) { - Packet packet = packets.poll(); - if (packet == null || i == limit) { - break; - } - - ByteBuf packetBuf = allocateBuffer(allocator); - encodePacket(packet, packetBuf, allocator, true); - - int packetSize = packetBuf.writerIndex(); - buf.writeBytes(toChars(packetSize)); - buf.writeBytes(B64_DELIMITER); - buf.writeBytes(packetBuf); - - packetBuf.release(); - - i++; - - for (ByteBuf attachment : packet.getAttachments()) { - ByteBuf encodedBuf = Base64.encode(attachment, Base64Dialect.URL_SAFE); - buf.writeBytes(toChars(encodedBuf.readableBytes() + 2)); - buf.writeBytes(B64_DELIMITER); - buf.writeBytes(BINARY_HEADER); - buf.writeBytes(encodedBuf); - } - } - - if (jsonpMode) { - out.writeBytes(JSONP_HEAD); - out.writeBytes(toChars(jsonpIndex)); - out.writeBytes(JSONP_START); - } - - processUtf8(buf, out, jsonpMode); - buf.release(); - - if (jsonpMode) { - out.writeBytes(JSONP_END); - } - } - - private void processUtf8(ByteBuf in, ByteBuf out, boolean jsonpMode) { - while (in.isReadable()) { - short value = (short) (in.readByte() & 0xFF); - if (value >>> 7 == 0) { - if (jsonpMode && (value == '\\' || value == '\'')) { - out.writeByte('\\'); - } - out.writeByte(value); - } else { - out.writeByte(((value >>> 6) | 0xC0)); - out.writeByte(((value & 0x3F) | 0x80)); - } - } - } - - public void encodePackets(Queue packets, ByteBuf buffer, ByteBufAllocator allocator, int limit) throws IOException { - int i = 0; - while (true) { - Packet packet = packets.poll(); - if (packet == null || i == limit) { - break; - } - encodePacket(packet, buffer, allocator, false); - - i++; - - for (ByteBuf attachment : packet.getAttachments()) { - buffer.writeByte(1); - buffer.writeBytes(longToBytes(attachment.readableBytes() + 1)); - buffer.writeByte(0xff); - buffer.writeByte(4); - buffer.writeBytes(attachment); - } - } - } - - private byte toChar(int number) { - return (byte) (number ^ 0x30); - } - - static final char[] DigitTens = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', - '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', - '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', - '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', - '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', - '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',}; - - static final char[] DigitOnes = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', - '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', - '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',}; - - static final char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', - 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z'}; - - static final int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, - Integer.MAX_VALUE}; - - // Requires positive x - static int stringSize(long x) { - for (int i = 0;; i++) - if (x <= sizeTable[i]) - return i + 1; - } - - static void getChars(long i, int index, byte[] buf) { - long q, r; - int charPos = index; - byte sign = 0; - - if (i < 0) { - sign = '-'; - i = -i; - } - - // Generate two digits per iteration - while (i >= 65536) { - q = i / 100; - // really: r = i - (q * 100); - r = i - ((q << 6) + (q << 5) + (q << 2)); - i = q; - buf[--charPos] = (byte) DigitOnes[(int)r]; - buf[--charPos] = (byte) DigitTens[(int)r]; - } - - // Fall thru to fast mode for smaller numbers - // assert(i <= 65536, i); - for (;;) { - q = (i * 52429) >>> (16 + 3); - r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ... - buf[--charPos] = (byte) digits[(int)r]; - i = q; - if (i == 0) - break; - } - if (sign != 0) { - buf[--charPos] = sign; - } - } - - public static byte[] toChars(long i) { - int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); - byte[] buf = new byte[size]; - getChars(i, size, buf); - return buf; - } - - public static byte[] longToBytes(long number) { - // TODO optimize - int length = (int)(Math.log10(number)+1); - byte[] res = new byte[length]; - int i = length; - while (number > 0) { - res[--i] = (byte) (number % 10); - number = number / 10; - } - return res; - } - - public void encodePacket(Packet packet, ByteBuf buffer, ByteBufAllocator allocator, boolean binary) throws IOException { - ByteBuf buf = buffer; - if (!binary) { - buf = allocateBuffer(allocator); - } - byte type = toChar(packet.getType().getValue()); - buf.writeByte(type); - - try { - switch (packet.getType()) { - - case PONG: { - buf.writeBytes(packet.getData().toString().getBytes(CharsetUtil.UTF_8)); - break; - } - - case OPEN: { - ByteBufOutputStream out = new ByteBufOutputStream(buf); - jsonSupport.writeValue(out, packet.getData()); - break; - } - - case MESSAGE: { - - ByteBuf encBuf = null; - - if (packet.getSubType() == PacketType.ERROR) { - encBuf = allocateBuffer(allocator); - - ByteBufOutputStream out = new ByteBufOutputStream(encBuf); - jsonSupport.writeValue(out, packet.getData()); - } - - if (packet.getSubType() == PacketType.EVENT - || packet.getSubType() == PacketType.ACK) { - - List values = new ArrayList(); - if (packet.getSubType() == PacketType.EVENT) { - values.add(packet.getName()); - } - - encBuf = allocateBuffer(allocator); - - List args = packet.getData(); - values.addAll(args); - ByteBufOutputStream out = new ByteBufOutputStream(encBuf); - jsonSupport.writeValue(out, values); - - if (!jsonSupport.getArrays().isEmpty()) { - packet.initAttachments(jsonSupport.getArrays().size()); - for (byte[] array : jsonSupport.getArrays()) { - packet.addAttachment(Unpooled.wrappedBuffer(array)); - } - packet.setSubType(packet.getSubType() == PacketType.ACK - ? PacketType.BINARY_ACK : PacketType.BINARY_EVENT); - } - } - - byte subType = toChar(packet.getSubType().getValue()); - buf.writeByte(subType); - - if (packet.hasAttachments()) { - byte[] ackId = toChars(packet.getAttachments().size()); - buf.writeBytes(ackId); - buf.writeByte('-'); - } - - if (packet.getSubType() == PacketType.CONNECT) { - if (!packet.getNsp().isEmpty()) { - buf.writeBytes(packet.getNsp().getBytes(CharsetUtil.UTF_8)); - } - } else { - if (!packet.getNsp().isEmpty()) { - buf.writeBytes(packet.getNsp().getBytes(CharsetUtil.UTF_8)); - buf.writeByte(','); - } - } - - if (packet.getAckId() != null) { - byte[] ackId = toChars(packet.getAckId()); - buf.writeBytes(ackId); - } - - if (encBuf != null) { - buf.writeBytes(encBuf); - encBuf.release(); - } - - break; - } - } - } finally { - // we need to write a buffer in any case - if (!binary) { - buffer.writeByte(0); - int length = buf.writerIndex(); - buffer.writeBytes(longToBytes(length)); - buffer.writeByte(0xff); - buffer.writeBytes(buf); - - buf.release(); - } - } - } - - public static int find(ByteBuf buffer, ByteBuf searchValue) { - for (int i = buffer.readerIndex(); i < buffer.readerIndex() + buffer.readableBytes(); i++) { - if (isValueFound(buffer, i, searchValue)) { - return i; - } - } - return -1; - } - - private static boolean isValueFound(ByteBuf buffer, int index, ByteBuf search) { - for (int i = 0; i < search.readableBytes(); i++) { - if (buffer.getByte(index + i) != search.getByte(i)) { - return false; - } - } - return true; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketType.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketType.java deleted file mode 100644 index 7031d52ff..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/PacketType.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - - -public enum PacketType { - - OPEN(0), CLOSE(1), PING(2), PONG(3), MESSAGE(4), UPGRADE(5), NOOP(6), - - CONNECT(0, true), DISCONNECT(1, true), EVENT(2, true), ACK(3, true), ERROR(4, true), BINARY_EVENT(5, true), BINARY_ACK(6, true); - - public static final PacketType[] VALUES = values(); - private final int value; - private final boolean inner; - - PacketType(int value) { - this(value, false); - } - - PacketType(int value, boolean inner) { - this.value = value; - this.inner = inner; - } - - public int getValue() { - return value; - } - - public static PacketType valueOf(int value) { - for (PacketType type : VALUES) { - if (type.getValue() == value && !type.inner) { - return type; - } - } - throw new IllegalStateException(); - } - - public static PacketType valueOfInner(int value) { - for (PacketType type : VALUES) { - if (type.getValue() == value && type.inner) { - return type; - } - } - throw new IllegalArgumentException("Can't parse " + value); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/UTF8CharsScanner.java b/fine-socketio/src/main/java/com/fr/third/socketio/protocol/UTF8CharsScanner.java deleted file mode 100644 index 4e8728217..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/protocol/UTF8CharsScanner.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.protocol; - -import io.netty.buffer.ByteBuf; - -public class UTF8CharsScanner { - - /** - * Lookup table used for determining which input characters need special - * handling when contained in text segment. - */ - static final int[] sInputCodes; - static { - /* - * 96 would do for most cases (backslash is ascii 94) but if we want to - * do lookups by raw bytes it's better to have full table - */ - int[] table = new int[256]; - // Control chars and non-space white space are not allowed unquoted - for (int i = 0; i < 32; ++i) { - table[i] = -1; - } - // And then string end and quote markers are special too - table['"'] = 1; - table['\\'] = 1; - sInputCodes = table; - } - - /** - * Additionally we can combine UTF-8 decoding info into similar data table. - */ - static final int[] sInputCodesUtf8; - static { - int[] table = new int[sInputCodes.length]; - System.arraycopy(sInputCodes, 0, table, 0, sInputCodes.length); - for (int c = 128; c < 256; ++c) { - int code; - - // We'll add number of bytes needed for decoding - if ((c & 0xE0) == 0xC0) { // 2 bytes (0x0080 - 0x07FF) - code = 2; - } else if ((c & 0xF0) == 0xE0) { // 3 bytes (0x0800 - 0xFFFF) - code = 3; - } else if ((c & 0xF8) == 0xF0) { - // 4 bytes; double-char with surrogates and all... - code = 4; - } else { - // And -1 seems like a good "universal" error marker... - code = -1; - } - table[c] = code; - } - sInputCodesUtf8 = table; - } - - private int getCharTailIndex(ByteBuf inputBuffer, int i) { - int c = (int) inputBuffer.getByte(i) & 0xFF; - switch (sInputCodesUtf8[c]) { - case 2: // 2-byte UTF - i += 2; - break; - case 3: // 3-byte UTF - i += 3; - break; - case 4: // 4-byte UTF - i += 4; - break; - default: - i++; - break; - } - return i; - } - - public int getActualLength(ByteBuf inputBuffer, int length) { - int len = 0; - int start = inputBuffer.readerIndex(); - for (int i = inputBuffer.readerIndex(); i < inputBuffer.readableBytes() + inputBuffer.readerIndex();) { - i = getCharTailIndex(inputBuffer, i); - len++; - if (length == len) { - return i-start; - } - } - throw new IllegalStateException(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/CancelableScheduler.java b/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/CancelableScheduler.java deleted file mode 100644 index 1cd23d97b..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/CancelableScheduler.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.scheduler; - -import io.netty.channel.ChannelHandlerContext; - -import java.util.concurrent.TimeUnit; - -public interface CancelableScheduler { - - void update(ChannelHandlerContext ctx); - - void cancel(SchedulerKey key); - - void scheduleCallback(SchedulerKey key, Runnable runnable, long delay, TimeUnit unit); - - void schedule(Runnable runnable, long delay, TimeUnit unit); - - void schedule(SchedulerKey key, Runnable runnable, long delay, TimeUnit unit); - - void shutdown(); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/HashedWheelScheduler.java b/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/HashedWheelScheduler.java deleted file mode 100644 index d0e699c5b..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/HashedWheelScheduler.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.scheduler; - -import java.util.Map; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.util.HashedWheelTimer; -import io.netty.util.Timeout; -import io.netty.util.TimerTask; -import io.netty.util.internal.PlatformDependent; - -public class HashedWheelScheduler implements CancelableScheduler { - - private final Map scheduledFutures = PlatformDependent.newConcurrentHashMap(); - private final HashedWheelTimer executorService; - - public HashedWheelScheduler() { - executorService = new HashedWheelTimer(); - } - - public HashedWheelScheduler(ThreadFactory threadFactory) { - executorService = new HashedWheelTimer(threadFactory); - } - - private volatile ChannelHandlerContext ctx; - - @Override - public void update(ChannelHandlerContext ctx) { - this.ctx = ctx; - } - - @Override - public void cancel(SchedulerKey key) { - Timeout timeout = scheduledFutures.remove(key); - if (timeout != null) { - timeout.cancel(); - } - } - - @Override - public void schedule(final Runnable runnable, long delay, TimeUnit unit) { - executorService.newTimeout(new TimerTask() { - @Override - public void run(Timeout timeout) throws Exception { - runnable.run(); - } - }, delay, unit); - } - - @Override - public void scheduleCallback(final SchedulerKey key, final Runnable runnable, long delay, TimeUnit unit) { - Timeout timeout = executorService.newTimeout(new TimerTask() { - @Override - public void run(Timeout timeout) throws Exception { - ctx.executor().execute(new Runnable() { - @Override - public void run() { - try { - runnable.run(); - } finally { - scheduledFutures.remove(key); - } - } - }); - } - }, delay, unit); - - if (!timeout.isExpired()) { - scheduledFutures.put(key, timeout); - } - } - - @Override - public void schedule(final SchedulerKey key, final Runnable runnable, long delay, TimeUnit unit) { - Timeout timeout = executorService.newTimeout(new TimerTask() { - @Override - public void run(Timeout timeout) throws Exception { - try { - runnable.run(); - } finally { - scheduledFutures.remove(key); - } - } - }, delay, unit); - - if (!timeout.isExpired()) { - scheduledFutures.put(key, timeout); - } - } - - @Override - public void shutdown() { - executorService.stop(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/HashedWheelTimeoutScheduler.java b/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/HashedWheelTimeoutScheduler.java deleted file mode 100644 index c04eb7a25..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/HashedWheelTimeoutScheduler.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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. - */ -/** - * Modified version of HashedWheelScheduler specially for timeouts handling. - * Difference: - * - handling old timeout with same key after adding new one - * fixes multithreaded problem that appears in highly concurrent non-atomic sequence cancel() -> schedule() - * - * (c) Alim Akbashev, 2015-02-11 - */ - -package com.fr.third.socketio.scheduler; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.util.HashedWheelTimer; -import io.netty.util.Timeout; -import io.netty.util.TimerTask; -import io.netty.util.internal.PlatformDependent; - -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -public class HashedWheelTimeoutScheduler implements CancelableScheduler { - - private final ConcurrentMap scheduledFutures = PlatformDependent.newConcurrentHashMap(); - private final HashedWheelTimer executorService; - - private volatile ChannelHandlerContext ctx; - - public HashedWheelTimeoutScheduler() { - executorService = new HashedWheelTimer(); - } - - public HashedWheelTimeoutScheduler(ThreadFactory threadFactory) { - executorService = new HashedWheelTimer(threadFactory); - } - - @Override - public void update(ChannelHandlerContext ctx) { - this.ctx = ctx; - } - - @Override - public void cancel(SchedulerKey key) { - Timeout timeout = scheduledFutures.remove(key); - if (timeout != null) { - timeout.cancel(); - } - } - - @Override - public void schedule(final Runnable runnable, long delay, TimeUnit unit) { - executorService.newTimeout(new TimerTask() { - @Override - public void run(Timeout timeout) throws Exception { - runnable.run(); - } - }, delay, unit); - } - - @Override - public void scheduleCallback(final SchedulerKey key, final Runnable runnable, long delay, TimeUnit unit) { - Timeout timeout = executorService.newTimeout(new TimerTask() { - @Override - public void run(Timeout timeout) throws Exception { - ctx.executor().execute(new Runnable() { - @Override - public void run() { - try { - runnable.run(); - } finally { - scheduledFutures.remove(key); - } - } - }); - } - }, delay, unit); - - replaceScheduledFuture(key, timeout); - } - - @Override - public void schedule(final SchedulerKey key, final Runnable runnable, long delay, TimeUnit unit) { - Timeout timeout = executorService.newTimeout(new TimerTask() { - @Override - public void run(Timeout timeout) throws Exception { - try { - runnable.run(); - } finally { - scheduledFutures.remove(key); - } - } - }, delay, unit); - - replaceScheduledFuture(key, timeout); - } - - @Override - public void shutdown() { - executorService.stop(); - } - - private void replaceScheduledFuture(final SchedulerKey key, final Timeout newTimeout) { - final Timeout oldTimeout; - - if (newTimeout.isExpired()) { - // no need to put already expired timeout to scheduledFutures map. - // simply remove old timeout - oldTimeout = scheduledFutures.remove(key); - } else { - oldTimeout = scheduledFutures.put(key, newTimeout); - } - - // if there was old timeout, cancel it - if (oldTimeout != null) { - oldTimeout.cancel(); - } - } -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/SchedulerKey.java b/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/SchedulerKey.java deleted file mode 100644 index 2f81f12b5..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/scheduler/SchedulerKey.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.scheduler; - - -public class SchedulerKey { - - public enum Type {PING_TIMEOUT, ACK_TIMEOUT, UPGRADE_TIMEOUT}; - - private final Type type; - private final Object sessionId; - - public SchedulerKey(Type type, Object sessionId) { - this.type = type; - this.sessionId = sessionId; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((sessionId == null) ? 0 : sessionId.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SchedulerKey other = (SchedulerKey) obj; - if (sessionId == null) { - if (other.sessionId != null) - return false; - } else if (!sessionId.equals(other.sessionId)) - return false; - if (type != other.type) - return false; - return true; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryPubSubStore.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryPubSubStore.java deleted file mode 100644 index e2eb50b27..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryPubSubStore.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store; - -import com.fr.third.socketio.store.pubsub.PubSubListener; -import com.fr.third.socketio.store.pubsub.PubSubMessage; -import com.fr.third.socketio.store.pubsub.PubSubStore; -import com.fr.third.socketio.store.pubsub.PubSubType; - -public class MemoryPubSubStore implements PubSubStore { - - @Override - public void publish(PubSubType type, PubSubMessage msg) { - } - - @Override - public void subscribe(PubSubType type, PubSubListener listener, Class clazz) { - } - - @Override - public void unsubscribe(PubSubType type) { - } - - @Override - public void shutdown() { - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryStore.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryStore.java deleted file mode 100644 index fce3b32b8..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryStore.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store; - -import io.netty.util.internal.PlatformDependent; - -import java.util.Map; - -public class MemoryStore implements Store { - - private final Map store = PlatformDependent.newConcurrentHashMap(); - - @Override - public void set(String key, Object value) { - store.put(key, value); - } - - @Override - public T get(String key) { - return (T) store.get(key); - } - - @Override - public boolean has(String key) { - return store.containsKey(key); - } - - @Override - public void del(String key) { - store.remove(key); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryStoreFactory.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryStoreFactory.java deleted file mode 100644 index e87d804b6..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/MemoryStoreFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store; - -import io.netty.util.internal.PlatformDependent; - -import java.util.Map; -import java.util.UUID; - -import com.fr.third.socketio.store.pubsub.BaseStoreFactory; -import com.fr.third.socketio.store.pubsub.PubSubStore; - -public class MemoryStoreFactory extends BaseStoreFactory { - - private final MemoryPubSubStore pubSubMemoryStore = new MemoryPubSubStore(); - - @Override - public Store createStore(UUID sessionId) { - return new MemoryStore(); - } - - @Override - public PubSubStore pubSubStore() { - return pubSubMemoryStore; - } - - @Override - public void shutdown() { - } - - @Override - public String toString() { - return getClass().getSimpleName() + " (local session store only)"; - } - - @Override - public Map createMap(String name) { - return PlatformDependent.newConcurrentHashMap(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonPubSubStore.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonPubSubStore.java deleted file mode 100644 index 8c4287d84..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonPubSubStore.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store; - -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; - -import com.fr.third.org.redisson.api.RTopic; -import com.fr.third.org.redisson.api.RedissonClient; -import com.fr.third.org.redisson.api.listener.MessageListener; - -import com.fr.third.socketio.store.pubsub.PubSubListener; -import com.fr.third.socketio.store.pubsub.PubSubMessage; -import com.fr.third.socketio.store.pubsub.PubSubStore; -import com.fr.third.socketio.store.pubsub.PubSubType; - -import io.netty.util.internal.PlatformDependent; - -public class RedissonPubSubStore implements PubSubStore { - - private final RedissonClient redissonPub; - private final RedissonClient redissonSub; - private final Long nodeId; - - private final ConcurrentMap> map = PlatformDependent.newConcurrentHashMap(); - - public RedissonPubSubStore(RedissonClient redissonPub, RedissonClient redissonSub, Long nodeId) { - this.redissonPub = redissonPub; - this.redissonSub = redissonSub; - this.nodeId = nodeId; - } - - @Override - public void publish(PubSubType type, PubSubMessage msg) { - msg.setNodeId(nodeId); - redissonPub.getTopic(type.toString()).publish(msg); - } - - @Override - public void subscribe(PubSubType type, final PubSubListener listener, Class clazz) { - String name = type.toString(); - RTopic topic = redissonSub.getTopic(name); - int regId = topic.addListener(new MessageListener() { - @Override - public void onMessage(String channel, T msg) { - if (!nodeId.equals(msg.getNodeId())) { - listener.onMessage(msg); - } - } - }); - - Queue list = map.get(name); - if (list == null) { - list = new ConcurrentLinkedQueue(); - Queue oldList = map.putIfAbsent(name, list); - if (oldList != null) { - list = oldList; - } - } - list.add(regId); - } - - @Override - public void unsubscribe(PubSubType type) { - String name = type.toString(); - Queue regIds = map.remove(name); - RTopic topic = redissonSub.getTopic(name); - for (Integer id : regIds) { - topic.removeListener(id); - } - } - - @Override - public void shutdown() { - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonStore.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonStore.java deleted file mode 100644 index c738e4954..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonStore.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store; - -import java.util.Map; -import java.util.UUID; - -import com.fr.third.org.redisson.api.RedissonClient; - -public class RedissonStore implements Store { - - private final Map map; - - public RedissonStore(UUID sessionId, RedissonClient redisson) { - this.map = redisson.getMap(sessionId.toString()); - } - - @Override - public void set(String key, Object value) { - map.put(key, value); - } - - @Override - public T get(String key) { - return (T) map.get(key); - } - - @Override - public boolean has(String key) { - return map.containsKey(key); - } - - @Override - public void del(String key) { - map.remove(key); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonStoreFactory.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonStoreFactory.java deleted file mode 100644 index e548871c0..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/RedissonStoreFactory.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store; - -import java.util.Map; -import java.util.UUID; - -import com.fr.third.org.redisson.Redisson; -import com.fr.third.org.redisson.api.RedissonClient; - -import com.fr.third.socketio.store.pubsub.BaseStoreFactory; -import com.fr.third.socketio.store.pubsub.PubSubStore; - -public class RedissonStoreFactory extends BaseStoreFactory { - - private final RedissonClient redisClient; - private final RedissonClient redisPub; - private final RedissonClient redisSub; - - private final PubSubStore pubSubStore; - - public RedissonStoreFactory() { - this(Redisson.create()); - } - - public RedissonStoreFactory(RedissonClient redisson) { - this.redisClient = redisson; - this.redisPub = redisson; - this.redisSub = redisson; - - this.pubSubStore = new RedissonPubSubStore(redisPub, redisSub, getNodeId()); - } - - public RedissonStoreFactory(Redisson redisClient, Redisson redisPub, Redisson redisSub) { - this.redisClient = redisClient; - this.redisPub = redisPub; - this.redisSub = redisSub; - - this.pubSubStore = new RedissonPubSubStore(redisPub, redisSub, getNodeId()); - } - - @Override - public Store createStore(UUID sessionId) { - return new RedissonStore(sessionId, redisClient); - } - - @Override - public PubSubStore pubSubStore() { - return pubSubStore; - } - - @Override - public void shutdown() { - redisClient.shutdown(); - redisPub.shutdown(); - redisSub.shutdown(); - } - - @Override - public Map createMap(String name) { - return redisClient.getMap(name); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/Store.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/Store.java deleted file mode 100644 index f0fa9b58c..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/Store.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store; - - -public interface Store { - - void set(String key, Object val); - - T get(String key); - - boolean has(String key); - - void del(String key); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/StoreFactory.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/StoreFactory.java deleted file mode 100644 index d1eeaaba6..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/StoreFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store; - -import java.util.Map; -import java.util.UUID; - -import com.fr.third.socketio.Disconnectable; -import com.fr.third.socketio.handler.AuthorizeHandler; -import com.fr.third.socketio.namespace.NamespacesHub; -import com.fr.third.socketio.protocol.JsonSupport; -import com.fr.third.socketio.store.pubsub.PubSubStore; - -/** - * - * Creates a client Store and PubSubStore - * - */ -public interface StoreFactory extends Disconnectable { - - PubSubStore pubSubStore(); - - Map createMap(String name); - - Store createStore(UUID sessionId); - - void init(NamespacesHub namespacesHub, AuthorizeHandler authorizeHandler, JsonSupport jsonSupport); - - void shutdown(); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/BaseStoreFactory.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/BaseStoreFactory.java deleted file mode 100644 index ed957f3c4..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/BaseStoreFactory.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.handler.AuthorizeHandler; -import com.fr.third.socketio.handler.ClientHead; -import com.fr.third.socketio.namespace.NamespacesHub; -import com.fr.third.socketio.protocol.JsonSupport; -import com.fr.third.socketio.store.StoreFactory; - -public abstract class BaseStoreFactory implements StoreFactory { - - private final Logger log = LoggerFactory.getLogger(getClass()); - - private Long nodeId = (long) (Math.random() * 1000000); - - protected Long getNodeId() { - return nodeId; - } - - @Override - public void init(final NamespacesHub namespacesHub, final AuthorizeHandler authorizeHandler, JsonSupport jsonSupport) { - pubSubStore().subscribe(PubSubType.DISCONNECT, new PubSubListener() { - @Override - public void onMessage(DisconnectMessage msg) { - log.debug("{} sessionId: {}", PubSubType.DISCONNECT, msg.getSessionId()); - } - }, DisconnectMessage.class); - - pubSubStore().subscribe(PubSubType.CONNECT, new PubSubListener() { - @Override - public void onMessage(ConnectMessage msg) { - authorizeHandler.connect(msg.getSessionId()); - log.debug("{} sessionId: {}", PubSubType.CONNECT, msg.getSessionId()); - } - }, ConnectMessage.class); - - pubSubStore().subscribe(PubSubType.DISPATCH, new PubSubListener() { - @Override - public void onMessage(DispatchMessage msg) { - String name = msg.getRoom(); - - namespacesHub.get(msg.getNamespace()).dispatch(name, msg.getPacket()); - log.debug("{} packet: {}", PubSubType.DISPATCH, msg.getPacket()); - } - }, DispatchMessage.class); - - pubSubStore().subscribe(PubSubType.JOIN, new PubSubListener() { - @Override - public void onMessage(JoinLeaveMessage msg) { - String name = msg.getRoom(); - - namespacesHub.get(msg.getNamespace()).join(name, msg.getSessionId()); - log.debug("{} sessionId: {}", PubSubType.JOIN, msg.getSessionId()); - } - }, JoinLeaveMessage.class); - - pubSubStore().subscribe(PubSubType.LEAVE, new PubSubListener() { - @Override - public void onMessage(JoinLeaveMessage msg) { - String name = msg.getRoom(); - - namespacesHub.get(msg.getNamespace()).leave(name, msg.getSessionId()); - log.debug("{} sessionId: {}", PubSubType.LEAVE, msg.getSessionId()); - } - }, JoinLeaveMessage.class); - } - - @Override - public abstract PubSubStore pubSubStore(); - - @Override - public void onDisconnect(ClientHead client) { - } - - @Override - public String toString() { - return getClass().getSimpleName() + " (distributed session store, distributed publish/subscribe)"; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/ConnectMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/ConnectMessage.java deleted file mode 100644 index d24e44592..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/ConnectMessage.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - -import java.util.UUID; - -public class ConnectMessage extends PubSubMessage { - - private static final long serialVersionUID = 3108918714495865101L; - - private UUID sessionId; - - public ConnectMessage() { - } - - public ConnectMessage(UUID sessionId) { - super(); - this.sessionId = sessionId; - } - - public UUID getSessionId() { - return sessionId; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/DisconnectMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/DisconnectMessage.java deleted file mode 100644 index b3a6d7b91..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/DisconnectMessage.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - -import java.util.UUID; - -public class DisconnectMessage extends PubSubMessage { - - private static final long serialVersionUID = -2763553673397520368L; - - private UUID sessionId; - - public DisconnectMessage() { - } - - public DisconnectMessage(UUID sessionId) { - super(); - this.sessionId = sessionId; - } - - public UUID getSessionId() { - return sessionId; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/DispatchMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/DispatchMessage.java deleted file mode 100644 index 12c633860..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/DispatchMessage.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - -import com.fr.third.socketio.protocol.Packet; - -public class DispatchMessage extends PubSubMessage { - - private static final long serialVersionUID = 6692047718303934349L; - - private String room; - private String namespace; - private Packet packet; - - public DispatchMessage() { - } - - public DispatchMessage(String room, Packet packet, String namespace) { - this.room = room; - this.packet = packet; - this.namespace = namespace; - } - - public String getNamespace() { - return namespace; - } - - public Packet getPacket() { - return packet; - } - - public String getRoom() { - return room; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/JoinLeaveMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/JoinLeaveMessage.java deleted file mode 100644 index cb49785af..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/JoinLeaveMessage.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - -import java.util.UUID; - -public class JoinLeaveMessage extends PubSubMessage { - - private static final long serialVersionUID = -944515928988033174L; - - private UUID sessionId; - private String namespace; - private String room; - - public JoinLeaveMessage() { - } - - public JoinLeaveMessage(UUID id, String room, String namespace) { - super(); - this.sessionId = id; - this.room = room; - this.namespace = namespace; - } - - public String getNamespace() { - return namespace; - } - - public UUID getSessionId() { - return sessionId; - } - - public String getRoom() { - return room; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubListener.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubListener.java deleted file mode 100644 index a8ee3db53..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubListener.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - - -public interface PubSubListener { - - void onMessage(T data); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubMessage.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubMessage.java deleted file mode 100644 index f228a1677..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubMessage.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - -import java.io.Serializable; - -public abstract class PubSubMessage implements Serializable { - - private static final long serialVersionUID = -8789343104393884987L; - - private Long nodeId; - - public Long getNodeId() { - return nodeId; - } - - public void setNodeId(Long nodeId) { - this.nodeId = nodeId; - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubStore.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubStore.java deleted file mode 100644 index 7e7d5be77..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubStore.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - - -public interface PubSubStore { - - void publish(PubSubType type, PubSubMessage msg); - - void subscribe(PubSubType type, PubSubListener listener, Class clazz); - - void unsubscribe(PubSubType type); - - void shutdown(); - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubType.java b/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubType.java deleted file mode 100644 index b6b39f275..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/store/pubsub/PubSubType.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.store.pubsub; - -public enum PubSubType { - - CONNECT, DISCONNECT, JOIN, LEAVE, DISPATCH; - - @Override - public String toString() { - return name().toLowerCase(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/transport/NamespaceClient.java b/fine-socketio/src/main/java/com/fr/third/socketio/transport/NamespaceClient.java deleted file mode 100644 index 1346ded3b..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/transport/NamespaceClient.java +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.transport; - -import java.net.SocketAddress; -import java.util.Arrays; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicBoolean; - -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.AckCallback; -import com.fr.third.socketio.HandshakeData; -import com.fr.third.socketio.SocketIOClient; -import com.fr.third.socketio.Transport; -import com.fr.third.socketio.handler.ClientHead; -import com.fr.third.socketio.namespace.Namespace; -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketType; - -public class NamespaceClient implements SocketIOClient { - - private static final Logger log = LoggerFactory.getLogger(NamespaceClient.class); - - private final AtomicBoolean disconnected = new AtomicBoolean(); - private final ClientHead baseClient; - private final Namespace namespace; - - public NamespaceClient(ClientHead baseClient, Namespace namespace) { - this.baseClient = baseClient; - this.namespace = namespace; - namespace.addClient(this); - } - - public ClientHead getBaseClient() { - return baseClient; - } - - @Override - public Transport getTransport() { - return baseClient.getCurrentTransport(); - } - - @Override - public boolean isChannelOpen() { - return baseClient.isChannelOpen(); - } - - @Override - public Namespace getNamespace() { - return namespace; - } - - @Override - public void sendEvent(String name, Object ... data) { - Packet packet = new Packet(PacketType.MESSAGE); - packet.setSubType(PacketType.EVENT); - packet.setName(name); - packet.setData(Arrays.asList(data)); - send(packet); - } - - @Override - public void sendEvent(String name, AckCallback ackCallback, Object ... data) { - Packet packet = new Packet(PacketType.MESSAGE); - packet.setSubType(PacketType.EVENT); - packet.setName(name); - packet.setData(Arrays.asList(data)); - send(packet, ackCallback); - } - - private boolean isConnected() { - return !disconnected.get() && baseClient.isConnected(); - } - - @Override - public void send(Packet packet, AckCallback ackCallback) { - if (!isConnected()) { - ackCallback.onTimeout(); - return; - } - long index = baseClient.getAckManager().registerAck(getSessionId(), ackCallback); - packet.setAckId(index); - send(packet); - } - - @Override - public void send(Packet packet) { - if (!isConnected()) { - return; - } - - baseClient.send(packet.withNsp(namespace.getName())); - } - - public void onDisconnect() { - disconnected.set(true); - - baseClient.removeNamespaceClient(this); - namespace.onDisconnect(this); - - log.debug("Client {} for namespace {} has been disconnected", baseClient.getSessionId(), getNamespace().getName()); - } - - @Override - public void disconnect() { - Packet packet = new Packet(PacketType.MESSAGE); - packet.setSubType(PacketType.DISCONNECT); - send(packet); -// onDisconnect(); - } - - @Override - public UUID getSessionId() { - return baseClient.getSessionId(); - } - - @Override - public SocketAddress getRemoteAddress() { - return baseClient.getRemoteAddress(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((getSessionId() == null) ? 0 : getSessionId().hashCode()); - result = prime * result - + ((getNamespace().getName() == null) ? 0 : getNamespace().getName().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - NamespaceClient other = (NamespaceClient) obj; - if (getSessionId() == null) { - if (other.getSessionId() != null) - return false; - } else if (!getSessionId().equals(other.getSessionId())) - return false; - if (getNamespace().getName() == null) { - if (other.getNamespace().getName() != null) - return false; - } else if (!getNamespace().getName().equals(other.getNamespace().getName())) - return false; - return true; - } - - @Override - public void joinRoom(String room) { - namespace.joinRoom(room, getSessionId()); - } - - @Override - public void leaveRoom(String room) { - namespace.leaveRoom(room, getSessionId()); - } - - @Override - public void set(String key, Object val) { - baseClient.getStore().set(key, val); - } - - @Override - public T get(String key) { - return baseClient.getStore().get(key); - } - - @Override - public boolean has(String key) { - return baseClient.getStore().has(key); - } - - @Override - public void del(String key) { - baseClient.getStore().del(key); - } - - @Override - public Set getAllRooms() { - return namespace.getRooms(this); - } - - @Override - public HandshakeData getHandshakeData() { - return baseClient.getHandshakeData(); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/transport/PollingTransport.java b/fine-socketio/src/main/java/com/fr/third/socketio/transport/PollingTransport.java deleted file mode 100644 index 981875447..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/transport/PollingTransport.java +++ /dev/null @@ -1,193 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.transport; - -import com.fr.third.socketio.Transport; -import com.fr.third.socketio.handler.AuthorizeHandler; -import com.fr.third.socketio.handler.ClientHead; -import com.fr.third.socketio.handler.ClientsBox; -import com.fr.third.socketio.handler.EncoderHandler; -import com.fr.third.socketio.messages.PacketsMessage; -import com.fr.third.socketio.messages.XHROptionsMessage; -import com.fr.third.socketio.messages.XHRPostMessage; -import com.fr.third.socketio.protocol.PacketDecoder; -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.handler.codec.http.*; -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.List; -import java.util.UUID; - -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; - -@Sharable -public class PollingTransport extends ChannelInboundHandlerAdapter { - - public static final String NAME = "polling"; - - private static final Logger log = LoggerFactory.getLogger(PollingTransport.class); - - private final PacketDecoder decoder; - private final ClientsBox clientsBox; - private final AuthorizeHandler authorizeHandler; - - public PollingTransport(PacketDecoder decoder, AuthorizeHandler authorizeHandler, ClientsBox clientsBox) { - this.decoder = decoder; - this.authorizeHandler = authorizeHandler; - this.clientsBox = clientsBox; - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof FullHttpRequest) { - FullHttpRequest req = (FullHttpRequest) msg; - QueryStringDecoder queryDecoder = new QueryStringDecoder(req.uri()); - - List transport = queryDecoder.parameters().get("transport"); - - if (transport != null && NAME.equals(transport.get(0))) { - List sid = queryDecoder.parameters().get("sid"); - List j = queryDecoder.parameters().get("j"); - List b64 = queryDecoder.parameters().get("b64"); - - String origin = req.headers().get(HttpHeaderNames.ORIGIN); - ctx.channel().attr(EncoderHandler.ORIGIN).set(origin); - - String userAgent = req.headers().get(HttpHeaderNames.USER_AGENT); - ctx.channel().attr(EncoderHandler.USER_AGENT).set(userAgent); - - if (j != null && j.get(0) != null) { - Integer index = Integer.valueOf(j.get(0)); - ctx.channel().attr(EncoderHandler.JSONP_INDEX).set(index); - } - if (b64 != null && b64.get(0) != null) { - String flag = b64.get(0); - if ("true".equals(flag)) { - flag = "1"; - } else if ("false".equals(flag)) { - flag = "0"; - } - Integer enable = Integer.valueOf(flag); - ctx.channel().attr(EncoderHandler.B64).set(enable == 1); - } - - try { - if (sid != null && sid.get(0) != null) { - final UUID sessionId = UUID.fromString(sid.get(0)); - handleMessage(req, sessionId, queryDecoder, ctx); - } else { - // first connection - ClientHead client = ctx.channel().attr(ClientHead.CLIENT).get(); - handleMessage(req, client.getSessionId(), queryDecoder, ctx); - } - } finally { - req.release(); - } - return; - } - } - ctx.fireChannelRead(msg); - } - - private void handleMessage(FullHttpRequest req, UUID sessionId, QueryStringDecoder queryDecoder, ChannelHandlerContext ctx) - throws IOException { - String origin = req.headers().get(HttpHeaderNames.ORIGIN); - if (queryDecoder.parameters().containsKey("disconnect")) { - ClientHead client = clientsBox.get(sessionId); - client.onChannelDisconnect(); - ctx.channel().writeAndFlush(new XHRPostMessage(origin, sessionId)); - } else if (HttpMethod.POST.equals(req.method())) { - onPost(sessionId, ctx, origin, req.content()); - } else if (HttpMethod.GET.equals(req.method())) { - onGet(sessionId, ctx, origin); - } else if (HttpMethod.OPTIONS.equals(req.method())) { - onOptions(sessionId, ctx, origin); - } else { - log.error("Wrong {} method invocation for {}", req.method(), sessionId); - sendError(ctx); - } - } - - private void onOptions(UUID sessionId, ChannelHandlerContext ctx, String origin) { - ClientHead client = clientsBox.get(sessionId); - if (client == null) { - log.error("{} is not registered. Closing connection", sessionId); - sendError(ctx); - return; - } - - ctx.channel().writeAndFlush(new XHROptionsMessage(origin, sessionId)); - } - - private void onPost(UUID sessionId, ChannelHandlerContext ctx, String origin, ByteBuf content) - throws IOException { - ClientHead client = clientsBox.get(sessionId); - if (client == null) { - log.error("{} is not registered. Closing connection", sessionId); - sendError(ctx); - return; - } - - - // release POST response before message processing - ctx.channel().writeAndFlush(new XHRPostMessage(origin, sessionId)); - - Boolean b64 = ctx.channel().attr(EncoderHandler.B64).get(); - if (b64 != null && b64) { - Integer jsonIndex = ctx.channel().attr(EncoderHandler.JSONP_INDEX).get(); - content = decoder.preprocessJson(jsonIndex, content); - } - - ctx.pipeline().fireChannelRead(new PacketsMessage(client, content, Transport.POLLING)); - } - - protected void onGet(UUID sessionId, ChannelHandlerContext ctx, String origin) { - ClientHead client = clientsBox.get(sessionId); - if (client == null) { - log.error("{} is not registered. Closing connection", sessionId); - sendError(ctx); - return; - } - - client.bindChannel(ctx.channel(), Transport.POLLING); - - authorizeHandler.connect(client); - } - - private void sendError(ChannelHandlerContext ctx) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR); - ctx.channel().writeAndFlush(res).addListener(ChannelFutureListener.CLOSE); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - final Channel channel = ctx.channel(); - ClientHead client = clientsBox.get(channel); - if (client != null && client.isTransportChannel(ctx.channel(), Transport.POLLING)) { - log.debug("channel inactive {}", client.getSessionId()); - client.releasePollingChannel(channel); - } - super.channelInactive(ctx); - } - -} diff --git a/fine-socketio/src/main/java/com/fr/third/socketio/transport/WebSocketTransport.java b/fine-socketio/src/main/java/com/fr/third/socketio/transport/WebSocketTransport.java deleted file mode 100644 index 31991952d..000000000 --- a/fine-socketio/src/main/java/com/fr/third/socketio/transport/WebSocketTransport.java +++ /dev/null @@ -1,224 +0,0 @@ -/** - * Copyright (c) 2012-2019 Nikita Koksharov - * - * Licensed 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 com.fr.third.socketio.transport; - -import java.util.List; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -import com.fr.third.socketio.protocol.Packet; -import com.fr.third.socketio.protocol.PacketType; -import com.fr.third.slf4j.Logger; -import com.fr.third.slf4j.LoggerFactory; - -import com.fr.third.socketio.Configuration; -import com.fr.third.socketio.SocketIOChannelInitializer; -import com.fr.third.socketio.Transport; -import com.fr.third.socketio.handler.AuthorizeHandler; -import com.fr.third.socketio.handler.ClientHead; -import com.fr.third.socketio.handler.ClientsBox; -import com.fr.third.socketio.messages.PacketsMessage; -import com.fr.third.socketio.scheduler.CancelableScheduler; -import com.fr.third.socketio.scheduler.SchedulerKey; - -import io.netty.buffer.ByteBufHolder; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.QueryStringDecoder; -import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; -import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketFrameAggregator; -import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; -import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory; -import io.netty.util.ReferenceCountUtil; - -@Sharable -public class WebSocketTransport extends ChannelInboundHandlerAdapter { - - public static final String NAME = "websocket"; - - private static final Logger log = LoggerFactory.getLogger(WebSocketTransport.class); - - private final AuthorizeHandler authorizeHandler; - private final CancelableScheduler scheduler; - private final Configuration configuration; - private final ClientsBox clientsBox; - - private final boolean isSsl; - - public WebSocketTransport(boolean isSsl, - AuthorizeHandler authorizeHandler, Configuration configuration, - CancelableScheduler scheduler, ClientsBox clientsBox) { - this.isSsl = isSsl; - this.authorizeHandler = authorizeHandler; - this.configuration = configuration; - this.scheduler = scheduler; - this.clientsBox = clientsBox; - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof CloseWebSocketFrame) { - ctx.channel().writeAndFlush(msg).addListener(ChannelFutureListener.CLOSE); - } else if (msg instanceof BinaryWebSocketFrame - || msg instanceof TextWebSocketFrame) { - ByteBufHolder frame = (ByteBufHolder) msg; - ClientHead client = clientsBox.get(ctx.channel()); - if (client == null) { - log.debug("Client with was already disconnected. Channel closed!"); - ctx.channel().close(); - frame.release(); - return; - } - - ctx.pipeline().fireChannelRead(new PacketsMessage(client, frame.content(), Transport.WEBSOCKET)); - frame.release(); - } else if (msg instanceof FullHttpRequest) { - FullHttpRequest req = (FullHttpRequest) msg; - QueryStringDecoder queryDecoder = new QueryStringDecoder(req.uri()); - String path = queryDecoder.path(); - List transport = queryDecoder.parameters().get("transport"); - List sid = queryDecoder.parameters().get("sid"); - - if (transport != null && NAME.equals(transport.get(0))) { - try { - if (!configuration.getTransports().contains(Transport.WEBSOCKET)) { - log.debug("{} transport not supported by configuration.", Transport.WEBSOCKET); - ctx.channel().close(); - return; - } - if (sid != null && sid.get(0) != null) { - final UUID sessionId = UUID.fromString(sid.get(0)); - handshake(ctx, sessionId, path, req); - } else { - ClientHead client = ctx.channel().attr(ClientHead.CLIENT).get(); - // first connection - handshake(ctx, client.getSessionId(), path, req); - } - } finally { - req.release(); - } - } else { - ctx.fireChannelRead(msg); - } - } else { - ctx.fireChannelRead(msg); - } - } - - @Override - public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { - ClientHead client = clientsBox.get(ctx.channel()); - if (client != null && client.isTransportChannel(ctx.channel(), Transport.WEBSOCKET)) { - ctx.flush(); - } else { - super.channelReadComplete(ctx); - } - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - final Channel channel = ctx.channel(); - ClientHead client = clientsBox.get(channel); - Packet packet = new Packet(PacketType.MESSAGE); - packet.setSubType(PacketType.DISCONNECT); - if (client != null && client.isTransportChannel(ctx.channel(), Transport.WEBSOCKET)) { - log.debug("channel inactive {}", client.getSessionId()); - client.onChannelDisconnect(); - } - super.channelInactive(ctx); - if (client != null) { - client.send(packet); - } - channel.close(); - ctx.close(); - } - - private void handshake(ChannelHandlerContext ctx, final UUID sessionId, String path, FullHttpRequest req) { - final Channel channel = ctx.channel(); - - WebSocketServerHandshakerFactory factory = - new WebSocketServerHandshakerFactory(getWebSocketLocation(req), null, true, configuration.getMaxFramePayloadLength()); - WebSocketServerHandshaker handshaker = factory.newHandshaker(req); - if (handshaker != null) { - ChannelFuture f = handshaker.handshake(channel, req); - f.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (!future.isSuccess()) { - log.error("Can't handshake " + sessionId, future.cause()); - return; - } - - channel.pipeline().addBefore(SocketIOChannelInitializer.WEB_SOCKET_TRANSPORT, SocketIOChannelInitializer.WEB_SOCKET_AGGREGATOR, - new WebSocketFrameAggregator(configuration.getMaxFramePayloadLength())); - connectClient(channel, sessionId); - } - }); - } else { - WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); - } - } - - private void connectClient(final Channel channel, final UUID sessionId) { - ClientHead client = clientsBox.get(sessionId); - if (client == null) { - log.warn("Unauthorized client with sessionId: {} with ip: {}. Channel closed!", - sessionId, channel.remoteAddress()); - channel.close(); - return; - } - - client.bindChannel(channel, Transport.WEBSOCKET); - - authorizeHandler.connect(client); - - if (client.getCurrentTransport() == Transport.POLLING) { - SchedulerKey key = new SchedulerKey(SchedulerKey.Type.UPGRADE_TIMEOUT, sessionId); - scheduler.schedule(key, new Runnable() { - @Override - public void run() { - ClientHead clientHead = clientsBox.get(sessionId); - if (clientHead != null) { - if (log.isDebugEnabled()) { - log.debug("client did not complete upgrade - closing transport"); - } - clientHead.onChannelDisconnect(); - } - } - }, configuration.getUpgradeTimeout(), TimeUnit.MILLISECONDS); - } - - log.debug("сlient {} handshake completed", sessionId); - } - - private String getWebSocketLocation(HttpRequest req) { - String protocol = "ws://"; - if (isSsl) { - protocol = "wss://"; - } - return protocol + req.headers().get(HttpHeaderNames.HOST) + req.uri(); - } - -}