所需jar包mina-core.jar,slf4j-api.jar,slf4j-jdk14.jar
最基本的对象,Server端 及其Handler用来接收消息;ProtocolCodecFactory包含decoder和encoder用来对消息进行编解码,可自定义也可使用mina自带的。
client端选择较多,http,telnet,自己写socket连,用mina提供的connector都可以。
贴代码了。
这个例子中写了个简单的聊天服务器,接收客户端消息,并转发给目的客户端。
server:图方便,直接继承IoHandlerAdapter 。用以map存储连接的用户
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Hashtable;
import java.util.Map;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class Server extends IoHandlerAdapter {
private Map<Integer, IoSession> userMap;
public Server() {
super();
// TODO Auto-generated constructor stub
userMap = new Hashtable<Integer, IoSession>();
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CFactory("server")));
acceptor.setHandler(this);
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
try {
acceptor.bind(new InetSocketAddress(Constants.PORT));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
new Server();
}
/* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#messageReceived(org.apache.mina.core.session.IoSession, java.lang.Object)
*/
public void messageReceived(IoSession session, Object message) throws Exception {
Msg msg = (Msg)message;
System.out.println(msg.toString());
userMap.put(msg.getFuserId(), session);
if(msg.getTuserId() > 0 && userMap.get(msg.getTuserId()) != null) {
userMap.get(msg.getTuserId()).write(msg);
}
}
}
ProtocolCodecFactory:
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
public class CFactory implements ProtocolCodecFactory {
private ProtocolDecoder decoder;
private ProtocolEncoder encoder;
public CFactory(String name) {
this(name, false);
}
public CFactory(String name, boolean showLog) {
decoder = new BDecoder(name, showLog);
encoder = new BEncoder(name, showLog);
}
@Override
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
// TODO Auto-generated method stub
return encoder;
}
@Override
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
// TODO Auto-generated method stub
return decoder;
}
}
decoder:从会话中读出数据并转为对象,写入输出流
import java.nio.charset.Charset;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
public class BDecoder extends CumulativeProtocolDecoder {
private String name;
private boolean showLog;
public BDecoder(String name, boolean showLog) {
super();
this.name = name;
this.showLog = showLog;
}
@Override
protected boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
// TODO Auto-generated method stub
Msg msg = new Msg(in.getInt(), in.getInt(), in.getInt(),
in.getString(Charset.forName(Constants.DEFAULTCHARSET).newDecoder()));
out.write(msg);
if(showLog) {
String log = msg.toString() + "\t" + name + " decode";
System.out.println(log);
}
return true;
}
}
encoder:将对象转为IObuffer并写入输出流
import java.nio.charset.Charset;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
public class BEncoder extends ProtocolEncoderAdapter {
private String name;
private boolean showLog;
public BEncoder(String name, boolean showLog) {
super();
this.name = name;
this.showLog = showLog;
}
@Override
public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
// TODO Auto-generated method stub
Msg msg = (Msg)message;
if(showLog) {
String log = msg.toString() + "\t" + name + " encode";
System.out.println(log);
}
IoBuffer buffer = IoBuffer.allocate(0, false);
buffer.setAutoExpand(true);
buffer.putInt(msg.getCode());
buffer.putInt(msg.getFuserId());
buffer.putInt(msg.getTuserId());
buffer.putString(msg.getMsg(), Charset.forName(Constants.DEFAULTCHARSET).newEncoder());
buffer.flip();
out.write(buffer);
}
}
client端:图方便
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Vector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
public class Client extends IoHandlerAdapter {
private int id;
private SocketConnector connector;
private InetSocketAddress address;
private List<Msg> list;
public Client(int id) {
super();
this.id = id;
list = new Vector<Msg>();
connector = new NioSocketConnector();
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CFactory("client_" + id)));
connector.setHandler(this);
address = new InetSocketAddress("127.0.0.1", Constants.PORT);
list.add(new Msg(0,id, 0, ""));
connector.connect(address);
}
public void send(Msg msg) throws Exception {
list.add(msg);
connector.connect(address);
}
public void messageReceived(IoSession session, Object message) throws Exception {
System.out.println("messageReceived:" + message.toString());
}
public void sessionCreated(IoSession session) throws Exception {
System.out.println("sessionCreated");
synchronized(list) {
if(list != null && !list.isEmpty()) {
session.write(list.get(0));
list.remove(0);
}
}
}
public void sessionOpened(IoSession session) throws Exception {
System.out.println("sessionOpened");
}
public int getId() {
return id;
}
}
常量类
public class Constants {
public static final String DEFAULTCHARSET = "UTF-8";
public static final int PORT = 9125;
}
消息对象
import java.io.Serializable;
public class Msg implements Serializable {
private static final long serialVersionUID = 3352801416609666672L;
private int code;
private int fuserId;
private int tuserId;
private String msg;
public String toString() {
return new StringBuilder()
.append("code:").append(code)
.append("fuserId:").append(fuserId)
.append("tuserId:").append(tuserId)
.append("msg").append(msg)
.toString();
}
public Msg() {
super();
// TODO Auto-generated constructor stub
}
public Msg(int code, int fuserId, int tuserId, String msg) {
super();
this.code = code;
this.fuserId = fuserId;
this.tuserId = tuserId;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public int getFuserId() {
return fuserId;
}
public void setFuserId(int fuserId) {
this.fuserId = fuserId;
}
public int getTuserId() {
return tuserId;
}
public void setTuserId(int tuserId) {
this.tuserId = tuserId;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
客户端启动类
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Mc {
public static void main(String[] args) throws Exception {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
String s = null;
Client c = new Client(Integer.parseInt(args[0]));
// Client c = null;
// if((s = r.readLine()) != null)
// c = new Client(Integer.parseInt(s));
while((s = r.readLine()) != null) {
String[] ss = createClient(s);
if(ss != null)
c.send(new Msg(0, c.getId(), Integer.parseInt(ss[0]), ss[1]));
}
}
public static String[] createClient(String s) {
for(int i = 0; i < s.length(); i ++) {
if(s.charAt(i) == ' ')
return new String[]{s.substring(0, i), s.substring(i)};
}
return null;
}
}