private ExchangeServer getServer(URL url) {
    // 指定自己的exchanger
    url = url.addParameterIfAbsent(Constants.EXCHANGER_KEY, HeaderExchanger2.NAME);
    // server type setting
    url = url.addParameterIfAbsent(Constants.SERVER_KEY, NettyTransporter2.NAME);
    // check server type
    String str = url.getParameter(Constants.SERVER_KEY, NettyTransporter2.NAME);
    if (str != null
        && str.length() > 0
        && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str)) {
      throw new RpcException("Unsupported server type: " + str + ", url: " + url);
    }

    ExchangeServer server;
    try {
      server = Exchangers.bind(url, requestHandler);
    } catch (RemotingException e) {
      throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
    }
    str = url.getParameter(Constants.CLIENT_KEY);
    if (str != null && str.length() > 0) {
      Set<String> supportedTypes =
          ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();
      if (!supportedTypes.contains(str)) {
        throw new RpcException("Unsupported client type: " + str);
      }
    }
    return server;
  }
  /** 创建新连接. */
  private ExchangeClient initClient(URL url) {
    // 指定自己的exchanger
    url = url.addParameterIfAbsent(Constants.EXCHANGER_KEY, HeaderExchanger2.NAME);
    // client type setting.
    url =
        url.addParameterIfAbsent(
            Constants.CLIENT_KEY, url.getParameter(Constants.SERVER_KEY, NettyTransporter2.NAME));
    // check client type
    String str =
        url.getParameter(
            Constants.CLIENT_KEY, url.getParameter(Constants.SERVER_KEY, NettyTransporter2.NAME));
    // BIO存在严重性能问题,暂时不允许使用
    if (str != null
        && str.length() > 0
        && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str)) {
      throw new RpcException(
          "Unsupported client type: "
              + str
              + ","
              + " supported client type is "
              + StringUtils.join(
                  ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions(),
                  " "));
    }

    ExchangeClient client;
    try {
      // 设置连接应该是lazy的
      if (url.getParameter(Constants.LAZY_CONNECT_KEY, false)) {
        client = new LazyConnectExchangeClient(url, requestHandler);
      } else {
        client = Exchangers.connect(url, requestHandler);
      }
    } catch (RemotingException e) {
      throw new RpcException(
          "Fail to create remoting client for service(" + url + "): " + e.getMessage(), e);
    }
    return client;
  }
Example #3
0
  protected void encodeResponse(Channel channel, ChannelBuffer buffer, Response res)
      throws IOException {
    try {
      Serialization serialization = getSerialization(channel);
      // header.
      byte[] header = new byte[HEADER_LENGTH];
      // set magic number.
      Bytes.short2bytes(MAGIC, header);
      // set request and serialization flag.
      header[2] = serialization.getContentTypeId();
      if (res.isHeartbeat()) header[2] |= FLAG_EVENT;
      // set response status.
      byte status = res.getStatus();
      header[3] = status;
      // set request id.
      Bytes.long2bytes(res.getId(), header, 4);

      int savedWriteIndex = buffer.writerIndex();
      buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);
      ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
      ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
      try {
        // encode response data or error message.
        if (status == Response.OK) {
          if (res.isHeartbeat()) {
            encodeHeartbeatData(channel, out, res.getResult());
          } else {
            encodeResponseData(channel, out, res.getResult());
          }
        } else out.writeUTF(res.getErrorMessage());
        out.flushBuffer();
      } finally {
        // modified by lishen
        if (out instanceof Cleanable) {
          ((Cleanable) out).cleanup();
        }
      }

      bos.flush();
      bos.close();

      int len = bos.writtenBytes();
      checkPayload(channel, len);
      Bytes.int2bytes(len, header, 12);
      // write
      buffer.writerIndex(savedWriteIndex);
      buffer.writeBytes(header); // write header.
      buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
    } catch (Throwable t) {
      // 发送失败信息给Consumer,否则Consumer只能等超时了
      if (!res.isEvent() && res.getStatus() != Response.BAD_RESPONSE) {
        try {
          // FIXME 在Codec中打印出错日志?在IoHanndler的caught中统一处理?
          logger.warn(
              "Fail to encode response: "
                  + res
                  + ", send bad_response info instead, cause: "
                  + t.getMessage(),
              t);

          Response r = new Response(res.getId(), res.getVersion());
          r.setStatus(Response.BAD_RESPONSE);
          r.setErrorMessage(
              "Failed to send response: " + res + ", cause: " + StringUtils.toString(t));
          channel.send(r);

          return;
        } catch (RemotingException e) {
          logger.warn(
              "Failed to send bad_response info back: " + res + ", cause: " + e.getMessage(), e);
        }
      }

      // 重新抛出收到的异常
      if (t instanceof IOException) {
        throw (IOException) t;
      } else if (t instanceof RuntimeException) {
        throw (RuntimeException) t;
      } else if (t instanceof Error) {
        throw (Error) t;
      } else {
        throw new RuntimeException(t.getMessage(), t);
      }
    }
  }