content: package hxy.server.socket.engine;
  
  import com.esotericsoftware.reflectasm.MethodAccess;
  import hxy.server.socket.anno.Socket;
  import hxy.server.socket.engine.factory.CodeHandlerRouteFactory;
  import hxy.server.socket.entity.CodeHandlerBean;
  import hxy.server.socket.relation.Client;
  import hxy.server.socket.util.ByteUtil;
  import hxy.server.socket.util.JsonUtil;
  import hxy.server.socket.util.ProtoUtil;
  import io.netty.channel.Channel;
  import io.netty.channel.ChannelHandlerContext;
  import io.netty.handler.codec.http.HttpRequest;
  import io.netty.util.Attribute;
  import io.netty.util.AttributeKey;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.util.Map;
  
  /**
   * @Description
   * @Author xinyu.huang
   * @Time 2020/4/8 21:32
   */
  @Socket
  public class SimpleCodeHandler implements SocketMsgHandler<Object> {
      private Logger logger = LoggerFactory.getLogger(SimpleCodeHandler.class);
  
      @Override
      public void onConnect(ChannelHandlerContext ctx, HttpRequest req) {
          logger.debug("onConnect:{}", ctx.channel().toString());
          for (ChannelActive channelActive : CodeHandlerRouteFactory.getChannelActives()) {
              channelActive.onConnect(ctx, req);
          }
      }
  
      @Override
      public void onMessage(ChannelHandlerContext ctx, Object msg) {
          if (msg instanceof String) {
              onMessageText(ctx, (String) msg);
          } else if (msg instanceof byte[]) {
              onMessageByte(ctx, (byte[]) msg);
          } else {
              throw new UnsupportedOperationException("unsupported type for msg,please use String or byte[]");
          }
      }
  
      private void onMessageText(ChannelHandlerContext ctx, String msg) {
          if (msg.isEmpty() || msg.trim().isEmpty()) {
              return;
          }
          String clientCode = msg.substring(0, msg.indexOf("|"));
          String surplusStr = msg.substring(msg.indexOf("|") + 1);
          String serverCode = surplusStr.substring(0, surplusStr.indexOf("|"));
  
          CodeHandlerBean codeHandlerBean = CodeHandlerRouteFactory.getCodeHandlerBean(Integer.parseInt(serverCode));
          if (codeHandlerBean == null) {
              logger.warn("serverCode:{} is not exists", serverCode);
              return;
          }
  
          String contentJsonStr = surplusStr.substring(surplusStr.indexOf("|") + 1);
  
          Class<?>[] clzs = codeHandlerBean.getParamType();
          Object[] params = new Object[clzs.length];
          for (int i = 0; i < clzs.length; i++) {
              Class parameter = clzs[i];
              if (Channel.class.isAssignableFrom(parameter)) {
                  params[i] = ctx.channel();
              } else if (Client.class.isAssignableFrom(parameter)) {
                  Attribute<Client> attribute = ctx.channel().attr(AttributeKey.valueOf(Client.CLIENT_ATTRIBUTE_KEY));
                  Client client = attribute.get();
                  params[i] = client;
              } else if (int.class.isAssignableFrom(parameter) || Integer.class.isAssignableFrom(parameter)) {
                  params[i] = Integer.parseInt(clientCode);
              } else if (Map.class.isAssignableFrom(parameter)) {
                  params[i] = JsonUtil.jsonToMap(contentJsonStr);
              } else {
                  params[i] = JsonUtil.json2Object(contentJsonStr, parameter);
              }
  
          }
          MethodAccess methodAccess = codeHandlerBean.getMethod();
          methodAccess.invoke(codeHandlerBean.getBean(), codeHandlerBean.getIndex(), params);
      }
  
      private void onMessageByte(ChannelHandlerContext ctx, byte[] msg) {
          byte[] idByte = new byte[4];
          System.arraycopy(msg, 0, idByte, 0, 4);
  
          byte[] uriByte = new byte[4];
          System.arraycopy(msg, 4, uriByte, 0, 4);
          int serverCode = ByteUtil.byteArrayToInt(uriByte);
  
          CodeHandlerBean codeHandlerBean = CodeHandlerRouteFactory.getCodeHandlerBean(serverCode);
          if (codeHandlerBean == null) {
              logger.warn("serverCode:{} is not exists", serverCode);
              return;
          }
  
          byte[] messageBody = new byte[msg.length - 8];
          System.arraycopy(msg, 8, messageBody, 0, msg.length - 8);
  
          Class<?>[] clzs = codeHandlerBean.getParamType();
          Object[] params = new Object[clzs.length];
          for (int i = 0; i < clzs.length; i++) {
              Class parameter = clzs[i];
              if (Channel.class.isAssignableFrom(parameter)) {
                  params[i] = ctx.channel();
              } else if (Client.class.isAssignableFrom(parameter)) {
                  Attribute<Client> attribute = ctx.channel().attr(AttributeKey.valueOf(Client.CLIENT_ATTRIBUTE_KEY));
                  Client client = attribute.get();
                  params[i] = client;
              } else if (int.class.isAssignableFrom(parameter) || Integer.class.isAssignableFrom(parameter)) {
                  params[i] = serverCode;
              }else {
                  params[i] = ProtoUtil.deserializeFromByte(messageBody,parameter);
              }
          }
          MethodAccess methodAccess = codeHandlerBean.getMethod();
          methodAccess.invoke(codeHandlerBean.getBean(), codeHandlerBean.getIndex(), params);
      }
  
      @Override
      public void disConnect(ChannelHandlerContext ctx) {
          logger.debug("disConnect:{}", ctx.channel().toString());
          for (ChannelActive channelActive : CodeHandlerRouteFactory.getChannelActives()) {
              channelActive.disConnect(ctx);
          }
      }
  
  }
  