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

com.iohao.game.widget.light.room.AbstractFlowContextSend Maven / Gradle / Ivy

There is a newer version: 21.23
Show newest version
/*
 * # iohao.com . 渔民小镇
 * Copyright (C) 2021 - 2022 double joker ([email protected]) . All Rights Reserved.
 *
 * Licensed 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 com.iohao.game.widget.light.room;

import com.iohao.game.action.skeleton.core.ActionSend;
import com.iohao.game.action.skeleton.core.commumication.BroadcastContext;
import com.iohao.game.action.skeleton.core.commumication.BrokerClientContext;
import com.iohao.game.action.skeleton.core.flow.FlowContext;
import com.iohao.game.action.skeleton.core.flow.attr.FlowAttr;
import com.iohao.game.action.skeleton.protocol.HeadMetadata;
import com.iohao.game.action.skeleton.protocol.ResponseMessage;
import com.iohao.game.widget.light.domain.event.message.Eo;
import com.iohao.game.widget.light.domain.event.message.Topic;
import lombok.AccessLevel;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.jctools.maps.NonBlockingHashSet;

import java.util.Collection;
import java.util.Objects;
import java.util.Set;

/**
 * 抽象响应消息 推送
 *
 * @author 渔民小镇
 * @date 2022-03-31
 */
@Slf4j
@Accessors(chain = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
public abstract class AbstractFlowContextSend implements Topic, Eo, ActionSend {

    /** 需要推送的用户id列表 */
    final Set userIds = new NonBlockingHashSet<>();

    /** 是否执行发送领域事件操作: true 执行推送操作 */
    boolean doSend = true;

    /** 业务框架 flow 上下文 */
    protected final FlowContext flowContext;

    protected AbstractFlowContextSend(FlowContext flowContext) {
        this.flowContext = flowContext;
    }

    /**
     * 在将数据推送到调用方之前,触发的方法
     * 
     *     可以做一些逻辑,在逻辑中可以决定是否执行推送
     * 
*/ protected void logic() { } /** * 小把戏 (钩子方法). 子类可以做些其他的事情 *
     *     在将数据推送到调用方之前,触发的方法
     * 
*/ protected void trick() { } /** * 响应消息到远程, 此方法是同步推送 *
     *     如果没有特殊情况 , 使用异步推送 (当前类的) send 方法
     * 
* 模板方法模式: *
     * 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。
     * 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
     * 要点:
     * - “模板方法”定义了算法的步骤,把这些步骤的实现延迟到子类。
     * - 模板方法模式为我们提供了一种代码复用的重要技巧。
     * - 模板方法的抽象类可以定义具体方法、抽象方法和钩子。
     * - 抽象方法由子类实现。
     * - 钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它。
     * - 为了防止子类改变模板方法中的算法,可以将模板方法声明为final。
     * - 好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用低层模块。
     * - 你将在真实世界代码中看到模板方法模式的许多变体,不要期待它们全都是一眼就可以被你一眼认出的。
     * - 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。
     * - 工厂方法是模板方法的一种特殊版本。
     * 
*/ public final void execute() { Objects.requireNonNull(this.flowContext, "flowContext must not be null"); if (userIds.isEmpty()) { throw new RuntimeException("没有添加消息推送人 " + this.getClass()); } // 子类构建响应内容 this.logic(); // 钩子方法 if (!doSend) { return; } // 响应对象 ResponseMessage responseMessage = this.flowContext.getResponse(); HeadMetadata headMetadata = responseMessage.getHeadMetadata(); // 路由设置 int cmdMerge = this.getCmdMerge(); headMetadata.setCmdMerge(cmdMerge); // 在将数据推送前调用的钩子方法 this.trick(); BrokerClientContext brokerClientContext = flowContext.option(FlowAttr.brokerClientContext); // 推送响应 (广播消息)给指定的用户列表 BroadcastContext broadcastContext = brokerClientContext.getBroadcastContext(); broadcastContext.broadcast(responseMessage, this.userIds); } /** * 接收广播的用户 * * @param userIds 用户id列表 * @return me */ public AbstractFlowContextSend addUserId(Collection userIds) { this.userIds.addAll(userIds); return this; } /** * 接收广播的用户 * * @param userId 用户id * @return me */ public AbstractFlowContextSend addUserId(long userId) { this.userIds.add(userId); return this; } /** * 添加用户id列表 * * @param userIds 用户id列表 * @param excludeUserId 需要排除的用户id * @return me */ public AbstractFlowContextSend addUserId(Collection userIds, long excludeUserId) { return this.addUserId(userIds) .removeUserId(excludeUserId); } @Override public Class getTopic() { return AbstractFlowContextSend.class; } @Override public int getCmdMerge() { return flowContext.getActionCommand().getCmdInfo().getCmdMerge(); } /** * 不执行推送数据的操作 */ protected void disableSend() { this.doSend = false; } /** * 排除用户id * * @param userId 用户id * @return me */ private AbstractFlowContextSend removeUserId(long userId) { if (userId > 0) { this.userIds.remove(userId); } return this; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy