|
|
@ -1,12 +1,12 @@ |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Copyright 2012 Nikita Koksharov |
|
|
|
* Copyright (c) 2012-2019 Nikita Koksharov |
|
|
|
* <p> |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* You may obtain a copy of the License at |
|
|
|
* You may obtain a copy of the License at |
|
|
|
* <p> |
|
|
|
* |
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
* <p> |
|
|
|
* |
|
|
|
* Unless required by applicable law or agreed to in writing, software |
|
|
|
* Unless required by applicable law or agreed to in writing, software |
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
|
@ -15,7 +15,6 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package com.fr.third.socketio; |
|
|
|
package com.fr.third.socketio; |
|
|
|
|
|
|
|
|
|
|
|
import com.fr.third.socketio.listener.*; |
|
|
|
|
|
|
|
import com.fr.third.socketio.listener.ClientListeners; |
|
|
|
import com.fr.third.socketio.listener.ClientListeners; |
|
|
|
import com.fr.third.socketio.listener.ConnectListener; |
|
|
|
import com.fr.third.socketio.listener.ConnectListener; |
|
|
|
import com.fr.third.socketio.listener.DataListener; |
|
|
|
import com.fr.third.socketio.listener.DataListener; |
|
|
@ -39,7 +38,6 @@ import java.util.Collection; |
|
|
|
import java.util.UUID; |
|
|
|
import java.util.UUID; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
|
|
|
|
import io.netty.util.concurrent.GenericFutureListener; |
|
|
|
|
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
|
|
|
@ -48,27 +46,24 @@ import com.fr.third.socketio.namespace.NamespacesHub; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Fully thread-safe. |
|
|
|
* Fully thread-safe. |
|
|
|
|
|
|
|
* |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class SocketIOServer implements ClientListeners { |
|
|
|
public class SocketIOServer implements ClientListeners { |
|
|
|
|
|
|
|
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(SocketIOServer.class); |
|
|
|
private static final Logger log = LoggerFactory.getLogger(SocketIOServer.class); |
|
|
|
|
|
|
|
|
|
|
|
private final Configuration configCopy; |
|
|
|
private final Configuration configCopy; |
|
|
|
|
|
|
|
|
|
|
|
private final Configuration configuration; |
|
|
|
private final Configuration configuration; |
|
|
|
|
|
|
|
|
|
|
|
private final NamespacesHub namespacesHub; |
|
|
|
private final NamespacesHub namespacesHub; |
|
|
|
|
|
|
|
|
|
|
|
private final SocketIONamespace mainNamespace; |
|
|
|
private final SocketIONamespace mainNamespace; |
|
|
|
|
|
|
|
|
|
|
|
private SocketIOChannelInitializer pipelineFactory = new SocketIOChannelInitializer(); |
|
|
|
private SocketIOChannelInitializer pipelineFactory = new SocketIOChannelInitializer(); |
|
|
|
|
|
|
|
|
|
|
|
private EventLoopGroup bossGroup; |
|
|
|
private EventLoopGroup bossGroup; |
|
|
|
|
|
|
|
|
|
|
|
private EventLoopGroup workerGroup; |
|
|
|
private EventLoopGroup workerGroup; |
|
|
|
|
|
|
|
|
|
|
|
public SocketIOServer(Configuration configuration) { |
|
|
|
public SocketIOServer(Configuration configuration) { |
|
|
|
|
|
|
|
|
|
|
|
this.configuration = configuration; |
|
|
|
this.configuration = configuration; |
|
|
|
this.configCopy = new Configuration(configuration); |
|
|
|
this.configCopy = new Configuration(configuration); |
|
|
|
namespacesHub = new NamespacesHub(configCopy); |
|
|
|
namespacesHub = new NamespacesHub(configCopy); |
|
|
@ -76,7 +71,6 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void setPipelineFactory(SocketIOChannelInitializer pipelineFactory) { |
|
|
|
public void setPipelineFactory(SocketIOChannelInitializer pipelineFactory) { |
|
|
|
|
|
|
|
|
|
|
|
this.pipelineFactory = pipelineFactory; |
|
|
|
this.pipelineFactory = pipelineFactory; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -86,7 +80,6 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
* @return clients collection |
|
|
|
* @return clients collection |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Collection<SocketIOClient> getAllClients() { |
|
|
|
public Collection<SocketIOClient> getAllClients() { |
|
|
|
|
|
|
|
|
|
|
|
return namespacesHub.get(Namespace.DEFAULT_NAME).getAllClients(); |
|
|
|
return namespacesHub.get(Namespace.DEFAULT_NAME).getAllClients(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -97,7 +90,6 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
* @return client |
|
|
|
* @return client |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public SocketIOClient getClient(UUID uuid) { |
|
|
|
public SocketIOClient getClient(UUID uuid) { |
|
|
|
|
|
|
|
|
|
|
|
return namespacesHub.get(Namespace.DEFAULT_NAME).getClient(uuid); |
|
|
|
return namespacesHub.get(Namespace.DEFAULT_NAME).getClient(uuid); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -107,12 +99,10 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
* @return namespaces collection |
|
|
|
* @return namespaces collection |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Collection<SocketIONamespace> getAllNamespaces() { |
|
|
|
public Collection<SocketIONamespace> getAllNamespaces() { |
|
|
|
|
|
|
|
|
|
|
|
return namespacesHub.getAllNamespaces(); |
|
|
|
return namespacesHub.getAllNamespaces(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public BroadcastOperations getBroadcastOperations() { |
|
|
|
public BroadcastOperations getBroadcastOperations() { |
|
|
|
|
|
|
|
|
|
|
|
return new BroadcastOperations(getAllClients(), configCopy.getStoreFactory()); |
|
|
|
return new BroadcastOperations(getAllClients(), configCopy.getStoreFactory()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -124,7 +114,6 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
* @return broadcast operations |
|
|
|
* @return broadcast operations |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public BroadcastOperations getRoomOperations(String room) { |
|
|
|
public BroadcastOperations getRoomOperations(String room) { |
|
|
|
|
|
|
|
|
|
|
|
Iterable<SocketIOClient> clients = namespacesHub.getRoomClients(room); |
|
|
|
Iterable<SocketIOClient> clients = namespacesHub.getRoomClients(room); |
|
|
|
return new BroadcastOperations(clients, configCopy.getStoreFactory()); |
|
|
|
return new BroadcastOperations(clients, configCopy.getStoreFactory()); |
|
|
|
} |
|
|
|
} |
|
|
@ -133,41 +122,15 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
* Start server |
|
|
|
* Start server |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void start() { |
|
|
|
public void start() { |
|
|
|
|
|
|
|
|
|
|
|
startAsync().syncUninterruptibly(); |
|
|
|
startAsync().syncUninterruptibly(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void start(GenericFutureListener<? extends Future<? super Void>> listener) { |
|
|
|
|
|
|
|
startAsync(listener).syncUninterruptibly(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Start server asynchronously |
|
|
|
* Start server asynchronously |
|
|
|
* |
|
|
|
* |
|
|
|
* @return void |
|
|
|
* @return void |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Future<Void> startAsync() { |
|
|
|
public Future<Void> startAsync() { |
|
|
|
return startAsync(new FutureListener<Void>() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void operationComplete(Future<Void> 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<Void> startAsync(GenericFutureListener<? extends Future<? super Void>> listener) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.info("Session store / pubsub factory used: {}", configCopy.getStoreFactory()); |
|
|
|
log.info("Session store / pubsub factory used: {}", configCopy.getStoreFactory()); |
|
|
|
initGroups(); |
|
|
|
initGroups(); |
|
|
|
|
|
|
|
|
|
|
@ -180,8 +143,8 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
|
|
|
|
|
|
|
|
ServerBootstrap b = new ServerBootstrap(); |
|
|
|
ServerBootstrap b = new ServerBootstrap(); |
|
|
|
b.group(bossGroup, workerGroup) |
|
|
|
b.group(bossGroup, workerGroup) |
|
|
|
.channel(channelClass) |
|
|
|
.channel(channelClass) |
|
|
|
.childHandler(pipelineFactory); |
|
|
|
.childHandler(pipelineFactory); |
|
|
|
applyConnectionOptions(b); |
|
|
|
applyConnectionOptions(b); |
|
|
|
|
|
|
|
|
|
|
|
InetSocketAddress addr = new InetSocketAddress(configCopy.getPort()); |
|
|
|
InetSocketAddress addr = new InetSocketAddress(configCopy.getPort()); |
|
|
@ -189,11 +152,19 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
addr = new InetSocketAddress(configCopy.getHostname(), configCopy.getPort()); |
|
|
|
addr = new InetSocketAddress(configCopy.getHostname(), configCopy.getPort()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return b.bind(addr).addListener(listener); |
|
|
|
return b.bind(addr).addListener(new FutureListener<Void>() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void operationComplete(Future<Void> 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()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected void applyConnectionOptions(ServerBootstrap bootstrap) { |
|
|
|
protected void applyConnectionOptions(ServerBootstrap bootstrap) { |
|
|
|
|
|
|
|
|
|
|
|
SocketConfig config = configCopy.getSocketConfig(); |
|
|
|
SocketConfig config = configCopy.getSocketConfig(); |
|
|
|
bootstrap.childOption(ChannelOption.TCP_NODELAY, config.isTcpNoDelay()); |
|
|
|
bootstrap.childOption(ChannelOption.TCP_NODELAY, config.isTcpNoDelay()); |
|
|
|
if (config.getTcpSendBufferSize() != -1) { |
|
|
|
if (config.getTcpSendBufferSize() != -1) { |
|
|
@ -211,7 +182,6 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected void initGroups() { |
|
|
|
protected void initGroups() { |
|
|
|
|
|
|
|
|
|
|
|
if (configCopy.isUseLinuxNativeEpoll()) { |
|
|
|
if (configCopy.isUseLinuxNativeEpoll()) { |
|
|
|
bossGroup = new EpollEventLoopGroup(configCopy.getBossThreads()); |
|
|
|
bossGroup = new EpollEventLoopGroup(configCopy.getBossThreads()); |
|
|
|
workerGroup = new EpollEventLoopGroup(configCopy.getWorkerThreads()); |
|
|
|
workerGroup = new EpollEventLoopGroup(configCopy.getWorkerThreads()); |
|
|
@ -225,7 +195,6 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
* Stop server |
|
|
|
* Stop server |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void stop() { |
|
|
|
public void stop() { |
|
|
|
|
|
|
|
|
|
|
|
bossGroup.shutdownGracefully().syncUninterruptibly(); |
|
|
|
bossGroup.shutdownGracefully().syncUninterruptibly(); |
|
|
|
workerGroup.shutdownGracefully().syncUninterruptibly(); |
|
|
|
workerGroup.shutdownGracefully().syncUninterruptibly(); |
|
|
|
|
|
|
|
|
|
|
@ -233,31 +202,22 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
log.info("SocketIO server stopped"); |
|
|
|
log.info("SocketIO server stopped"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Stop server |
|
|
|
|
|
|
|
* 不等待 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void stopImmediately() { |
|
|
|
public void stopImmediately() { |
|
|
|
|
|
|
|
this.bossGroup.shutdownGracefully(0L, 1L, TimeUnit.SECONDS).syncUninterruptibly(); |
|
|
|
bossGroup.shutdownGracefully(0L, 1L, TimeUnit.SECONDS).syncUninterruptibly(); |
|
|
|
this.workerGroup.shutdownGracefully(0L, 1L, TimeUnit.SECONDS).syncUninterruptibly(); |
|
|
|
workerGroup.shutdownGracefully(0L, 1L, TimeUnit.SECONDS).syncUninterruptibly(); |
|
|
|
this.pipelineFactory.stop(); |
|
|
|
|
|
|
|
|
|
|
|
pipelineFactory.stop(); |
|
|
|
|
|
|
|
log.info("SocketIO server stopped"); |
|
|
|
log.info("SocketIO server stopped"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public SocketIONamespace addNamespace(String name) { |
|
|
|
public SocketIONamespace addNamespace(String name) { |
|
|
|
|
|
|
|
|
|
|
|
return namespacesHub.create(name); |
|
|
|
return namespacesHub.create(name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public SocketIONamespace getNamespace(String name) { |
|
|
|
public SocketIONamespace getNamespace(String name) { |
|
|
|
|
|
|
|
|
|
|
|
return namespacesHub.get(name); |
|
|
|
return namespacesHub.get(name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void removeNamespace(String name) { |
|
|
|
public void removeNamespace(String name) { |
|
|
|
|
|
|
|
|
|
|
|
namespacesHub.remove(name); |
|
|
|
namespacesHub.remove(name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -269,55 +229,46 @@ public class SocketIOServer implements ClientListeners { |
|
|
|
* @return Configuration object |
|
|
|
* @return Configuration object |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Configuration getConfiguration() { |
|
|
|
public Configuration getConfiguration() { |
|
|
|
|
|
|
|
|
|
|
|
return configuration; |
|
|
|
return configuration; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addMultiTypeEventListener(String eventName, MultiTypeEventListener listener, Class<?>... eventClass) { |
|
|
|
public void addMultiTypeEventListener(String eventName, MultiTypeEventListener listener, Class<?>... eventClass) { |
|
|
|
|
|
|
|
|
|
|
|
mainNamespace.addMultiTypeEventListener(eventName, listener, eventClass); |
|
|
|
mainNamespace.addMultiTypeEventListener(eventName, listener, eventClass); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public <T> void addEventListener(String eventName, Class<T> eventClass, DataListener<T> listener) { |
|
|
|
public <T> void addEventListener(String eventName, Class<T> eventClass, DataListener<T> listener) { |
|
|
|
|
|
|
|
|
|
|
|
mainNamespace.addEventListener(eventName, eventClass, listener); |
|
|
|
mainNamespace.addEventListener(eventName, eventClass, listener); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void removeAllListeners(String eventName) { |
|
|
|
public void removeAllListeners(String eventName) { |
|
|
|
|
|
|
|
|
|
|
|
mainNamespace.removeAllListeners(eventName); |
|
|
|
mainNamespace.removeAllListeners(eventName); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addDisconnectListener(DisconnectListener listener) { |
|
|
|
public void addDisconnectListener(DisconnectListener listener) { |
|
|
|
|
|
|
|
|
|
|
|
mainNamespace.addDisconnectListener(listener); |
|
|
|
mainNamespace.addDisconnectListener(listener); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addConnectListener(ConnectListener listener) { |
|
|
|
public void addConnectListener(ConnectListener listener) { |
|
|
|
|
|
|
|
|
|
|
|
mainNamespace.addConnectListener(listener); |
|
|
|
mainNamespace.addConnectListener(listener); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addPingListener(PingListener listener) { |
|
|
|
public void addPingListener(PingListener listener) { |
|
|
|
|
|
|
|
|
|
|
|
mainNamespace.addPingListener(listener); |
|
|
|
mainNamespace.addPingListener(listener); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addListeners(Object listeners) { |
|
|
|
public void addListeners(Object listeners) { |
|
|
|
|
|
|
|
|
|
|
|
mainNamespace.addListeners(listeners); |
|
|
|
mainNamespace.addListeners(listeners); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addListeners(Object listeners, Class<?> listenersClass) { |
|
|
|
public void addListeners(Object listeners, Class<?> listenersClass) { |
|
|
|
|
|
|
|
|
|
|
|
mainNamespace.addListeners(listeners, listenersClass); |
|
|
|
mainNamespace.addListeners(listeners, listenersClass); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|