public final class WTFSocketServer {

    /**
     * Spring 上下文
     */
    private ApplicationContext spring = new ClassPathXmlApplicationContext("spring.wtf.socket.xml");

    /**
     * 消息调度组件
     * 根据消息的头信息将消息投递到指定的目的地
     */
    @Resource()
    private WTFSocketScheduler scheduler;

    /**
     * 路由组件
     * 查询和记录连接的地址
     */
    @Resource
    private WTFSocketRouting routing;

    /**
     * 协议族组件
     * IO层收到数据后选择合适的解析器将数据解析为标准消息格式
     */
    @Resource
    private WTFSocketProtocolFamily protocolFamily;

    /**
     * 安全组件
     * 可用添加一些安全策略，如发送数据的授权许可等
     */
    @Resource
    private WTFSocketSecureDelegatesGroup secureDelegatesGroup;

    /**
     * 事件组组件
     * 包含了一些服务器的监听事件
     */
    @Resource
    private WTFSocketEventListenersGroup eventsGroup;

    /**
     * 服务器配置
     */
    private WTFSocketConfig config;

    public WTFSocketServer() {
        spring.getAutowireCapableBeanFactory().autowireBean(this);
        scheduler.setContext(this);
        routing.setContext(this);
    }

    public void run(WTFSocketConfig config) {
        this.config = config;
        scheduler.run();
    }

    public WTFSocketServer addController(WTFSocketController controller) {
        if (scheduler.getHandler() instanceof WTFSocketControllersGroup) {
            ((WTFSocketControllersGroup) scheduler.getHandler()).addController(controller);
        }
        return this;
    }

    public WTFSocketScheduler getScheduler() {
        return scheduler;
    }

    public WTFSocketProtocolFamily getProtocolFamily() {
        return protocolFamily;
    }

    public WTFSocketSecureDelegatesGroup getSecureDelegatesGroup() {
        return secureDelegatesGroup;
    }

    public WTFSocketRouting getRouting() {
        return routing;
    }

    public WTFSocketEventListenersGroup getEventsGroup() {
        return eventsGroup;
    }

    public WTFSocketConfig getConfig() {
        return config;
    }

    public void setScheduler(WTFSocketScheduler scheduler) {
        this.scheduler = scheduler;
    }

    public void setProtocolFamily(WTFSocketProtocolFamily protocolFamily) {
        this.protocolFamily = protocolFamily;
    }

    public void setSecureDelegatesGroup(WTFSocketSecureDelegatesGroup secureDelegatesGroup) {
        this.secureDelegatesGroup = secureDelegatesGroup;
    }

    public void setRouting(WTFSocketRouting routing) {
        this.routing = routing;
    }

    public void setEventsGroup(WTFSocketEventListenersGroup eventsGroup) {
        this.eventsGroup = eventsGroup;
    }

    public WTFSocketConfig setConfig() {
        return config;
    }


    public ApplicationContext getSpring() {
        return spring;
    }
} public interface WTFSocketController {

    /**
     * 控制器优先级
     * 数值越低优先级越高，默认的优先级为 WTFSocketPriority.MEDIUM
     *
     * @return 优先级数值
     */
    default int priority() {
        return WTFSocketPriority.MEDIUM;
    }

    /**
     * 是否响应该消息
     *
     * @param msg 消息对象
     *
     * @return 是否响应
     */
    boolean isResponse(WTFSocketMsg msg);

    /**
     * 控制器工作函数
     * 当控制器的isResponse()方法为true时调用
     * 当控制器工作完成后如果返回true表示该请求被消费，请求传递终止
     * 否则请求继续向下传递
     *
     * @param source    消息发送源
     * @param request   请求消息
     * @param responses 回复消息列表
     *
     * @return 请求是否被消费
     *
     * @throws WTFSocketException 异常消息
     */
    boolean work(WTFSocketRoutingItem source, WTFSocketMsg request, List<WTFSocketMsg> responses) throws WTFSocketException;

} public abstract class WTFSocketException extends Exception {


    public WTFSocketException(String msg) {
        super(msg);
    }

    public abstract int getErrCode();

} public class WTFSocketKeepWordsException extends WTFSocketFatalException {
    public WTFSocketKeepWordsException(String msg) {
        super(msg);
    }

    @Override
    public int getErrCode() {
        return 69;
    }
} public class WTFSocketDefaultIOTerm extends WTFSocketBaseIOTerm {

    private Channel channel;

    @Override
    public void write(String data) {
        if (channel != null && channel.isWritable()) {
            if (StringUtils.equals("TCP", connectType)) {
                ByteBuf byteBuf = Unpooled.copiedBuffer(data.getBytes());
                channel.writeAndFlush(byteBuf);
            }
            if (StringUtils.equals("WebSocket", connectType)) {
                channel.writeAndFlush(new TextWebSocketFrame(data));
            }
        }
    }

    @Override
    public void close() {
        if (channel != null && channel.isOpen()) {
            channel.close();
        }
    }

    public Channel getChannel() {
        return channel;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
    }
} public interface WTFSocketMsg {

    String getIoTag();

    void setIoTag(String ioTag);

    String getFrom();

    void setFrom(String from);

    String getTo();

    void setTo(String to);

    int getMsgId();

    void setMsgId(int msgId);

    int getMsgType();

    void setMsgType(int msgType);

    int getState();

    void setState(int state);

    void setConnectType(String connectType);

    String getConnectType();

    String getVersion();

    void setVersion(String version);

    Object getBody();

    <T> T getBody(Class<T> tClass);

    void setBody(Object body);

    WTFSocketMsg makeResponse();
} @Component
@Scope("prototype")
public class WTFSocketRoutingFormalItem extends WTFSocketRoutingItem {

    /**
     * 授权通讯地址
     */
    private Set<String> authTargetsAddress;

    public boolean isAuthTarget(String targetAddress) {
        return authTargetsAddress != null && (authTargetsAddress.contains("*") || authTargetsAddress.contains(targetAddress));
    }

    public void addAuthTarget(String targetAddress) {
        if (authTargetsAddress == null) {
            authTargetsAddress = new HashSet<String>() {{
                add("server");
            }};
        }
        authTargetsAddress.add(targetAddress);
    }

    public void removeAuthTarget(String targetAddress) {
        if (authTargetsAddress != null) {
            authTargetsAddress.remove(targetAddress);
        }
    }

    public void close() throws WTFSocketException {
        super.close();
        getContext().getRouting().getFormalMap().remove(this);
    }
} @Component
@Scope("prototype")
public abstract class WTFSocketRoutingItem {

    /**
     * 自身通讯地址
     */
    private String address;
    /**
     * 终端对象
     */
    private WTFSocketIOTerm term;
    /**
     * 接受的协议类型
     */
    private String accept;
    /**
     * 终端类型（iOS, Android, Hardware）
     */
    private String deviceType = "Unknown";
    /**
     * 是否允许覆盖
     */
    private boolean cover = true;
    /**
     * 允许用户为客户端添加自定义Tag信息
     */
    private Object tag;

    private WTFSocketServer context;

    public void setAddress(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    public String getAccept() {
        return accept;
    }

    public void setAccept(String accept) {
        this.accept = accept;
    }

    public String getDeviceType() {
        return deviceType;
    }

    public void setDeviceType(String deviceType) {
        this.deviceType = deviceType == null ? "Unknown" : deviceType;
    }

    public WTFSocketIOTerm getTerm() {
        return term;
    }

    public void setTerm(WTFSocketIOTerm term) {
        this.term = term;
    }

    public boolean isCover() {
        return cover;
    }

    public void setCover(boolean cover) {
        this.cover = cover;
    }

    public WTFSocketServer getContext() {
        return context;
    }

    public void setContext(WTFSocketServer context) {
        this.context = context;
    }

    public Object getTag() {
        return tag;
    }

    public void setTag(Object tag) {
        this.tag = tag;
    }

    public void close() throws WTFSocketException {
        getContext().getEventsGroup().publishEvent(this, null, WTFSocketEventsType.Disconnect);
        getTerm().close();
    }
} public interface WTFSocketSecureStrategy {

    void check(WTFSocketServer context, WTFSocketMsg msg) throws WTFSocketException;

    void setNext(WTFSocketSecureStrategy next);

} public abstract class WTFSocketBaseSecureStrategyImpl implements WTFSocketSecureStrategy{

    protected Log logger = LogFactory.getLog(this.getClass());

    protected WTFSocketSecureStrategy next;

    protected void doNext(WTFSocketServer context, WTFSocketMsg msg) throws WTFSocketException {
        if (null != next) {
            next.check(context, msg);
        }
    }

    public void setNext(WTFSocketSecureStrategy next) {
        if (null == this.next) {
            this.next = next;
        } else {
            next.setNext(this.next);
            this.next = next;
        }
    }
} public final class WTFSocketPriority {

    private WTFSocketPriority() {
    }

    public final static int HIGHEST = -3;
    public final static int HIGH = -2;
    public final static int MEDIUM_HIGH = -1;
    public final static int MEDIUM = 0;
    public final static int MEDIUM_LOW = 1;
    public final static int LOW = 2;
    public final static int LOWEST = 3;

}
import org.apache.commons.lang.StringUtils;
import wtf.socket.WTFSocketServer;
import wtf.socket.controller.WTFSocketController;
import wtf.socket.exception.WTFSocketException;
import wtf.socket.exception.fatal.WTFSocketKeepWordsException;
import wtf.socket.io.term.WTFSocketDefaultIOTerm;
import wtf.socket.protocol.WTFSocketMsg;
import wtf.socket.routing.item.WTFSocketRoutingFormalItem;
import wtf.socket.routing.item.WTFSocketRoutingItem;
import wtf.socket.secure.strategy.WTFSocketSecureStrategy;
import wtf.socket.secure.strategy.impl.WTFSocketBaseSecureStrategyImpl;
import wtf.socket.util.WTFSocketPriority;
import java.util.List;
package wtf.socket.controller.impl;



/**
 *
 * Created by ZFly on 2017/5/1.
 */
public enum  WTFSocketHeartbeatControllerImpl implements WTFSocketController {

    INSTANCE;

    WTFSocketHeartbeatControllerImpl() {

    }

    private boolean unInit = true;

    @Override
    public int priority() {
        return WTFSocketPriority.HIGH;
    }

    @Override
    public boolean isResponse(WTFSocketMsg msg) {
        return msg.getMsgType() == 0;
    }

    @Override
    public boolean work(WTFSocketRoutingItem source, WTFSocketMsg request, List<WTFSocketMsg> responses) throws WTFSocketException {
        if (unInit) {
            // 注册heartbeat用户
            final WTFSocketRoutingFormalItem heartbeatItem = new WTFSocketRoutingFormalItem();
            heartbeatItem.setTerm(new WTFSocketDefaultIOTerm());