/* * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software;Designed and Developed mainly by many Chinese * opensource volunteers. you can redistribute it and/or modify it under the * terms of the GNU General Public License version 2 only, as published by the * Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Any questions about this component can be directed to it's project Web address * https://code.google.com/p/opencloudb/. * */ package com.talent.nio.communicate.handler.intf; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.talent.nio.api.Packet; import com.talent.nio.communicate.ChannelContext; /** * * @author 谭耀武 * @date 2012-08-09 * */ public abstract class BlockSupportPacketHandler implements PacketHandlerIntf { private static final Logger log = LoggerFactory.getLogger(BlockSupportPacketHandler.class); private MessageChangeListener msgChangeListener; /** * key:序列号;value: Packet对象 */ private static Map<BlockSupportPacketHandler, Packet> mapOfProcessorAndPacket = new ConcurrentHashMap<BlockSupportPacketHandler, Packet>(); private List<Packet> receivedPackets = new ArrayList<Packet>(); private boolean isRunning = false; /** * */ public BlockSupportPacketHandler() { } /** * @param args */ public static void main(String[] args) { } /** * 删除key * * @param serialNo * @return */ public static Packet removeKey(BlockSupportPacketHandler blockSupportpacketHandler) { return mapOfProcessorAndPacket.remove(blockSupportpacketHandler); } /** * 获取key * * @param serialNo * @return */ public static Packet getKey(BlockSupportPacketHandler blockSupportpacketHandler) { return mapOfProcessorAndPacket.get(blockSupportpacketHandler); } @Override /** * */ public byte[] onSend(Packet packet, ChannelContext channelContext) { this.setBlockCompleted(false); mapOfProcessorAndPacket.put(this, packet); receivedPackets.clear(); return serialMessage(packet); } @Override public void onReceived(Packet packet, ChannelContext channelContext) throws Exception { if (packet == null) { log.info("received data is null, Refuse to distribute it"); } MessageChangeListener msgChangeListener = this.getMsgChangeListener(); Object obj = msgChangeListener.onMessage(packet); receivedPackets.add(packet); Packet afterProcessedPacket = null; try { afterProcessedPacket = this.processMessage(packet, obj); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } finally { if (this.isBlockCompleted(packet)) { notifyMessageWaiter(afterProcessedPacket, channelContext); } } } /** * 通知消息等待者 * * @param afterProcessedPacket */ public void notifyMessageWaiter(Packet afterProcessedPacket, ChannelContext channelContext) { if (afterProcessedPacket == null) { log.error("afterProcessedPacket is null"); return; } Packet initPacket = mapOfProcessorAndPacket.remove(this); if (initPacket != null) { try { mapOfProcessorAndPacket.put(this, afterProcessedPacket); synchronized (initPacket) { initPacket.notify(); } } catch (Exception e) { log.error(e.getMessage(), e); } finally { // synMessageMap.remove(serialNo); } } else { log.error("initPacket is null!{}", channelContext); } } /** * 收到消息后,进行业务处理 * * @param packet * 收到的packet对象 * @param obj * MsgChangeListener.onMessage()返回的对象 * @return * @throws Exception */ public abstract Packet processMessage(Packet packet, Object obj) throws Exception; /** * 在发送消息前,应用需要先将消息序列化成字节数组 * * @param packet * @return */ public abstract byte[] serialMessage(Packet packet); /** * 阻塞发送是否已经完成 * * @param packet * @return true:已经完成 */ public abstract boolean isBlockCompleted(Packet packet); public abstract void setBlockCompleted(boolean isBlockCompleted); public void setRunning(boolean isRunning) { this.isRunning = isRunning; } public boolean isRunning() { return isRunning; } public void setMsgChangeListener(MessageChangeListener msgChangeListener) { this.msgChangeListener = msgChangeListener; } public MessageChangeListener getMsgChangeListener() { return msgChangeListener; } public void setReceivedPackets(List<Packet> receivedPackets) { this.receivedPackets = receivedPackets; } public List<Packet> getReceivedPackets() { return receivedPackets; } }