`

mina2 请求过滤器实现

    博客分类:
  • mina
 
阅读更多
/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
package org.apache.mina.filter.firewall;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.mina.core.filterchain.IoFilter;
import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A {@link IoFilter} which blocks connections from connecting
 * at a rate faster than the specified interval.
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class ConnectionThrottleFilter extends IoFilterAdapter {
    /** A logger for this class */
    private final static Logger LOGGER = LoggerFactory.getLogger(ConnectionThrottleFilter.class);

    /** The default delay to wait for a session to be accepted again */
    private static final long DEFAULT_TIME = 1000;

    /**
     * The minimal delay the sessions will have to wait before being created
     * again
     */
    private long allowedInterval;

    /** The map of created sessiosn, associated with the time they were created */
    private final Map<String, Long> clients;

    /** A lock used to protect the map from concurrent modifications */
    private Lock lock = new ReentrantLock();

    // A thread that is used to remove sessions that have expired since they
    // have
    // been added.
    private class ExpiredSessionThread extends Thread {
        public void run() {

            try {
                // Wait for the delay to be expired
                Thread.sleep(allowedInterval);
            } catch (InterruptedException e) {
                // We have been interrupted, get out of the loop.
                return;
            }

            // now, remove all the sessions that have been created
            // before the delay
            long currentTime = System.currentTimeMillis();

            lock.lock();

            try {
                Iterator<String> sessions = clients.keySet().iterator();

                while (sessions.hasNext()) {
                    String session = sessions.next();
                    long creationTime = clients.get(session);

                    if (creationTime + allowedInterval < currentTime) {
                        clients.remove(session);
                    }
                }
            } finally {
                lock.unlock();
            }
        }
    }

    /**
     * Default constructor.  Sets the wait time to 1 second
     */
    public ConnectionThrottleFilter() {
        this(DEFAULT_TIME);
    }

    /**
     * Constructor that takes in a specified wait time.
     *
     * @param allowedInterval
     *     The number of milliseconds a client is allowed to wait
     *     before making another successful connection
     *
     */
    public ConnectionThrottleFilter(long allowedInterval) {
        this.allowedInterval = allowedInterval;
        clients = new ConcurrentHashMap<String, Long>();

        // Create the cleanup thread
        ExpiredSessionThread cleanupThread = new ExpiredSessionThread();

        // And make it a daemon so that it's killed when the server exits
        cleanupThread.setDaemon(true);

        // start the cleanuo thread now
        cleanupThread.start();
    }

    /**
     * Sets the interval between connections from a client.
     * This value is measured in milliseconds.
     *
     * @param allowedInterval
     *     The number of milliseconds a client is allowed to wait
     *     before making another successful connection
     */
    public void setAllowedInterval(long allowedInterval) {
        lock.lock();

        try {
            this.allowedInterval = allowedInterval;
        } finally {
            lock.unlock();
        }
    }

    /**
     * Method responsible for deciding if a connection is OK
     * to continue
     *
     * @param session
     *     The new session that will be verified
     * @return
     *     True if the session meets the criteria, otherwise false
     */
    protected boolean isConnectionOk(IoSession session) {
        SocketAddress remoteAddress = session.getRemoteAddress();

        if (remoteAddress instanceof InetSocketAddress) {
            InetSocketAddress addr = (InetSocketAddress) remoteAddress;
            long now = System.currentTimeMillis();

            lock.lock();

            try {
                if (clients.containsKey(addr.getAddress().getHostAddress())) {

                    LOGGER.debug("This is not a new client");
                    Long lastConnTime = clients.get(addr.getAddress().getHostAddress());

                    clients.put(addr.getAddress().getHostAddress(), now);

                    // if the interval between now and the last connection is
                    // less than the allowed interval, return false
                    if (now - lastConnTime < allowedInterval) {
                        LOGGER.warn("Session connection interval too short");
                        return false;
                    }

                    return true;
                }

                clients.put(addr.getAddress().getHostAddress(), now);
            } finally {
                lock.unlock();
            }

            return true;
        }

        return false;
    }

    @Override
    public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
        if (!isConnectionOk(session)) {
            LOGGER.warn("Connections coming in too fast; closing.");
            session.close(true);
        }

        nextFilter.sessionCreated(session);
    }
}

 

分享到:
评论

相关推荐

    MINA 协议解码过滤器

    在`mina src`压缩包中,可能包含MINA框架的源代码,你可以通过阅读这些源码来深入理解MINA的工作原理,特别是过滤器和解码器的实现。这对于学习MINA、理解和定制自己的网络服务非常有帮助。同时,结合提供的博客链接...

    mina2核心框架

    文件可能涵盖了MINA2的高级主题,如性能调优、异常处理策略、自定义过滤器的实现以及与其他开源库的集成等。 总的来说,MINA2作为一个强大的网络通信框架,不仅提供了高效稳定的并发处理能力,还具备了高度灵活性和...

    MINA长连接框架实现通讯

    2. **MINA Server端实现**:在MINA中,Server端主要负责监听指定的端口,接收到客户端连接请求后,创建一个Session对象来代表与该客户端的连接。Server端可以通过自定义的Filter(过滤器)来处理进来的数据,如解码...

    Mina2中文文档

    - **安全传输**:介绍了Mina支持的SSL过滤器,用于实现加密通信的安全保障。 #### Chapter 12 - 日志过滤器 - **日志管理**:讲解了如何使用Mina的日志过滤器记录应用程序运行时的各种日志信息。 ### Part III - ...

    Mina实现RPC的例子

    这个例子中的链接(http://blog.csdn.net/stevexk/archive/2008/07/23/2697907.aspx)提供了更详细的实现细节,包括具体的编码和解码逻辑,以及如何在Mina的过滤器和处理器中处理RPC请求。如果你需要深入学习,建议...

    给予mina 协议进行大数据传输

    6. **丰富的API**:MINA提供了一套完整的API,包括Filter(过滤器)机制,可以方便地对网络数据流进行拦截、修改或增强。 7. **自定义编码与解码**:如前所述,MINA支持自定义编解码器,允许开发者根据业务需求定制...

    Mina+Socket通信

    文件"MinaSocket"可能包含了实现上述功能的详细代码,包括服务端的Acceptor配置、过滤器设置、事件处理器编写,以及客户端的Socket连接、数据发送和接收等。通过阅读和理解这些代码,你可以更好地掌握Mina与Socket...

    Mina自定义协议简单实现

    - **添加编码器和解码器**:通过`FilterChainBuilder`创建过滤器链,添加自定义的编码器和解码器,确保数据在发送和接收时正确处理。 3. **创建Mina客户端** - **配置Connector**:使用`TcpClient`或`...

    Java mina2源码

    2. **Filter**:Mina2的过滤器系统是其强大之处。每个Filter都有两个方法,`messageReceived`和`messageSent`,分别处理接收到的数据和发送出去的数据。开发者可以创建多个Filter,形成一个处理链,每个Filter执行...

    springboot 深度整合mina开箱即用

    - **创建过滤器链**:Mina的过滤器机制允许我们在数据传输过程中进行预处理或后处理,比如编码解码、安全检查等。 - **定义业务处理器**:实现具体的业务逻辑,处理客户端发来的消息。 **4. 配置Spring Boot** 在...

    MINA 服务端和客户端demo

    - MINA支持自定义过滤器(Filter)链,过滤器可以在数据传输过程中进行处理,如加密、解码、压缩等。过滤器链使得功能模块化,易于维护和扩展。 在"minaServer.rar"和"minaClient.rar"这两个压缩包中,分别包含了...

    MINA2 教程 socket

    MINA2的核心组件包括`Session`(会话)、`Filter`(过滤器)和`ProtocolCodec`(编码解码器)。`Session`代表了网络连接,负责数据传输;`Filter`用于数据处理,可以添加多个中间件以实现各种功能;`ProtocolCodec`...

    mina2 实例程序(socket通讯调用远程方法)

    《mina2实现Socket通信调用远程方法详解》 在当今的分布式系统中,远程方法调用(Remote Method Invocation,RMI)是常见的通信方式之一,它允许程序在不同的网络节点间透明地调用方法,极大地简化了分布式应用的...

    基于spring的Mina框架

    在Spring中整合Mina,首先需要在Spring配置文件中声明Mina的相关bean,如Acceptor、ProtocolCodecFactory(编码解码工厂)和FilterChainBuilder(过滤器链构建器)。通过Spring的依赖注入,我们可以轻松地管理这些...

    Mina2源码分析

    6. **IoFilterChain**:为每个会话提供过滤器链,由IoFilterChainBuilder构建。 7. **广播消息**:支持向所有会话广播消息,并返回一个WriteFuture集合。 8. **IoSessionDataStructureFactory**:为IoSession提供...

    MINA2与Netty4比较分析

    如果在过滤器链中没有添加“threadPool”过滤器,则业务逻辑处理和IoProcessor使用同一个线程。如果有,则使用设置的线程池来处理业务逻辑。 Netty4同样使用了Reactor模式,但其线程模型更为灵活,包括了单线程模型...

    websocket+java服务器(mina)

    2. **Filter Chain**:Mina通过过滤器链处理进来的消息。开发者可以自定义过滤器来实现特定功能,如身份验证、数据编码解码等。 3. **ProtocolCodecFactory**:用于将网络数据流转换成应用程序可以理解的对象,以及...

    mina使用mina使用mina使用

    2. **Filter**:过滤器是Mina的核心设计之一,通过定义一系列的过滤器链,可以在数据传输过程中进行预处理和后处理,如数据编码解码、安全加密等。 3. **ProtocolDecoder/Encoder**:这些组件负责将接收到的原始字节...

Global site tag (gtag.js) - Google Analytics