问题描述
- 大师帮忙实现客户端的一对一会话,谢了。
-
import java.net.InetSocketAddress;
import java.nio.charset.Charset;import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/**
*服务端
*/
public class MinaServer {
protected static Logger logger = LoggerFactory.getLogger(MinaServer.class);
static int PORT=7082;
static IoAcceptor acceptor=null;public static void main(String[] args){ try{ acceptor=new NioSocketAcceptor(); //设置编码过滤器 acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter( new TextLineCodecFactory(Charset.forName("UTF-8"), LineDelimiter.WINDOWS.getValue(), LineDelimiter.WINDOWS.getValue()))); //设置缓冲区的大小 acceptor.getSessionConfig().setReadBufferSize(1024); acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 90); acceptor.setHandler(new Myhandler()); acceptor.bind(new InetSocketAddress(PORT)); logger.info("服务端启动成功... 端口号为:" + PORT); }catch(Exception e){ logger.error("服务端启动异常....", e); e.printStackTrace(); } }
}
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/**
*服务端处理器:- */
public class Myhandler extends IoHandlerAdapter{
protected static Logger logger = LoggerFactory.getLogger(Myhandler.class);// 发送消息异常时触发
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {logger.error("服务端发送消息异常"+cause);
}
// 接收到消息时触发
@Override
public void messageReceived(IoSession session, Object message) throws Exception {//获取客户端发过来的key String key = message.toString(); logger.info("message :"+message.toString()); String carPark_id = key.substring(key.indexOf("=") + 1); logger.info("carPark_id :"+carPark_id); //保存客户端的会话session SessionMap sessionMap = SessionMap.newInstance(); sessionMap.addSession(carPark_id, session); sessionMap.getSession(key);
// String msg=(String) message;
// logger.info("服务端接收到数据"+msg);
// if("exit".equals(msg)){
// session.close(true);
// }
// Date date=new Date();
// SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
// session.write(sdf.format(date));// //拿到所有的客户端Session
// Collection sessions = session.getService().getManagedSessions().values();
// for (IoSession sess : sessions) {// sess.write("所有客户端收到消息");
// }
} // 发送消息成功后触发 @Override public void messageSent(IoSession session, Object message) throws Exception { logger.info("服务端发送信息成功!"); } // 会话关闭时触发 @Override public void sessionClosed(IoSession session) throws Exception { logger.debug("客户端与服务端断开连接!"); } // 创建会话时触发 @Override public void sessionCreated(IoSession session) throws Exception { logger.info("sessionCreated"); } // 会话空闲时触发 // 当连接空闲时被触发。使用IoSessionConfig中的setIdleTime(IdleStatus status, int // idleTime)方法可以设置session的空闲时间。如果该Session的空闲时间超过设置的值,该方法被触发,可以通过session.getIdleCount(status)来获取sessionIdle被触发的次数。 @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { logger.info("服务端进入空闲状态..."); } // 打开会话时触发 // 会话创建之后--》会话打开 @Override public void sessionOpened(IoSession session) throws Exception { logger.info("服务端与客户端已连接sessionOpened"); }
}
import java.net.InetSocketAddress;
import java.nio.charset.Charset;import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
/**- 客户端
*/
public class MinaClient {private static String host="127.0.0.1";
private static int port=7082;
public static void main(String[] args) {
// TODO Auto-generated method stub
IoSession session=null;
// 创建一个非阻塞的客户端程序
IoConnector connector=new NioSocketConnector();
// 设置链接超时时间
connector.setConnectTimeoutMillis(3000*10);
//设置过滤器
connector.getFilterChain().addLast("coderc", new ProtocolCodecFilter(
new TextLineCodecFactory(Charset.forName("UTF-8"),
LineDelimiter.WINDOWS.getValue(),
LineDelimiter.WINDOWS.getValue())));
connector.setHandler(new MyClientHandler());
//连接到服务端
ConnectFuture future=connector.connect(new InetSocketAddress(host,port));
future.awaitUninterruptibly(); //等待我们的连接
session=future.getSession();
session.write("你好!服务大哥");
session.getCloseFuture().awaitUninterruptibly(); //等待关闭链接
connector.dispose();
}
}
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class MyClientHandler extends IoHandlerAdapter {
protected static Logger logger = LoggerFactory.getLogger(MyClientHandler.class);// 发送消息异常时触发 @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { logger.debug("客户端发送消息异常exceptionCaught"); } // 接收到消息时触发 @Override public void messageReceived(IoSession session, Object message) throws Exception {
// String msg=(String) message;
// logger.info("客户端收到数据:"+msg);
logger.info("-----服务端返回的json数据----");
String s = message.toString();
logger.info("客户端收到消息: :" + s);
logger.info("消息长度为:" + s.length());
}@Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { // TODO 自动生成的方法存根 logger.info("-客户端与服务端连接[空闲] - " + status.toString()); if(session != null){ session.close(true); } }
}
import java.util.HashMap;
import java.util.Map;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/**
- @Description: 单例工具类,保存所有mina客户端连接
- @author whl
- @date 2014-9-29 上午10:09:15
*
*/
public class SessionMap {private final static Logger LOGGER=LoggerFactory.getLogger(SessionMap.class);
private static SessionMap sessionMap = null;
private Mapmap = new HashMap();
//构造私有化 单例
private SessionMap(){}/**
- @Description: 获取唯一实例
- @author whl
- @date 2014-9-29 下午1:29:33
*/
public static SessionMap newInstance(){
LOGGER.debug("SessionMap单例获取---");
if(sessionMap == null){
sessionMap = new SessionMap();
}
return sessionMap;
}
/**
- @Description: 保存session会话
- @author whl
- @date 2014-9-29 下午1:31:05
*/
public void addSession(String key, IoSession session){
LOGGER.debug("保存会话到SessionMap单例---key=" + key);
this.map.put(key, session);
}
/**
- @Description: 根据key查找缓存的session
- @author whl
- @date 2014-9-29 下午1:31:55
*/
public IoSession getSession(String key){
LOGGER.debug("获取会话从SessionMap单例---key=" + key);
return this.map.get(key);
}
/**
- @Description: 发送消息到客户端
- @author whl
- @date 2014-9-29 下午1:57:51
*/
public void sendMessage(String[] keys, Object message){
for(String key : keys){
IoSession session = getSession(key);
LOGGER.debug("反向发送消息到客户端Session---key=" + key + "----------消息=" + message);
if(session == null){
return;
}
session.write(message);}
}
}
- */
解决方案
1.有两个思路,一个是服务器中转方式
2.另外一个方式是让需要通信的客户端都在服务器哪里登记,客户端从服务器获取其他客户端的地址信息,然后直接和其他客户端建立连接。