With the recent explosion of Socket server implementations, a lot of questions have come up about how to connect to Socket server if client is behind proxy, firewalls, and load-balancing routers, I am trying to write sample code (groovy + java) here using Socket.IO-Client java :
Dependencies :
- <!– https://mvnrepository.com/artifact/io.socket/socket.io-client –>
<dependency>
<groupId>io.socket</groupId>
<artifactId>socket.io-client</artifactId>
<version>0.7.0</version>
</dependency> - <!– https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all –>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.12</version>
</dependency> - <!– https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient –>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
Code :
- First of all create our own ProxyAuthenticator to support both basic and NTLM authentication :
[code]
import okhttp3.*
class BqProxyAuthenticator implements Authenticator {
final NTLMEngineImpl engine = new NTLMEngineImpl();
private String domain;
private String username;
private String password;
private String ntlmMsg1;
private String host
public BqProxyAuthenticator(String host, String username, String password, String domain) {
this.host = host
this.domain = domain
this.username = username
this.password = password
this.ntlmMsg1 = BqExceptionUtil.ignoreException {
engine.generateType1Msg(null, null)
}
}
@Override
public Request authenticate(Route route, Response response) throws IOException {
try {
final List WWWAuthenticate = response.headers().values(“WWW-Authenticate”);
if (WWWAuthenticate && WWWAuthenticate.contains(“NTLM”)) {
if(!ntlmMsg1) {
ntlmMsg1 = engine.generateType3Msg(username, password, domain, host, WWWAuthenticate.get(0)?.substring(5))
}
return response.request().newBuilder().header(“Authorization”, “NTLM ” + ntlmMsg1).build();
}
return response.request().newBuilder().header(“Proxy-Authorization”, Credentials.basic(username, password)).build();
}
finally {
if(response?.body()) {
response?.body().close()
}
}
}
}
[/code]
Note:- Here one question is arise that where is NTLMEngineImpl class?
The answer is You need to grab code from here and write it on same package where BqProxyAuthenticator present.
- Now to support proxy authentication we need to create our OkHttpClient builder as :
[code]
private OkHttpClient.Builder getHttpClientBuilder() {
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.MINUTES).writeTimeout(5, TimeUnit.MINUTES).readTimeout(5, TimeUnit.MINUTES)
String host = “host”
int port = 123
String user = “proxy username”
String password = “proxy password”
String domain = “domain”
if (!host && !port) {
return clientBuilder
}
// now set proxy
clientBuilder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(LoadProxyUtil.httpProxyHost, LoadProxyUtil.httpProxyPort.toInteger())))
// no authentication at all
if (!user ) {
return clientBuilder
}
clientBuilder.proxyAuthenticator(new BqProxyAuthenticator(host, user, password , domain ))
return clientBuilder
}
[/code]
- Let’s trying to connect to socket server as :
[code]
import io.socket.*
import okhttp3.OkHttpClient
OkHttpClient okHttpClient = getHttpClientBuilder().build()
//Set our client builder
IO.setDefaultOkHttpCallFactory(okHttpClient)
IO.setDefaultOkHttpWebSocketFactory(okHttpClient)
//Now trying to connect socket server
Socket socket = IO.socket(“socket server url”)
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object… args) {
//Perform your emit operation here
}
})
socket.connect()
[/code]
Reference issue link :
- https://github.com/socketio/socket.io-client-java/issues/50
- https://github.com/square/okhttp/issues/206
Thanks