mina2官方例证chat服务器

mina2官方例子chat服务器
这是chat服务器里面的main方法入口:
package org.apache.mina.example.chat;

import java.net.InetSocketAddress;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

/**
 * (<b>Entry point</b>) Chat server
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class Main {
    /** 服务器端口号 */
    private static final int PORT = 1234;

    /** 是否启用ssl */
    private static final boolean USE_SSL = false;

    public static void main(String[] args) throws Exception {
    	//实例化一个NioSocketAcceptor
        NioSocketAcceptor acceptor = new NioSocketAcceptor();
        //获取过滤器链
        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
        //实例化MdcInjectionFilter过滤器,针对日志输出做MDC操作,可以参考log4j的MDC、NDC的文档
        MdcInjectionFilter mdcInjectionFilter = new MdcInjectionFilter();
        //添加MdcInjectionFilter过滤器
        chain.addLast("mdc", mdcInjectionFilter);

        //如果开启ssl,则添加ssl支持过滤链
        if (USE_SSL) {
            addSSLSupport(chain);
        }
        /* 添加TextLine编解码过滤器,将一行以换行符为结束符号的byte[]转换成String对象
         * TextLineCodecFactory有TextLineEncoder编码实现,TextLineDecoder解码实现
        */
        chain.addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory()));
        //添加日志过滤器
        addLogger(chain);

        // 设置handler
        acceptor.setHandler(new ChatProtocolHandler());
        //绑定服务器端口
        acceptor.bind(new InetSocketAddress(PORT));

        System.out.println("Listening on port " + PORT);
    }
    /**
     * 添加ssl支持过滤器
     * @param chain	过滤器链
     * @throws Exception
     */
    private static void addSSLSupport(DefaultIoFilterChainBuilder chain)
            throws Exception {
        SslFilter sslFilter = new SslFilter(BogusSslContextFactory
                .getInstance(true));
        chain.addLast("sslFilter", sslFilter);
        System.out.println("SSL ON");
    }
    /**
     * 添加日志过滤器
     * @param chain	过滤器链
     * @throws Exception
     */
    private static void addLogger(DefaultIoFilterChainBuilder chain)
            throws Exception {
        chain.addLast("logger", new LoggingFilter());
        System.out.println("Logging ON");
    }
}

这是协议命令:
package org.apache.mina.example.chat;

/**
 * Encapsulates a chat command. Use {@link #valueOf(String)} to create an
 * instance given a command string.
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class ChatCommand {
    public static final int LOGIN = 0;//登录

    public static final int QUIT = 1;//退出

    public static final int BROADCAST = 2;//广播

    private final int num;

    private ChatCommand(int num) {
        this.num = num;
    }

    public int toInt() {
        return num;
    }
    
    /*
     * 
     */
    public static ChatCommand valueOf(String s) {
        s = s.toUpperCase();
        if ("LOGIN".equals(s)) {
            return new ChatCommand(LOGIN);
        }
        if ("QUIT".equals(s)) {
            return new ChatCommand(QUIT);
        }
        if ("BROADCAST".equals(s)) {
            return new ChatCommand(BROADCAST);
        }

        throw new IllegalArgumentException("Unrecognized command: " + s);
    }
}

这是chatProtocolhandler
package org.apache.mina.example.chat;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * {@link IoHandler} implementation of a simple chat server protocol.
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class ChatProtocolHandler extends IoHandlerAdapter {
    private final static Logger LOGGER = LoggerFactory.getLogger(ChatProtocolHandler.class);
    //客户端session Set集合
    private final Set<IoSession> sessions = Collections
            .synchronizedSet(new HashSet<IoSession>());
    //用户 Set集合
    private final Set<String> users = Collections
            .synchronizedSet(new HashSet<String>());
    
    /**
     * 异常处理
     */
    @Override
    public void exceptionCaught(IoSession session, Throwable cause) {
        LOGGER.warn("Unexpected exception.", cause);
        //如果有未捕获的异常则关闭连接
        session.close(true);
    }
    /**
     * 接收信息处理
     */
    @Override
    public void messageReceived(IoSession session, Object message) {
        Logger log = LoggerFactory.getLogger(ChatProtocolHandler.class);
        log.info("received: " + message);
        //转换成String类型
        String theMessage = (String) message;
        //以空格分隔成两半
        String[] result = theMessage.split(" ", 2);
        //前半段是协议命令
        String theCommand = result[0];
        
        try {
        	//转换成协议命令对象
            ChatCommand command = ChatCommand.valueOf(theCommand);
            //从session取得key为user的值
            //取得当前用户
            String user = (String) session.getAttribute("user");
            
            switch (command.toInt()) {
            //退出
            case ChatCommand.QUIT:
                session.write("QUIT OK");
                session.close(true);
                break;
            //登录
            case ChatCommand.LOGIN:
            	//session里有用户已登录
                if (user != null) {
                    session.write("LOGIN ERROR user " + user
                            + " already logged in.");
                    return;
                }
                //取得后半段的用户名
                if (result.length == 2) {
                    user = result[1];
                } else {
                    session.write("LOGIN ERROR invalid login command.");
                    return;
                }

                //该用户已在线
                //if(isChatUser(user)){
                if (users.contains(user)) {
                    session.write("LOGIN ERROR the name " + user
                            + " is already used.");
                    return;
                }
                //将连接添加到sessions集合中统一管理
                sessions.add(session);
                //设置该session的user属性
                session.setAttribute("user", user);
                //edit me
                MdcInjectionFilter.setProperty(session, "user", user);

                //将用户添加users集合中统一管理
                users.add(user);
                //给客户端返回登录成功消息
                session.write("LOGIN OK");
                //通知所有现在用户有新用户登入
                broadcast("The user " + user + " has joined the chat session.");
                break;
                //广播信息
            case ChatCommand.BROADCAST:
            	//取得后半段用户需要广播的信息内容,并广播
                if (result.length == 2) {
                    broadcast(user + ": " + result[1]);
                }
                break;
                //不认识的命令
            default:
                LOGGER.info("Unhandled command: " + command);
                break;
            }

        } catch (IllegalArgumentException e) {
            LOGGER.debug("Illegal argument", e);
        }
    }
    /**
     * 给所有在线用户广播信息
     * @param message 信息内容
     */
    public void broadcast(String message) {
        synchronized (sessions) {
            for (IoSession session : sessions) {
                if (session.isConnected()) {
                    session.write("BROADCAST OK " + message);
                }
            }
        }
    }
    
    /**
     * 连接断开处理
     */
    @Override
    public void sessionClosed(IoSession session) throws Exception {
        String user = (String) session.getAttribute("user");
        //移除用户以及连接,并通知其他在线用户该用户已离开
        users.remove(user);
        sessions.remove(session);
        broadcast("The user " + user + " has left the chat session.");
    }
    
    /**
     * 判断用户是否在线
     * @param name
     * @return
     */
    public boolean isChatUser(String name) {
        return users.contains(name);
    }
    
    /**
     * 获取在线用户数
     * @return	在线用户数
     */
    public int getNumberOfUsers() {
        return users.size();
    }
    
    /**
     * 强制某用户下线
     * @param name 用户名
     */
    public void kick(String name) {
        synchronized (sessions) {
            for (IoSession session : sessions) {
                if (name.equals(session.getAttribute("user"))) {
                    session.close(true);
                    break;
                }
            }
        }
    }
}