基于UDP的nio日志服务器

来源:互联网 发布:redhat centos 编辑:程序博客网 时间:2024/06/15 01:19

自己做的一个udp日志服务器,请多指教。

服务器启动类:

/** * 日志信息监听服务 * 配置文件在jar包内mongo.properties * @author Administrator *  */@Componentpublic class LogMsgServerWithInJarConfig implements SocketServer {@Resourceprivate NIOSelectorHandler logMsgRequestHandler;@Value("${server.logcenter.udp.port:10000}")private int port;@Overridepublic void accept() throws Exception {SocketHandler handler = new ConcurrentSocketHandler(LogMsgBusinessLogicHandler.class, logMsgRequestHandler);SocketServer server = new UDPServer(port, false, handler);server.accept();}}

服务端基类:

import java.io.IOException;import java.nio.channels.Selector;/** * socket监听服务基类 *  * @author Administrator *  */public abstract class BasicServer implements SocketServer {/** * 系统给出默认端口号 */public static final int DEFAULT_PORT = 8099;/** * 监听端口号 */protected final int port;/** * nio selector */protected Selector select;/** * 是否阻塞 */protected boolean isBlocking = false;/** * 运行状态 */private volatile boolean isRuning = true;public boolean isRuning() {return isRuning;}public void setRuning(boolean isRuning) {this.isRuning = isRuning;}public BasicServer(int port) {this.port = port;}public BasicServer(int port, boolean isBlocking) {this.port = port;this.isBlocking = isBlocking;}@Overridepublic void accept() throws Exception {init();listen();}/** * 初始化连接 */protected abstract void init() throws IOException;/** * 监听处理逻辑 */protected abstract void listen() throws Exception;}

udp服务端实现类:

import java.io.IOException;import java.net.InetSocketAddress;import java.nio.channels.DatagramChannel;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.util.Iterator;/** * udp监听 * @author Administrator * */public final class UDPServer extends BasicServer {/** * udp包byte最大长度 */public static final int MAX_LENGTH = 65507;/** * channel */private DatagramChannel channel;/** * 处理程序 */private SocketHandler handler;public UDPServer(int port, boolean isBlocking, SocketHandler handler) {super(port, isBlocking);this.handler = handler;}public UDPServer(SocketHandler handler) {super(BasicServer.DEFAULT_PORT);this.handler = handler;}@Overrideprotected void init() throws IOException {this.channel = DatagramChannel.open();this.channel.configureBlocking(super.isBlocking);this.channel.bind(new InetSocketAddress(super.port));super.select = Selector.open();this.channel.register(super.select, SelectionKey.OP_READ);}@Overrideprotected void listen() throws Exception {while (isRuning()){if (select.select() <= 0)continue;Iterator<SelectionKey> iterator = select.selectedKeys().iterator();while (iterator.hasNext()){SelectionKey key = iterator.next();iterator.remove();handler.handl(key);}}}}

UDP服务器端请求处理类:

/** * socket请求处理 *  * @author Administrator *  */public class ConcurrentSocketHandler implements SocketHandler {private Class<? extends BusinessLogicHandler> clazz;private NIOSelectorHandler requestHandler;/* * 直接用的Executors工具类生成的线程池,如果有需要可以自己创建 */private ExecutorService executor;public ConcurrentSocketHandler(Class<? extends BusinessLogicHandler> t, NIOSelectorHandler requestHandler) {this.clazz = t;this.requestHandler = requestHandler;this.executor = Executors.newFixedThreadPool(50);}public ConcurrentSocketHandler(Class<? extends BusinessLogicHandler> t, NIOSelectorHandler requestHandler, int threadPoolMaxSize) {this.clazz = t;this.requestHandler = requestHandler;this.executor = Executors.newFixedThreadPool(threadPoolMaxSize);}@Overridepublic void handl(SelectionKey key) throws Exception {Map<String, Object> map = requestHandler.handl(key);if (map != null){BusinessLogicHandler handler = (BusinessLogicHandler) clazz.newInstance();handler.setMap(map);executor.execute(handler);}}}

UDP请求的NIO事件处理:

/** * 日志信息请求处理 *  * @author Administrator *  */@Componentpublic class LogMsgRequestHandler implements NIOSelectorHandler {/** * 在数据map中存储的键值 */public static final String DATA_KEY = "log-msg-request-data-key";@SuppressWarnings("serial")@Overridepublic Map<String, Object> handl(SelectionKey key) throws IOException {// TODO Auto-generated method stubif (!key.isReadable())return null;final ByteBuffer buf = ByteBuffer.allocate(65507);DatagramChannel channel = (DatagramChannel) key.channel();buf.clear();@SuppressWarnings("unused")SocketAddress address = channel.receive(buf);return new HashMap<String, Object>() {{put(DATA_KEY, new String(buf.array()));}};}}


业务逻辑处理接口:

/** * 业务处理接口 * @author Administrator * */public interface BusinessLogicHandler extends Runnable {public void setMap(Map<String, Object> map);}

然后就可以实现 BusinessLogicHandler 接口,进行业务逻辑的处理了。

0 0
原创粉丝点击