使用apache mina实现简单心跳服务

来源:互联网 发布:孔玮怎么样知乎 编辑:程序博客网 时间:2024/05/17 04:06

有些时候在开发cs应用的时候,服务端需要知道哪些在线和不在线,如果服务端用的是java框架,则可以使用此文章中的示例,这里只用到了mina的很基本的功能,没有使用到其他的高级的功能,主要是实现每多长时间检测一次是否接收到客户端的消息,以及客户端断开后的处理,实现类型在线状态的功能。

1、Server类

缓冲区默认是64字节,一般的服务只需要发送很短的消息,所以用默认的大小就可以了。

package com.qinyi.sitetv.main;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.charset.Charset;import java.util.ResourceBundle;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.TextLineCodecFactory;import org.apache.mina.filter.logging.LoggingFilter;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;public class HearbeatServer {private static final int PORT = 9123;public static void main(String[] args) throws IOException {ResourceBundle bundle = ResourceBundle.getBundle("config");String idleTime = bundle.getString("idle_time");IoAcceptor acceptor = new NioSocketAcceptor();acceptor.getFilterChain().addLast("logger", new LoggingFilter());        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));        acceptor.setHandler(new HearbeatHandler() );          //acceptor.getSessionConfig().setReadBufferSize( 2048 );        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, Integer.valueOf(idleTime) );acceptor.bind(new InetSocketAddress(PORT));}}

2、消息处理类


package com.qinyi.sitetv.main;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.ResourceBundle;import org.apache.log4j.Logger;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;import com.google.gson.Gson;import com.qinyi.sitetv.main.service.HearbeatService;import com.qinyi.sitetv.main.util.HttpClientUtil;public class HearbeatHandler extends IoHandlerAdapter {private Logger log = Logger.getLogger(this.getClass());private ResourceBundle bundle = ResourceBundle.getBundle("config");private static final List<String> orgCodeList;private static Map<String, Long> org2sessionMap = new HashMap<String, Long>();private static Map<Long, String> session2orgMap = new HashMap<Long, String>();private static Map<Long, String> session2record = new HashMap<Long, String>();private HearbeatService hearbeatService = new HearbeatService();static {orgCodeList = new ArrayList<String>();initOrgCodeList();}@SuppressWarnings("unchecked")private static void initOrgCodeList() {String url = ResourceBundle.getBundle("config").getString("xxx");HttpClientUtil hc = new HttpClientUtil(url, null);String result = hc.get();Gson gson = new Gson();List<Map<String, String>> list = gson.fromJson(result, List.class);for (Map<String, String> map : list) {orgCodeList.add(map.get("org_code"));}}@Overridepublic void sessionCreated(IoSession session) throws Exception {log.debug("session " + session.getId() + " is created, address: " + session.getRemoteAddress());}@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {cause.printStackTrace();log.error(cause.getMessage(), cause);}@Overridepublic void messageReceived(IoSession session, Object message) throws Exception {String msg = message.toString();log.info(session.getId() + ", " + msg);if (!orgCodeList.contains(msg.trim()) || "quit".equals(msg)) {session.close(true);log.debug("session id " + session.getId() + ", msg is not available, will be close.");return;}if (!org2sessionMap.containsKey(msg)) {org2sessionMap.put(msg, session.getId());session2orgMap.put(session.getId(), msg);String recordId = hearbeatService.onlineStart(msg);if (recordId != null && !"".equals(recordId) ) {session2record.put(session.getId(), recordId);log.debug("sessionId: " + session.getId() + " =======> recordId: " + recordId);}}}@Overridepublic void sessionIdle(IoSession session, IdleStatus status) throws Exception {log.debug("session id: " + session.getId() + ", idle count: " + session.getIdleCount(status));int maxIdleCount = Integer.valueOf(bundle.getString("max_idle_count"));//如果超过最大次数没有接收到消息,则关闭连接if (session2orgMap.get(session.getId()) == null && session.getIdleCount(status) > maxIdleCount) {session.close(true);log.debug("session id " + session.getId() + ", no msg received, will be close.");return;}if (session.getIdleCount(status) > maxIdleCount) {onlineEnd(session);session.close(true);log.debug("session id " + session.getId() + ", no msg received, will be close.");return;}}@Overridepublic void sessionClosed(IoSession session) throws Exception {log.debug("session " + session.getId() + " is closed");String orgCode = session2orgMap.get(session.getId());if (orgCode != null && !"".equals(orgCode)) {onlineEnd(session);}}private void onlineEnd(IoSession session) {String orgCode = session2orgMap.get(session.getId());String recordId = session2record.get(session.getId());session2orgMap.remove(session.getId());org2sessionMap.remove(orgCode);session2record.remove(session.getId());hearbeatService.onlineEnd(recordId);}}

详细使用可参考:http://blog.csdn.net/defonds/article/details/17996123

0 0