Jetty websocket client connect to Stomp.js topic channel - websocket

I have written a Spring Websocket server which is assessible from a browser via Stomp.js. I am now attempting to implement a Java client in order to connect my server to a secondary system. I am able to connect to the server using the following code
String destUri = "ws://localhost:8080/sample";
WebSocketClient client = new WebSocketClient();
SimpleEchoSocket socket = new SimpleEchoSocket();
try {
client.start();
URI echoUri = new URI(destUri);
ClientUpgradeRequest request = new ClientUpgradeRequest();
client.connect(socket, echoUri, request);
System.out.printf("Connecting to : %s%n", echoUri);
socket.awaitClose(5, TimeUnit.SECONDS);
} catch (Throwable t) {
t.printStackTrace();
}
The connection is opened, and now I would like to connect to my topic /price-stream. This is achieved by stomp.js :
stompClient.subscribe('/topic/pricechannel1', renderPrice);
what is the equivalent subscribe method for my Jetty websocket client? I cant find anything in the documentation I have found on the net.
Additional info:
I am trying to implement the stockticker example found here into another project. I can connect to the server through the provided Stomp.js interface in a web browser. Now I am attempting to create a Java client for use within a Swing GUI using Jetty websocket-client to connect.
I need to connect to the price stream, but it seems I am missing some kind of configuration request to latch on as a destination for the topic

In general, plain websocket clients (as the one provided by Jetty) support the websocket standard. STOMP is a protocol that sits on top of that transport.
Here, you'd need to implement your own STOMP client or interface an existing one with the websocket client you're using.
Spring 4.2 (to be published soon) includes a new STOMP client for this particular use case. See the reference documentation of 4.2.RC2.

Related

How to make a socket server that listens for client connections and opens a socket once an Endpoint is called in Spring?

I have an application that opens a "HttpURLConnection" to a printer. The printer is listening for socket connection and makes a connection when a new TCP socket connection is opened on the Application side (In this case through a new "HttpURLConnection"). Now, I want to mock this printer.
In the Application an Http call is made to the printer server and a socket connection is established between the Application and the server. How do I mock this printer as a spring boot application.
Sounds like you need to take a look into Spring Test Framework and especially its part about a Web: https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/testing.html#spring-mvc-test-client
I would really investigate a possibility to interact via a RestTemplate instead of direct HttpURLConnection and then use that MockRestServiceServer for mocking requests and responses.
Another way is to use a #SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) and implement controller with appropriate mappings and possible return results. This way you would be able to use the mentioned HttpURLConnection to connect to randomly allocated port for HTTP server and perform requests as in production.

How Amazon MQ service works without asking client to use TrustStore and KeyStore?

When we configure the SSL on standalone ActiveMQ, we may need to provide the TrustStore,TrustStore Password, KeyStore and KeyStore password in client code to connect to the Active MQ over SSL protocol but in case of AmazonMQ, though they have provided SSL endpoint, but we can connect to it simply without providing the trust and key related values.
Client code snippet for Simple ActiveMQ over SSL:
ActiveMQSslConnectionFactory connFactory = new ActiveMQSslConnectionFactory("ssl://<someHost>:61617");
String trustStore = "pathTo/client_new.ts";
String keyStore = "PathTo/client_new.ks";
try {
connFactory.setTrustStore(trustStore);
connFactory.setTrustStorePassword("password");
connFactory.setKeyStore(keyStore);
connFactory.setKeyStorePassword("password");
} catch (Exception e) {
e.printStackTrace();
}
Client code snippet for Amazon MQ over SSL:
ActiveMQConnectionFactory connFactory = new ActiveMQConnectionFactory("ssl://xyz.amazonaws.com:61617");
Basically, what make this difference?
Firstly AmazonMQ works on top of the ActiveMQ, amazon has written a wrapper layer over activeMQ so as functionality wise it works pretty much the same. AmazonMQ is managed Message Broker Service for ActiveMQ.
It manages everything related to space, configuring active/passive endpoints in different regions and some benefits mentioned in the below links.
https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/welcome.html
Other benefits of amazonMQ is you can setup alerts and many more as part of using other services of amazon like upgrading activemq version to the latest.
Now coming to you application part, one good thing was the way you have configured activemq was via SSL connection, though activemq exposes tcp endpoint as well which can be connected by simply providing broker URL but in case of amazonMQ it does not exposes any TCP endpoint only way to connect is by providing SSL endpoint and related parameters.
Refer this link on how application is connected to amazonMQ:
https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-connecting-application.html

How do we connect Spring WebClient to a Unix Domain Socket?

Spring's WebClient underlyingly uses Netty which access to Unix domain sockets. I am trying to make it access /var/run/docker.sock so that I can perform operations using the API as I need /services which is not supported by the docker-java library.
My current workaround is to create a socat container that exposes the Docker socket to TCP within an internal network which in turn allows me to use WebClient's HTTP connections.
Though come to think of it, having this workaround gives one benefit of not needing to put a larger Java application on the manager node.
However, I am still curious how to connect to the unix domain docket.
You can create a Netty HttpClient following their documentation regarding Unix Domain Sockets here.
import io.netty.channel.unix.DomainSocketAddress;
import reactor.netty.http.client.HttpClient;
HttpClient client = HttpClient.create()
.remoteAddress(() -> new DomainSocketAddress("/var/run/docker.sock"));
Then you can tell WebClient to use this HttpClient like this.
WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(client))
.build();
You can expose the docker daemon over TCP and use the REST API.

when do sockjs fallback to xhr streaming transport instead of websocket

I have a simple web app, which is using websockets.
simple webapp:
Frontend - using sockjs, stomp
Backend - Spring 4.2.x
Frontend & Backend are packaged in the same WAR, this WAR is deployed on IBM WebSphere Application Server v9.x
When I check the Developer Tools/Web Console in chrome(61.x)/firefox(56.0, 32 bit), I see that websocket transport is not being used, it's always xhr streaming. To use the websocket transport, I have passed the transports option in sockjs, like below, but after this change the websockets stopped working.
var sockjs = new SockJS(my url, null, {transports: ["websocket"]});
Do we need to change any configuration on IBM WebSphere Application Server v9.x to enable websocket transport ?
Update: on tomcat/liberty servers, sample app always uses websocket transport. Only on WAS, it is using xhr streaming. Issue in WAS?
Websocket protocol handling is on by default for Websphere v9.x

To post a message to a remote Queue using Web-Logic

I have gained some knowledge on consuming messages that are posted to a resource. In the process I used a stand-alone which posts messages to the local queue. Now, the task is to post messages to a remote queue, which resides in a server(say TIBCO), other than Web-Logic, which I use here.
My question is :
a) Are there any notable differences to be taken care of, when posting to a remote queue?
Sending a message to a remote server is pretty simple. All you need is the URL of the remote server and the port number on which the JMS provider is listening for the incoming connections. Once you have these details then you do a JNDI Lookup for the Queue and establish a Session to send out the message. Something like below:
// Provide the details of remote JMS Server
Properties props = new Properties();
props.put(Context.PROVIDER_URL, "mq://localhost:7676");
// Create the initial context for remote JMS server
InitialContext cntxt = new InitialContext(props);
System.out.println("Context Created");
// JNDI Lookup for QueueConnectionFactory in remote JMS Provider
QueueConnectionFactory qFactory = (QueueConnectionFactory)cntxt.lookup("TestQueueConnectionFactory");
// Create a Connection from QueueConnectionFactory
Connection connection = qFactory.createConnection();
System.out.println("Connection established with JMS Provide ");
See this JMS Client Server Example for full code details. I am guess you are only interested in the client code from this example.
What do you want to achieve?
If you simply want to post a message to a queue on any JMS compliant broker i would give a try to the Hermes Tool: http://www.hermesjms.com/confluence/display/HJMS/Home
Cheers

Resources