Java游戏服务器开发之十八--事件机制

    事件机制
        在一个游戏系统中,客户端使用事件机制用的也是比较多的,在这边也将服务端的事件机制实现下
        
        事件:事件先预设了触发条件及处理方法,在实际使用时,通过触发相关条件,调用对应方法。
            举个例子,在有界面的开发中,肯定都有button,button都会和某个方法进行绑定,当用户点击button,就会触发这个方法。这个就是事件
        一般事件都需要有几个通用方法,监听事件,移除事件,发送事件。
            
        像我们做的这个就没有这么复杂,算是一个简版的事件,不支持动态添加事件。所以只有添加监听事件,和发送事件。
            事件的存储使用一个map管理,里面包含 触发事件的key(EventType)和具体执行的方法value(IEventListener的实现类)
            然后通过EventUtil.fire(key)进行触发。
        
            
    EventUtil.java                事件的操作方法,
    IEventListener.java            事件的基类

    CommonValue.java            事件的key值,EventType
    EventRegister.java            注册事件

    LoginEventListener.java        具体的事件实现类
    UserServiceImpl.java        触发事件,调用EventUtil.fireEvent(CommonValue.EVENT_TYPE_LOGIN);
        
    具体看下
        IEventListener是一个接口,里面就一个方法execute
            /**
            * 事件的具体执行
            * 可以传入参数
            * @param param param
            */
            void execute(Object param);
        
        EventUtil
            里面有个map,用于存放触发key和事件数组(可以组合各个事件)
            addListener方法注册事件
            fireEvent为执行事件
        EventRegister
            把事件的注册,都写到这个类里面,在服务启动的时候运行
            registerPreparedListeners
        LoginEventListener
            实现IEventListener,重写execute方法。
        
        CommonValue
            /***************************************事件消息号**********************************************/
            public static final int EVENT_TYPE_LOGIN = 1001;
            public static final int EVENT_TYPE_LOGOUT = 1002;
        
        UserServiceImpl
            模拟调用过程,只要进行发送就行了
            EventUtil.fireEvent(CommonValue.EVENT_TYPE_LOGIN);
        
    详细代码
        EventUtil.java                事件的操作方法,

/*
 * Copyright (C), 2015-2018
 * FileName: EventUtil
 * Author:   zhao
 * Date:     2018/7/20 11:16
 * Description: 事件工具类
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.lizhaoblog.base.event;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 〈一句话功能简述〉<br>
 * 〈事件工具类〉
 *
 * @author zhao
 * @date 2018/7/20 11:16
 * @since 1.0.1
 */
public final class EventUtil {

  private static final Map<Integer, List<IEventListener>> PREPARED_LISTENERS = new HashMap<>(16);

  private static final Logger logger = LoggerFactory.getLogger(EventUtil.class);

  /**
   * 添加事件
   * 一个注册码,可以触发多个事件
   *
   * @param listener 事件
   * @param type     唯一码
   */
  public static void addListener(Integer type, IEventListener listener) {
    List<IEventListener> listenerList = PREPARED_LISTENERS.computeIfAbsent(type, k -> new ArrayList<>());
    listenerList.add(listener);
  }

  public static void fireEvent(Integer type) {
    fireEvent(type, null);
  }

  public static void fireEvent(Integer type, Object obj) {

    List<IEventListener> listenerList = PREPARED_LISTENERS.get(type);
    if (listenerList != null) {
      for (IEventListener listener : listenerList) {
        try {
          listener.execute(obj);
        } catch (Exception e) {
          logger.error("事件执行错误", e);
        }
      }
    }
  }

  private EventUtil() {
  }

}


        IEventListener.java            事件的基类

/*
 * Copyright (C), 2015-2018
 * FileName: IEventListener
 * Author:   zhao
 * Date:     2018/7/20 11:07
 * Description: Event的基类
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.lizhaoblog.base.event;

/**
 * 〈一句话功能简述〉<br>
 * 〈Event的基类〉
 *
 * @author zhao
 * @date 2018/7/20 11:07
 * @since 1.0.1
 */
public interface IEventListener {

  /**
   * 事件的具体执行
   * 可以传入参数
   * @param param param
   */
  void execute(Object param);
}


        CommonValue.java            事件的key值,EventType

  /***************************************事件消息号**********************************************/
  public static final int EVENT_TYPE_LOGIN = 1001;
  public static final int EVENT_TYPE_LOGOUT = 1002;


        EventRegister.java            注册事件

/*
 * Copyright (C), 2015-2018
 * FileName: EventRegister
 * Author:   zhao
 * Date:     2018/7/20 11:28
 * Description: 事件注册
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.lizhaoblog.server.biz.event;

import com.lizhaoblog.base.event.EventUtil;
import com.lizhaoblog.server.biz.constant.CommonValue;
import com.lizhaoblog.server.biz.event.listener.LoginEventListener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 〈一句话功能简述〉<br>
 * 〈事件注册〉
 *
 * @author zhao
 * @date 2018/7/20 11:28
 * @since 1.0.1
 */
@Component
@Scope("singleton")
public class EventRegister {

  @Autowired
  private LoginEventListener loginEventListener;

  @PostConstruct
  public void registerPreparedListeners() {
    addLoginListener();
  }

  /**
   * 登录事件监听器
   */
  private void addLoginListener() {
    EventUtil.addListener(CommonValue.EVENT_TYPE_LOGIN, loginEventListener);
  }

}


        LoginEventListener.java        具体的事件实现类

/*
 * Copyright (C), 2015-2018
 * FileName: LoginEventListener
 * Author:   zhao
 * Date:     2018/7/20 14:57
 * Description: 登录事件
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.lizhaoblog.server.biz.event.listener;

import com.lizhaoblog.base.event.IEventListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * 〈一句话功能简述〉<br>
 * 〈登录事件〉
 *
 * @author zhao
 * @date 2018/7/20 14:57
 * @since 1.0.1
 */
@Component
@Scope("singleton")
public class LoginEventListener implements IEventListener {
  public static final Logger logger = LoggerFactory.getLogger(LoginEventListener.class);

  @Override
  public void execute(Object param) {
    logger.info("LoginEventListener fire");
  }
}

猜你喜欢

转载自blog.csdn.net/cmqwan/article/details/81144906