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;
}
}
}
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值