All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.youyinnn.server.AbstractServerAioHandler Maven / Gradle / Ivy

The newest version!
package com.github.youyinnn.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.youyinnn.common.AbstractAioHandler;
import com.github.youyinnn.common.BaseSessionContext;
import com.github.youyinnn.common.Const;
import com.github.youyinnn.common.MsgType;
import com.github.youyinnn.common.packet.*;
import com.github.youyinnn.server.service.GroupCheckService;
import com.github.youyinnn.youdbutils.exceptions.AutowiredException;
import com.github.youyinnn.youdbutils.ioc.YouServiceIocContainer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.tio.core.Aio;
import org.tio.core.ChannelContext;
import org.tio.server.intf.ServerAioHandler;
import org.tio.utils.json.Json;

import java.util.List;

/**
 * The type Abstract server aio handler.
 *
 * @author youyinnn
 */
public abstract class AbstractServerAioHandler extends AbstractAioHandler implements ServerAioHandler {

    private static GroupCheckService service;

    private static final Logger SERVER_LOG = LogManager.getLogger("$im_server");

    static {
        try {
            service = (GroupCheckService) YouServiceIocContainer.getYouService(GroupCheckService.class);
        } catch (AutowiredException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Object handler(BasePacket packet, ChannelContext channelContext) throws Exception {
        String bodyJsonStr;
        byte msgType = packet.getMsgType();
        bodyJsonStr = new String(packet.getMsgBody(), Const.Handler.CHARSET);
        if (packet.getMsgBody() != null) {
            Boolean handler = true;
            if (msgType == MsgType.LOGIN_REQ) {
                LoginRequestBody loginRequestBody = Json.toBean(bodyJsonStr, LoginRequestBody.class);
                if (Server.isServerHandlerLogEnabled()) {
                    SERVER_LOG.info("收到登陆请求: userId:{}.",loginRequestBody.getLoginUserId());
                }
                beforeLoginRequestHandle();
                handler = loginRequestHandle(loginRequestBody, channelContext);
                if (handler) {
                    JSONObject bodyJsonObj = JSON.parseObject(bodyJsonStr);
                    String userId = bodyJsonObj.getString("loginUserId");
                    String groupJsonStr = service.getGroupJsonStr(userId);
                    if (groupJsonStr != null) {
                        List groups = JSON.parseArray(groupJsonStr, String.class);
                        for (String group : groups) {
                            Aio.bindGroup(channelContext,group);
                        }
                    }
                }
                afterLoginRequestHandle();
            } else if (msgType == MsgType.GROUP_MSG_REQ) {
                GroupMsgRequestBody groupMsgRequestBody = Json.toBean(bodyJsonStr, GroupMsgRequestBody.class);
                if (Server.isServerHandlerLogEnabled()) {
                    SERVER_LOG.info("收到群组消息请求: fromUserId:{}, toGroup:{}, msg:{}.",
                            groupMsgRequestBody.getFromUserId(),
                            groupMsgRequestBody.getToGroup(),
                            groupMsgRequestBody.getMsg());
                }
                beforeGroupMsgRequestHandle();
                groupMsgRequestHandle(groupMsgRequestBody, channelContext);
                afterGroupMsgRequestHandle();
            } else if (msgType == MsgType.JOIN_GROUP_REQ) {
                JoinGroupRequestBody joinGroupRequestBody = Json.toBean(bodyJsonStr, JoinGroupRequestBody.class);
                if (Server.isServerHandlerLogEnabled()) {
                    SERVER_LOG.info("收到加群请求: fromUserId:{}, toGroup:{}.",
                            joinGroupRequestBody.getFromUserId(),
                            joinGroupRequestBody.getGroup());
                }
                beforeJoinGroupRequestHandle();
                handler = joinGroupRequestHandle(joinGroupRequestBody, channelContext);
                if (handler) {
                    service.registerGroupInJson(joinGroupRequestBody.getFromUserId(),joinGroupRequestBody.getGroup());
                }
                afterJoinGroupRequestHandle();
            } else if (msgType == MsgType.P2P_REQ) {
                P2PRequestBody p2PRequestBody = Json.toBean(bodyJsonStr, P2PRequestBody.class);
                if (Server.isServerHandlerLogEnabled()) {
                    SERVER_LOG.info("收到P2P请求: fromUserId:{}, toUserId:{}, msg:{}.",
                            p2PRequestBody.getFromUserId(),
                            p2PRequestBody.getToUserId(),
                            p2PRequestBody.getMsg());
                }
                beforeP2PMsgRequestHandle();
                handler = p2PMsgRequestHandle(p2PRequestBody, channelContext);
                afterP2PMsgRequestHandle();
            } else if (msgType == MsgType.LOGOUT_REQ) {
                LogoutRequestBody logoutRequestBody = Json.toBean(bodyJsonStr, LogoutRequestBody.class);
                if (Server.isServerHandlerLogEnabled()) {
                    SERVER_LOG.info("收到登出请求: userId:{}.", logoutRequestBody.getLogoutUserId());
                }
                beforeLogoutRequestHandle();
                logoutRequestHandle(channelContext);
                afterLogoutRequestHandle();
            } else if (msgType == MsgType.QUIT_GROUP_REQ) {
                QuitGroupRequestBody quitGroupRequestBody = Json.toBean(bodyJsonStr, QuitGroupRequestBody.class);
                beforeQuitGroupRequestHandle();
                quitGroupRequestHandle(channelContext, quitGroupRequestBody.getGroupId());
                afterQUitGroupRequestHandle();
            } else if (msgType == MsgType.HEART_BEAT_REQ) {
                handler = heartbeatRequestHandler(Json.toBean(bodyJsonStr, GroupMsgRequestBody.class), channelContext);
            }
            return handler;
        }
        return null;
    }

    private Boolean loginRequestHandle(LoginRequestBody loginRequestBody, ChannelContext channelContext) {
        /*
         * 从请求登陆方获取请求者id,将该连接通道和该id进行绑定
         * 需要注意的是,这里的绑定的含义是告诉框架:我这个连接通道和该id绑定了
         * 此绑定的意义是面向框架的,绑定的id是提供给框架服务的.
         */
        String userId = loginRequestBody.getLoginUserId();
        Aio.bindUser(channelContext, userId);

        /*
         * 在该请求连接中获取属性对象,将该请求者id设置到连接通道的属性对象上.
         * 这个设置算是面向用户的设置,和框架无关,仅和用户业务有关.
         */
        BaseSessionContext sessionContext = (BaseSessionContext) channelContext.getAttribute();
        sessionContext.setUserId(userId);

        /*
         * 组成登陆的响应包, 发送回登陆的请求方.
         */
        BasePacket responsePacket = BasePacket.loginResponsePacket(Const.RequestCode.SUCCESS,getToken());
        return Aio.send(channelContext, responsePacket);
    }

    private void groupMsgRequestHandle(GroupMsgRequestBody groupMsgRequestBody, ChannelContext channelContext){
        BaseSessionContext sessionContext = (BaseSessionContext) channelContext.getAttribute();

        BasePacket responsePacket =
                BasePacket.groupMsgResponsePacket(groupMsgRequestBody.getMsg(), sessionContext.getUserId(), groupMsgRequestBody.getToGroup());
        Aio.sendToGroup(channelContext.getGroupContext(), groupMsgRequestBody.getToGroup(), responsePacket);
    }

    private Boolean joinGroupRequestHandle(JoinGroupRequestBody joinGroupRequestBody, ChannelContext channelContext) {
        Aio.bindGroup(channelContext, joinGroupRequestBody.getGroup());

        BasePacket responsePacket =
                BasePacket.joinGroupResponsePacket(Const.RequestCode.SUCCESS,"",joinGroupRequestBody.getGroup());
        return Aio.send(channelContext, responsePacket);
    }

    private Boolean p2PMsgRequestHandle(P2PRequestBody p2PRequestBody, ChannelContext channelContext) {
        BaseSessionContext sessionContext = (BaseSessionContext) channelContext.getAttribute();
        BasePacket responsePacket =
                BasePacket.p2PMsgResponsePacket(p2PRequestBody.getMsg(), sessionContext.getUserId());
        return Aio.sendToUser(channelContext.getGroupContext(), p2PRequestBody.getToUserId(), responsePacket);
    }

    private void logoutRequestHandle(ChannelContext channelContext) {
        BaseSessionContext sessionContext = (BaseSessionContext) channelContext.getAttribute();
        sessionContext.setUserId(null);
        Aio.unbindUser(channelContext);
    }

    private void quitGroupRequestHandle(ChannelContext channelContext, String groupId) {
        Aio.unbindGroup(groupId, channelContext);
    }

    /**
     * 必须实现一个Token获取方法
     *
     * @return token
     */
    protected abstract String getToken();

    /**
     * Before login request handle.
     */
    protected abstract void beforeLoginRequestHandle();

    /**
     * After login request handle.
     */
    protected abstract void afterLoginRequestHandle();

    /**
     * Before group msg request handle.
     */
    protected abstract void beforeGroupMsgRequestHandle();

    /**
     * After group msg request handle.
     */
    protected abstract void afterGroupMsgRequestHandle();

    /**
     * Before join group request handle.
     */
    protected abstract void beforeJoinGroupRequestHandle();

    /**
     * After join group request handle.
     */
    protected abstract void afterJoinGroupRequestHandle();

    /**
     * Before p 2 p msg request handle.
     */
    protected abstract void beforeP2PMsgRequestHandle();

    /**
     * After p 2 p msg request handle.
     */
    protected abstract void afterP2PMsgRequestHandle();

    /**
     * Before logout request handle.
     */
    protected abstract void beforeLogoutRequestHandle();

    /**
     * After logout request handle.
     */
    protected abstract void afterLogoutRequestHandle();

    /**
     * Before quit group request handle.
     */
    protected abstract void beforeQuitGroupRequestHandle();

    /**
     * After q uit group request handle.
     */
    protected abstract void afterQUitGroupRequestHandle();

    /**
     * 心跳请求处理
     *
     * @param baseMsgBody    the base msg body
     * @param channelContext the channel context
     * @return boolean
     */
    protected abstract boolean heartbeatRequestHandler(GroupMsgRequestBody baseMsgBody, ChannelContext channelContext);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy