Search in sources :

Example 1 with Borning

use of org.nutz.lang.born.Borning in project nutz by nutzam.

the class Sockets method localListen.

/**
     * 监听本地某一个端口,根据用户输入的命令的不同,执行不同的操作
     * <p>
     * 当然,你如果想让一个过程处理多种命令,请给的 key 前用 "REGEX:" 作为前缀,后面用一个正则表达式 来表示你的你要的匹配的命令 <br>
     * "REGEX:!" 开头的,表示后面的正则表达式是一个命令过滤,所有没有匹配上的命令都会被处理
     * 
     * @param port
     *            要监听的端口
     * @param actions
     *            动作执行类映射表
     * @param service
     *            线程池的实现类
     */
@SuppressWarnings("rawtypes")
public static void localListen(int port, Map<String, SocketAction> actions, ExecutorService service, Class<? extends SocketAtom> klass) {
    try {
        // 建立动作映射表
        SocketActionTable saTable = new SocketActionTable(actions);
        // 初始化 socket 接口
        final ServerSocket server;
        try {
            server = new ServerSocket(port);
        } catch (IOException e1) {
            throw Lang.wrapThrow(e1);
        }
        if (log.isInfoEnabled())
            log.infof("Local socket is up at :%d with %d action ready", port, actions.size());
        final Context context = Lang.context();
        context.set("stop", false);
        /*
             * 启动一个守护线程,判断是否该关闭 socket 服务
             */
        (new Thread() {

            @Override
            public void run() {
                setName("Nutz.Sockets monitor thread");
                while (true) {
                    try {
                        Thread.sleep(1000);
                        if (context.getBoolean("stop")) {
                            try {
                                server.close();
                            } catch (Throwable e) {
                            }
                            return;
                        }
                    } catch (Throwable e) {
                    }
                }
            }
        }).start();
        /*
             * 准备 SocketAtom 的生成器
             */
        Borning borning = Mirror.me(klass).getBorningByArgTypes(Context.class, Socket.class, SocketActionTable.class);
        if (borning == null) {
            log.error("boring == null !!!!");
            return;
        }
        /*
             * 进入监听循环
             */
        while (!context.getBoolean("stop")) {
            try {
                if (log.isDebugEnabled())
                    log.debug("Waiting for new socket");
                Socket socket = server.accept();
                if (context.getBoolean("stop")) {
                    Sockets.safeClose(socket);
                    // 监护线程也许还是睡觉,还没来得及关掉哦,所以自己检查一下
                    break;
                }
                if (log.isDebugEnabled())
                    log.debug("accept a new socket, create new SocketAtom to handle it ...");
                Runnable runnable = (Runnable) borning.born(new Object[] { context, socket, saTable });
                service.execute(runnable);
            } catch (Throwable e) {
                log.info("Throwable catched!! maybe ask to exit", e);
            }
        }
        if (!server.isClosed()) {
            try {
                server.close();
            } catch (Throwable e) {
            }
        }
        log.info("Seem stop signal was got, wait 15 for all running thread");
        try {
            service.shutdown();
            service.awaitTermination(15, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
        }
        try {
            service.shutdownNow();
        } catch (Throwable e2) {
        }
    } catch (RuntimeException e) {
        throw e;
    } finally {
        if (log.isInfoEnabled())
            log.info("Stop services ...");
        service.shutdown();
    }
    if (log.isInfoEnabled())
        log.infof("Local socket is down for :%d", port);
}
Also used : Context(org.nutz.lang.util.Context) Borning(org.nutz.lang.born.Borning) ServerSocket(java.net.ServerSocket) IOException(java.io.IOException) Socket(java.net.Socket) ServerSocket(java.net.ServerSocket)

Aggregations

IOException (java.io.IOException)1 ServerSocket (java.net.ServerSocket)1 Socket (java.net.Socket)1 Borning (org.nutz.lang.born.Borning)1 Context (org.nutz.lang.util.Context)1