I have been trying all day and night for couple of days trying to make websocket to work using proxy in Java. I tried different library like
https://github.com/TooTallNate/Java-WebSocket
https://github.com/AsyncHttpClient/async-http-client
But sadly these library doesn't support proxy with credentials. If you guys have known any other library that supports proxy then I would be appreciated.
Thanks in advance
Try nv-websocket-client library. It supports authentication at a proxy server. Note that, however, the current implementation supports Basic Authentication only.
// 1. Create a WebSocketFactory instance.
WebSocketFactory factory = new WebSocketFactory();
// 2. Set up information about a proxy server.
// Credentials can be set here.
ProxySettings settings = factory.getProxySettings();
settings.setServer("http://proxy.example.com");
settings.setCredentials("id", "password");
// 3. Connect to a WebSocket endpoint via the proxy.
WebSocket ws = factory.createSocket("ws://websocket.example.com");
// 4. Add a listener to receive WebSocket events.
ws.addListener(new WebSocketAdapter() {
#Override
public void onTextMessage(WebSocket ws, String message) {
// Received a text message.
......
}
});
// 5. Perform a WebSocket opening handshake.
ws.connect();
// 6. Send frames.
// 6-1. Text
ws.sendText("Hello.");
// 6-2. Binary
byte[] binary = ......;
ws.sendBinary(binary);
// 6-3. Ping
ws.sendPing("Are you there?");
// 6-4. Pong (unsolicited pong; RFC 6455, 5.5.3. Pong)
ws.sendPong("I'm OK.");
// 6-5. Fragmented Frames
ws.sendText("How ", false)
.sendContinuation("are ")
.sendContinuation("you?", true);
// 6-6. Periodical Ping
ws.setPingInterval(60 * 1000);
// 6-7. Periodical Pong (unsolicited pong; RFC 6455, 5.5.3. Pong)
ws.setPongInterval(60 * 1000);
// 6-8. Close (if you want to send one manually).
ws.sendClose(WebSocketCloseCode.NORMAL, "Bye.");
// 7. Disconnect
ws.disconnect();
Blog
WebSocket client library (Java SE 1.5+, Android)
http://darutk-oboegaki.blogspot.jp/2015/05/websocket-client-library-java-se-15.html
GitHub
https://github.com/TakahikoKawasaki/nv-websocket-client
JavaDoc
http://takahikokawasaki.github.io/nv-websocket-client/
Maven
<dependency>
<groupId>com.neovisionaries</groupId>
<artifactId>nv-websocket-client</artifactId>
<version>1.3</version>
</dependency>
The size of nv-websocket-client-1.3.jar is 62,854 bytes and it does not require any external dependencies.
You can try Tyrus (reference implementation of WebSocket API in Java EE); client side does not require any Java EE server to be running and if you are using Java 7, the client could be minimized to ~500kb.
Client behing proxy and Dependencies should provide enough info to try.
Related
On grpc client I am getting this error after calling the rpc method in server.
I am using grpc-spring-boot-starter (java). Please tell me how to increase response size.
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:262)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:243)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:156)
If you are using official grpc library then create client in following way.
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9089).usePlaintext().maxInboundMessageSize(Integer.MAX_VALUE).build();
productsBlockingStub prodStub = productsGrpc.newBlockingStub(channel);
You can refer the grpc project here. Just add modification formaxInboundMessageSize
If you are using grpc-client-spring-boot-starter then you can either.
#GrpcClient("greeting-service")
private GreetingServiceGrpc.GreetingServiceBlockingStub greetingServiceBlockingStub;
greetingServiceBlockingStub = greetingServiceBlockingStub.withMaxInboundMessageSize(Integer.MAX_VALUE);
greetingServiceBlockingStub = greetingServiceBlockingStub.withMaxOutboundMessageSize(Integer.MAX_VALUE);
Or add this in props.
grpc.client.greeting-service.max-inbound-message-size=9155241000
grpc.client.greeting-service.package-max-inbound-message-size=9155241000
grpc.client.greeting-service.server.max-inbound-message-size=9155241000
I try to define Braid server in java like this repo. And the following is my BootstrapBraidService class:
#CordaService
public class BootstrapBraidService extends SingletonSerializeAsToken{
private AppServiceHub appServiceHub;
private BraidConfig braidConfig;
public BootstrapBraidService(AppServiceHub appServiceHub){
this.appServiceHub = appServiceHub;
this.braidConfig = new BraidConfig();
// Include a flow on the Braid server.
braidConfig.withFlow(ExtendedStatusFlow.IssueFlow.class);
// Include a service on the Braid server.
braidConfig.withService("myService", new BraidService(appServiceHub));
// The port the Braid server listens on.
braidConfig.withPort(3001);
// Using http instead of https.
braidConfig.withHttpServerOptions(new HttpServerOptions().setSsl(false));
// Start the Braid server.
braidConfig.bootstrapBraid(this.appServiceHub,Object::notify);
}
}
However node startup without my setting, like port use default(8080) instead of my setting(3001).
And NodeJS server fails to get services descriptor:
{ Error: failed to get services descriptor from
http://localhost:8080/api/
at createHangUpError (_http_client.js:331:15)
at Socket.socketOnEnd (_http_client.js:423:23)
at emitNone (events.js:111:20)
at Socket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9) code: 'ECONNRESET', url: 'http://localhost:8080/api/' }
Can somebody tell me how to fix this problem? Thanks.
Update:
the node shell screenshot
The reason why this isn't working is because BraidConfig is an immutable class with a fluent API, but your code is using it as a classic mutable POJO which means none of your changes are being applied to the BraidConfig.
The following should work fine:
#CordaService
public class BootstrapBraidService extends SingletonSerializeAsToken{
private AppServiceHub appServiceHub;
private BraidConfig braidConfig;
public BootstrapBraidService(AppServiceHub appServiceHub){
this.appServiceHub = appServiceHub;
this.braidConfig = new BraidConfig()
// Include a flow on the Braid server.
.withFlow(ExtendedStatusFlow.IssueFlow.class)
// Include a service on the Braid server.
braidConfig.withService(new BraidService(appServiceHub))
// The port the Braid server listens on.
braidConfig.withPort(3001)
// Using http instead of https.
braidConfig.withHttpServerOptions(new HttpServerOptions().setSsl(false));
// Start the Braid server.
braidConfig.bootstrapBraid(this.appServiceHub,null);
}
}
regards,
Fuzz
I have problem with vertx HttpClient.
Here's code which shows that tests GET using vertx and plain java.
Vertx vertx = Vertx.vertx();
HttpClientOptions options = new HttpClientOptions()
.setTrustAll(true)
.setSsl(false)
.setDefaultPort(80)
.setProtocolVersion(HttpVersion.HTTP_1_1)
.setLogActivity(true);
HttpClient client = vertx.createHttpClient(options);
client.getNow("google.com", "/", response -> {
System.out.println("Received response with status code " + response.statusCode());
});
System.out.println(getHTML("http://google.com"));
Where getHTML() is from here: How do I do a HTTP GET in Java?
This is my output:
<!doctype html><html... etc <- correct output from plain java
Feb 08, 2017 11:31:21 AM io.vertx.core.http.impl.HttpClientRequestImpl
SEVERE: java.net.UnknownHostException: failed to resolve 'google.com'. Exceeded max queries per resolve 3
But vertx can't connect. What's wrong here? I'm not using any proxy.
For reference: a solution, as described in this question and in tsegismont's comment here, is to set the flag vertx.disableDnsResolver to true:
-Dvertx.disableDnsResolver=true
in order to fall back to the JVM DNS resolver as explained here:
sometimes it can be desirable to use the JVM built-in resolver, the JVM system property -Dvertx.disableDnsResolver=true activates this behavior
I observed this DNS resolution issue with a redis client in a kubernetes environment.
I had this issue, what caused it for me was stale DNS servers being picked up by the Java runtime, i.e. servers registered for a network the machine was no longer connected to. The issue is first in the Sun JNDI implementation, it also exists in Netty which uses JNDI to bootstrap its list of name servers on most platforms, then finally shows up in VertX.
I think a good place to fix this would be in the Netty layer where the set of default DNS servers is bootstrapped. I have raised a ticket with the Netty project so we'll see if they agree with me! Here is the Netty ticket
In the mean time a fairly basic workaround is to filter the default DNS servers detected by Netty, based on whether they are reachable or not. Here is a code Sample in Kotlin to apply before constructing the main VertX instance.
// The default set of name servers provided by JNDI can contain stale entries
// This default set is picked up by Netty and in turn by VertX
// To work around this, we filter for only reachable name servers on startup
val nameServers = DefaultDnsServerAddressStreamProvider.defaultAddressList()
val reachableNameServers = nameServers.stream()
.filter {ns -> ns.address.isReachable(NS_REACHABLE_TIMEOUT)}
.map {ns -> ns.address.hostAddress}
.collect(Collectors.toList())
if (reachableNameServers.size == 0)
throw StartupException("There are no reachable name servers available")
val opts = VertxOptions()
opts.addressResolverOptions.servers = reachableNameServers
// The primary Vertx instance
val vertx = Vertx.vertx(opts)
A little more detail in case it is helpful. I have a company machine, which at some point was connected to the company network by a physical cable. Details of the company's internal name servers were set up by DHCP on the physical interface. Using the wireless interface at home, DNS for the wireless interface gets set to my home DNS while the config for the physical interface is not updated. This is fine since that device is not active, ipconfig /all does not show the internal company DNS servers. However, looking in the registry they are still there:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
They get picked up by the JNDI mechanism, which feeds Netty and in turn VertX. Since they are not reachable from my home location, DNS resolution fails. I can imagine this home/office situation is not unique to me! I don't know whether something similar could occur with multiple virtual interfaces on containers or VMs, it could be worth looking at if you are having problems.
Here is the sample code which works for me.
public class TemplVerticle extends HttpVerticle {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
// Create the web client and enable SSL/TLS with a trust store
WebClient client = WebClient.create(vertx,
new WebClientOptions()
.setSsl(true)
.setTrustAll(true)
.setDefaultPort(443)
.setKeepAlive(true)
.setDefaultHost("www.w3schools.com")
);
client.get("www.w3schools.com")
.as(BodyCodec.string())
.send(ar -> {
if (ar.succeeded()) {
HttpResponse<String> response = ar.result();
System.out.println("Got HTTP response body");
System.out.println(response.body().toString());
} else {
ar.cause().printStackTrace();
}
});
}
}
Try using web client instead of httpclient, here you have an example (with rx):
private val client: WebClient = WebClient.create(vertx, WebClientOptions()
.setSsl(true)
.setTrustAll(true)
.setDefaultPort(443)
.setKeepAlive(true)
)
open fun <T> get(uri: String, marshaller: Class<T>): Single<T> {
return client.getAbs(host + uri).rxSend()
.map { extractJson(it, uri, marshaller) }
}
Another option is to use getAbs.
I am using Logica OpenSMPP (http://opensmpp.org/) to manage messages via SMPP protocol. I have a server, which can answer on my SMS and USSD messages, and I am developing a client. I have already managed to send DeliverSM message and get SubmitSM response from server via SMS: first I start SMSC, and then do something like that:
DeliverSM request = new DeliverSM();
request.setSourceAddr(from);
request.setDestAddr(to);
try {
request.setShortMessage(message);
} catch (WrongLengthOfStringException e) {
log.error("Error during setShortMessage", e);
}
request.setRegisteredDelivery((byte) 0);
new Transmitter(this.connection).send(request);
But I encounter some problems while doing the same for USSD. I know, that I must somehow use the following (cut from SMPP V3.4 Specification):
The ussd_service_op parameter is required to define the USSD service
operation when SMPP is being used as an interface to a (GSM) USSD
system.
What are the steps that I need to do to learn my client send both SMS and USSD messages to server?
This project hosts code for sending USSD. You may consider browsing the code to see how it's done, and then implement similar features in Logica OpenSMPP.
I am following the Jetty HttpClient Example, but I am unable to get an SSL connection working. When I connect using a proxy, it throws a "Not Implemented" exception. When I don't use a proxy, it doesn't return anything.
HttpClient client = new HttpClient();
client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
client.setProxy(new Address("www.example.com", 80));
client.start();
// create the exchange object, which lets you define where you want to go
// and what you want to do once you get a response
ContentExchange exchange = new ContentExchange()
{
// define the callback method to process the response when you get it
// back
protected void onResponseComplete() throws IOException
{
super.onResponseComplete();
String responseContent = this.getResponseContent();
// do something with the response content
System.out.println(responseContent);
}
};
exchange.setMethod("GET");
exchange.setURL("https://www.example.com");
exchange.setScheme(HttpSchemes.HTTPS_BUFFER);
// start the exchange
client.send(exchange);
exchange.waitForDone();
System.err.println("Response status: " + exchange.getResponseStatus());
Jetty v7.4.1:
if (dest.isSecure()) {
if (dest.isProxied()) {
SSLEngine engine=newSslEngine(channel); ep = new ProxySelectChannelEndPoint(channel, selectSet, key, _sslBuffers, engine, (int)_httpClient.getIdleTimeout());
} else { ...
Yeah weird, the source code for the Jetty-Client's SelectConnector looks like the following:
if (dest.isProxied()) {
String connect = HttpMethods.CONNECT+" "+dest.getAddress()+HttpVersions.HTTP_1_0+"\r\n\r\n";
// TODO need to send this over channel unencrypted and setup endpoint to ignore the 200 OK response.
throw new IllegalStateException("Not Implemented");
}
so the functionality doesn't exist at present - at least in the version I'm using (6.1.16) for using a proxy in this kind of way. It's also the same in the milestone Jetty 7 version (I found after downloading the source code).
I suggest your try a different client - check out Apache HttpClient:
http://hc.apache.org/httpclient-3.x/
The Jetty developers should really have marked this clearly in the Javadocs. another alternative is to implementinghave a go at implementing the feature for them and submitting it back as a patch.
try ProxyHandler (jetty 7) which handle connect-command for tunneling https-connection (via proxy)