所需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 stubuserMap = 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 blocke.printStackTrace();}}/*** @param args* @throws IOException */public static void main(String[] args) throws IOException {// TODO Auto-generated method stubnew 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);}@Overridepublic ProtocolEncoder getEncoder(IoSession session) throws Exception {// TODO Auto-generated method stubreturn encoder;}@Overridepublic ProtocolDecoder getDecoder(IoSession session) throws Exception {// TODO Auto-generated method stubreturn 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;}@Overrideprotected boolean doDecode(IoSession session, IoBuffer in,ProtocolDecoderOutput out) throws Exception {// TODO Auto-generated method stubMsg 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;}@Overridepublic void encode(IoSession session, Object message,ProtocolEncoderOutput out) throws Exception {// TODO Auto-generated method stubMsg 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;}
}