High latency/large payload Axis HTTP connections

For very large Axis WebService requests (eg, with attachments) to servers a long way away (high latency), the default TCP settings are not optimal and Axis doesn’t give you a way to change these. However it does give you a way to override the SocketFactory classes that it is using for this.

Once the code below is compiled into classes, they can replace Axis socket factories by calling them like this (for a class called “Main” that uses Axis calls):

java -classpath lib/axis.jar:lib/wsdl4j-1.5.1.jar:lib/jaxrpc.jar:lib/commons-logging-1.0.4.jar:lib/commons-discovery-0.2.jar:lib/mail.jar:lib/activation.jar:. -Daxis.socketSecureFactory=jwst.HighPerformanceSecureSocketFactory -Daxis.socketFactory=jwst.HighPerformanceSocketFactory Main

HighPerformanceSocketFactory.java:

package jwst;

import org.apache.axis.components.net.BooleanHolder;
import org.apache.axis.components.net.SocketFactory;
import org.apache.axis.components.net.DefaultSocketFactory;
import org.apache.axis.components.net.SecureSocketFactory;
import org.apache.axis.utils.Messages;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Hashtable;

public class HighPerformanceSocketFactory extends DefaultSocketFactory implements SocketFactory {
  protected SocketFactory socketFactory = null;

  public HighPerformanceSocketFactory(Hashtable attributes) {
    super(attributes);
  }

  @Override
  public Socket create(String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL) throws Exception {
    if (port == -1) {
      port = 80;
    }

    Socket s = new Socket();
    System.err.print("HighPerformanceSocket in use");
    System.err.print(" SO_RCVBUF: " + s.getReceiveBufferSize() + " -> ");
    //s.setReceiveBufferSize(2097136);
    System.err.print(s.getReceiveBufferSize());

    System.err.print(" SO_SNDBUF: " + s.getSendBufferSize() + " -> ");
    s.setSendBufferSize(1638400);
    System.err.println(s.getSendBufferSize());

    s.connect(new InetSocketAddress(host, port));
    return s;
  }
}

HighPerformanceSecureSocketFactory.java:

package jwst;

import org.apache.axis.components.net.BooleanHolder;
import org.apache.axis.components.net.SocketFactory;
import org.apache.axis.components.net.DefaultSocketFactory;
import org.apache.axis.components.net.SecureSocketFactory;
import org.apache.axis.utils.Messages;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Hashtable;

public class HighPerformanceSecureSocketFactory extends DefaultSocketFactory implements SecureSocketFactory {
  protected SSLSocketFactory sslFactory = null;

  public HighPerformanceSecureSocketFactory(Hashtable attributes) {
    super(attributes);
  }

  protected void initFactory() throws IOException {
    sslFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
  }

  @Override
  public Socket create(String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL) throws Exception {
    if (sslFactory == null) {
      initFactory();
    }
    if (port == -1) {
        port = 443;
    }
        
    Socket s = new Socket();
    System.err.print("HighPerformanceSecureSocket in use");
    System.err.print(" SO_RCVBUF: " + s.getReceiveBufferSize() + " -> ");
    // s.setReceiveBufferSize(2097136);
    System.err.print(s.getReceiveBufferSize());

    System.err.print(" SO_SNDBUF: " + s.getSendBufferSize() + " -> ");
    s.setSendBufferSize(1638400);
    System.err.println(s.getSendBufferSize());

    s.connect(new InetSocketAddress(host, port));
    Socket sslSocket = sslFactory.createSocket(s, host, port, true);
        
    ((SSLSocket) sslSocket).startHandshake();
    return sslSocket;
  }
}

Comments

    Leave a comment