In
this post, I am going to show you, how can we connect to a websocket end point
using a websocket client written in Java.
Prevoius
Next
Home
Lets
devide the steps.
a.
Build
websocket server endpoint
b.
Implement
a websocket client and connect to the websocket server endpoint
Finally,
web socket clients send some message to websocket server endpoint, and server receive
the message, convert the message to upper case and send it back to client.
Build websocket
server endpoint
Follow
below step-by-step procedure to build websocket server endpoint in eclipse.
I
am going to use below maven dependencies to build server end point.
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<!--
https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
Step 1: Create new dynamic
web project ‘websocketServerDemo’ in eclipse.
Step 2: Mavenize the project
‘websocketServerDemo’. Right click on the project -> Configure -> Convert
To Maven project.
Step 2: Update dependencies
in pom.xml
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>websocketServerDemo</groupId> <artifactId>websocketServerDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <warSourceDirectory>WebContent</warSourceDirectory> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.2</version> </dependency> </dependencies> </project>
Step 3: Define package
com.sample.model. Create a class Message in the package com.sample.model.
Message.java
package com.sample.model; public class Message { private String secretMessage; public String getSecretMessage() { return secretMessage; } public void setSecretMessage(String secretMessage) { this.secretMessage = secretMessage; } }
Step 3: Define package
‘com.sample.util’. Create a class JSONUtil.java.
JSONUtil.java
package com.sample.util; import com.google.gson.Gson; public class JSONUtil { private static Gson gson = new Gson(); /** * @param obj * @return json string of this object. */ public static String getJson(Object obj) { return gson.toJson(obj); } /** * Convert given json string to object. * * @param json * @param obj * @return an object by populating properties with json data. */ public static <T> T getObject(String json, Class<T> clazz) { return gson.fromJson(json, clazz); } }
Step 4: Define package
com.sample.encoders. Create MessageEncoder and MessageDecoder classes.
MessageEncoder.java
package com.sample.encoders; import javax.websocket.EncodeException; import javax.websocket.Encoder; import javax.websocket.EndpointConfig; import com.sample.model.Message; public class MessageEncoder implements Encoder.Text<Message> { @Override public void init(EndpointConfig config) { // TODO Auto-generated method stub } @Override public void destroy() { // TODO Auto-generated method stub } @Override public String encode(Message object) throws EncodeException { return com.sample.util.JSONUtil.getJson(object); //return null; } }
MessageDecoder.java
package com.sample.encoders; import javax.websocket.DecodeException; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; import com.sample.model.Message; import com.sample.util.JSONUtil; public class MessageDecoder implements Decoder.Text<Message> { @Override public void init(EndpointConfig config) { } @Override public void destroy() { } @Override public Message decode(String s) throws DecodeException { Message message = JSONUtil.getObject(s, Message.class); return message; } @Override public boolean willDecode(String s) { return true; } }
Step 5: Define package
‘com.sample.endpoint’. Create class WebSocketServer.java.
WebSocketServer.java
package com.sample.endpoint; import java.io.IOException; import javax.websocket.EncodeException; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import com.sample.encoders.MessageDecoder; import com.sample.encoders.MessageEncoder; import com.sample.model.Message; import com.sample.util.JSONUtil; @ServerEndpoint(value = "/connectToMe", encoders = MessageEncoder.class, decoders = MessageDecoder.class) public class WebSocketServer { @OnOpen public void onOpen(Session session) { System.out.println("Session Opened"); } @OnMessage public void onMessage(Message message, Session session) throws IOException, EncodeException { String secretMessage = message.getSecretMessage(); String result = secretMessage.toUpperCase(); Message resultMsg = new Message(); resultMsg.setSecretMessage(result); session.getBasicRemote().sendText(JSONUtil.getJson(resultMsg)); } @OnClose public void onClose(Session session) throws IOException, EncodeException { } @OnError public void onError(Throwable t) { } }
Total
project structure looks like below.
Implement websocket
client
Step 1: Create new java maven
project.
Right
click on project explorer -> New -> other.
Search
for maven.
Select
‘maven project’ and press Next button.
Select
the check box ‘Create a simple project (skip archetype selection).
Give
group id and artifact id as 'websocketClientDemo'
Click
on Finish button.
Step 2: Update maven
dependencies.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>websocketClientDemp</groupId> <artifactId>websocketClientDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api --> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.glassfish.tyrus.bundles/tyrus-standalone-client --> <dependency> <groupId>org.glassfish.tyrus.bundles</groupId> <artifactId>tyrus-standalone-client</artifactId> <version>1.9</version> </dependency> </dependencies> </project>
Step 3: Define the classes JSONUtil,
Message, MessageEncoder and MessageDecoder classes. Source code is same like
the source code defined in Websocket server application.
Step 4: Define the package
‘com.sample.client’. Create class
WebSocketClient.
WebSocketClient.java
package com.sample.client; import javax.websocket.ClientEndpoint; import javax.websocket.OnMessage; import com.sample.encoders.MessageDecoder; import com.sample.encoders.MessageEncoder; import com.sample.model.Message; @ClientEndpoint(encoders = MessageEncoder.class, decoders = MessageDecoder.class) public class WebSocketClient { @OnMessage public void onMessage(Message message) { String secretMsg = message.getSecretMessage(); System.out.println("Message received is : " + secretMsg); } }
Step 5: Define package
com.sample.test, create class TestClient.java.
TestClient.java
package com.sample.test; import org.glassfish.tyrus.client.ClientManager; import java.io.IOException; import java.net.*; import javax.websocket.DeploymentException; import com.sample.client.WebSocketClient; import com.sample.model.Message; import com.sample.util.JSONUtil; public class TestClient { public static void main(String args[]) throws DeploymentException, IOException, URISyntaxException, InterruptedException{ String server = "ws://localhost:8080/websocketServerDemo-0.0.1-SNAPSHOT/connectToMe"; String secretMessage = "good morning"; ClientManager client = ClientManager.createClient(); // client.getProperties().put(ClientProperties.PROXY_URI, "http://proxy:8083/"); javax.websocket.Session websocketSession = client.connectToServer(WebSocketClient.class, new URI(server)); websocketSession.setMaxIdleTimeout(0); Message message = new Message(); message.setSecretMessage(secretMessage); websocketSession.getBasicRemote().sendText(JSONUtil.getJson(message)); while(true){ Thread.sleep(2000); } } }
Project
structure looks like below.
Deploy the war file
Generate
the war file.
Right
click on the project -> Run As-> Maven Install.
Above
step generates the war file. Deploy the war file to server. If you are using
tomcat, copy the war file to webapps directory and start the server.
Once
the application is deployed, run TestClient.java application, you can able to
see the message ‘good morning’ in capital letters.
Exception in thread "main" javax.websocket.DeploymentException: Handshake response not received.
ReplyDeleteat org.glassfish.tyrus.client.ClientManager$3$1.run(ClientManager.java:655)
at org.glassfish.tyrus.client.ClientManager$3.run(ClientManager.java:673)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:826)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:496)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:312)
at com.renault.rpSimulator.RPsimulator.webSocketEndPoint.TestClient.main(TestClient.java:24)
Process finished with exit code 1
any idea ?