127

Can someone please provide me very simple example of websocket client using javax.websocket?

I want to connect to websocket (ws://socket.example.com:1234), send message (add channel) and listen to messages. All messages (sent & listened) are in JSON format.

And btw is this library the best for simple websocket communication?

Neuron
  • 5,141
  • 5
  • 38
  • 59
Martin Ille
  • 6,747
  • 9
  • 44
  • 63

6 Answers6

145

I've found a great example using javax.websocket here:

http://www.programmingforliving.com/2013/08/jsr-356-java-api-for-websocket-client-api.html

Here the code based on the example linked above:

TestApp.java:

package testapp;

import java.net.URI;
import java.net.URISyntaxException;

public class TestApp {

    public static void main(String[] args) {
        try {
            // open websocket
            final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(new URI("wss://real.okcoin.cn:10440/websocket/okcoinapi"));

            // add listener
            clientEndPoint.addMessageHandler(new WebsocketClientEndpoint.MessageHandler() {
                public void handleMessage(String message) {
                    System.out.println(message);
                }
            });

            // send message to websocket
            clientEndPoint.sendMessage("{'event':'addChannel','channel':'ok_btccny_ticker'}");

            // wait 5 seconds for messages from websocket
            Thread.sleep(5000);

        } catch (InterruptedException ex) {
            System.err.println("InterruptedException exception: " + ex.getMessage());
        } catch (URISyntaxException ex) {
            System.err.println("URISyntaxException exception: " + ex.getMessage());
        }
    }
}

WebsocketClientEndpoint.java:

package testapp;

import java.net.URI;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

/**
 * ChatServer Client
 *
 * @author Jiji_Sasidharan
 */
@ClientEndpoint
public class WebsocketClientEndpoint {

    Session userSession = null;
    private MessageHandler messageHandler;

    public WebsocketClientEndpoint(URI endpointURI) {
        try {
            WebSocketContainer container = ContainerProvider.getWebSocketContainer();
            container.connectToServer(this, endpointURI);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Callback hook for Connection open events.
     *
     * @param userSession the userSession which is opened.
     */
    @OnOpen
    public void onOpen(Session userSession) {
        System.out.println("opening websocket");
        this.userSession = userSession;
    }

    /**
     * Callback hook for Connection close events.
     *
     * @param userSession the userSession which is getting closed.
     * @param reason the reason for connection close
     */
    @OnClose
    public void onClose(Session userSession, CloseReason reason) {
        System.out.println("closing websocket");
        this.userSession = null;
    }

    /**
     * Callback hook for Message Events. This method will be invoked when a client send a message.
     *
     * @param message The text message
     */
    @OnMessage
    public void onMessage(String message) {
        if (this.messageHandler != null) {
            this.messageHandler.handleMessage(message);
        }
    }

   @OnMessage
   public void onMessage(ByteBuffer bytes) {
        System.out.println("Handle byte buffer");
    }

    /**
     * register message handler
     *
     * @param msgHandler
     */
    public void addMessageHandler(MessageHandler msgHandler) {
        this.messageHandler = msgHandler;
    }

    /**
     * Send a message.
     *
     * @param message
     */
    public void sendMessage(String message) {
        this.userSession.getAsyncRemote().sendText(message);
    }

    /**
     * Message handler.
     *
     * @author Jiji_Sasidharan
     */
    public static interface MessageHandler {

        public void handleMessage(String message);
    }
}
Martin Ille
  • 6,747
  • 9
  • 44
  • 63
  • 2
    Hi, how to make this code work if the websocketServer is sending a continuous stream of messages and websocketClient needs to consume the messages one by one? I get the error "The decoded text message was too big for the output buffer and the endpoint does not support partial messages" after running the code for about a minute – firstpostcommenter Dec 01 '17 at 15:23
  • Make sure to maven-import org.java-websocket. – Albert Hendriks Mar 25 '18 at 11:20
  • 21
    This code fails with the error: Could not find an implementation class. – Kirk Sefchik Jul 05 '18 at 14:13
  • 6
    @deathgaze javax.websocket api is only the specification don't have full implementation you may need to take the jar file tyrus-standalone-client-1.9.jar and try the same example that should solve your problem. i tested with my example and it is working fine. hope this will help you. – SRK Oct 17 '18 at 13:54
  • @Martin How can I send a message on Open. Example : I need to send '{"type":"subscribe","symbol":"AAPL"}' on open the websocket to subscribe. – Buddhika Feb 10 '20 at 10:06
  • 1
    for those who is getting error "Could not find an implementation class." should also include tyrus-standalone-client-1.9.jar while building . you can download it from [here](https://repo1.maven.org/maven2/org/glassfish/tyrus/bundles/tyrus-standalone-client/1.9/) – Tarun Rawat Feb 29 '20 at 10:02
51

TooTallNate has a simple client side https://github.com/TooTallNate/Java-WebSocket

Just add the java_websocket.jar in the dist folder into your project.

 import org.java_websocket.client.WebSocketClient;
 import org.java_websocket.drafts.Draft_10;
 import org.java_websocket.handshake.ServerHandshake;
 import org.json.JSONException;
 import org.json.JSONObject;

  WebSocketClient mWs = new WebSocketClient( new URI( "ws://socket.example.com:1234" ), new Draft_10() )
{
                    @Override
                    public void onMessage( String message ) {
                     JSONObject obj = new JSONObject(message);
                     String channel = obj.getString("channel");
                    }

                    @Override
                    public void onOpen( ServerHandshake handshake ) {
                        System.out.println( "opened connection" );
                    }

                    @Override
                    public void onClose( int code, String reason, boolean remote ) {
                        System.out.println( "closed connection" );
                    }

                    @Override
                    public void onError( Exception ex ) {
                        ex.printStackTrace();
                    }

                };
 //open websocket
 mWs.connect();
 JSONObject obj = new JSONObject();
 obj.put("event", "addChannel");
 obj.put("channel", "ok_btccny_ticker");
 String message = obj.toString();
 //send message
 mWs.send(message);

// and to close websocket

 mWs.close();
AmanicA
  • 4,659
  • 1
  • 34
  • 49
TCassells
  • 629
  • 4
  • 5
24

Have a look at this Java EE 7 examples from Arun Gupta.

I forked it on github.

Main

/**
 * @author Arun Gupta
 */
public class Client {

    final static CountDownLatch messageLatch = new CountDownLatch(1);

    public static void main(String[] args) {
        try {
            WebSocketContainer container = ContainerProvider.getWebSocketContainer();
            String uri = "ws://echo.websocket.org:80/";
            System.out.println("Connecting to " + uri);
            container.connectToServer(MyClientEndpoint.class, URI.create(uri));
            messageLatch.await(100, TimeUnit.SECONDS);
        } catch (DeploymentException | InterruptedException | IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

ClientEndpoint

/**
 * @author Arun Gupta
 */
@ClientEndpoint
public class MyClientEndpoint {
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("Connected to endpoint: " + session.getBasicRemote());
        try {
            String name = "Duke";
            System.out.println("Sending message to endpoint: " + name);
            session.getBasicRemote().sendText(name);
        } catch (IOException ex) {
            Logger.getLogger(MyClientEndpoint.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @OnMessage
    public void processMessage(String message) {
        System.out.println("Received message in client: " + message);
        Client.messageLatch.countDown();
    }

    @OnError
    public void processError(Throwable t) {
        t.printStackTrace();
    }
}
assylias
  • 321,522
  • 82
  • 660
  • 783
Koekiebox
  • 5,793
  • 14
  • 53
  • 88
5

Use this library org.java_websocket

First thing you should import that library in build.gradle

repositories {
 mavenCentral()
 }

then add the implementation in dependency{}

implementation "org.java-websocket:Java-WebSocket:1.3.0"

Then you can use this code

In your activity declare object for Websocketclient like

private WebSocketClient mWebSocketClient;

then add this method for callback

 private void ConnectToWebSocket() {
URI uri;
try {
    uri = new URI("ws://your web socket url");
} catch (URISyntaxException e) {
    e.printStackTrace();
    return;
}

mWebSocketClient = new WebSocketClient(uri) {
    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        Log.i("Websocket", "Opened");
        mWebSocketClient.send("Hello from " + Build.MANUFACTURER + " " + Build.MODEL);
    }

    @Override
    public void onMessage(String s) {
        final String message = s;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                TextView textView = (TextView)findViewById(R.id.edittext_chatbox);
                textView.setText(textView.getText() + "\n" + message);
            }
        });
    }

    @Override
    public void onClose(int i, String s, boolean b) {
        Log.i("Websocket", "Closed " + s);
    }

    @Override
    public void onError(Exception e) {
        Log.i("Websocket", "Error " + e.getMessage());
    }
};
mWebSocketClient.connect();

}

Muhammed Fasil
  • 7,909
  • 2
  • 19
  • 28
0

I have Spring 4.2 in my project and many SockJS Stomp implementations usually work well with Spring Boot implementations. This implementation from Baeldung worked(for me without changing from Spring 4.2 to 5). After Using the dependencies mentioned in his blog, it still gave me ClassNotFoundError. I added the below dependency to fix it.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>
veritas
  • 378
  • 1
  • 6
  • 16
  • I added an implemenation that worked for Spring MVC. why the downvote? – veritas Oct 07 '20 at 17:43
  • Spring was not questioned for. Other java-dependent client applications (e.g. android app's) cannot make use of this – MojioMS Sep 10 '21 at 07:45
  • 1
    @MojioMS But what is the probability that someone will open this question for SpringMVC and I will offer that answer? Isn't it better the OP ignores this answer because he has Java but not spring mvc? For those who have a websocket issue and have spring, this contribution could be useful. – veritas Sep 10 '21 at 12:12
  • 1
    Well, I've made that - lets call it 'mistake' - too. I didn't vote down your answer but just wanted to give an explanation. It might be useful to add some kind of 'Spring Framework solution'-title to your answer. – MojioMS Sep 13 '21 at 08:17
0

Here is such a solution from - com.neovisionary.ws.client.Web socket - https://github.com/TakahikoKawasaki/nv-websocket-client

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFactory;
import com.neovisionaries.ws.client.WebSocketFrame;

public class WssM {

    public static List<String> ListMessage = new ArrayList<>();
    public static boolean WebSocketLog = true;
    public static final String WssURL = "wss://site.com/api/sport_tree_ws/v1";
    public static final String WebsocketMessage = "{\"type\": \"subscribe_state\", \"subscribe_state\": {\"uid\": \"-1\"}}";

    

    public static void main(String[] args) throws IOException, WebSocketException {
        WebSocket socket = connect(WssURL);
        BufferedReader in = getInput();
        socket.sendText(WebsocketMessage);
        String text;
        try {
            while ((text = in.readLine()) != null) {
                if (text.equals("exit")) break;
                if (!socket.isOpen()) {
                    System.out.println("Socket is closed. Trying to reconnect...");
                    socket.recreate().connect();
                    System.out.println("Reconnected!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (socket.isOpen()) {
                System.out.println("Disconnecting connection to server!");
                socket.disconnect(); //Close the WebSocket.
            }
        }
    }
    private static WebSocket connect(String Host) throws IOException, WebSocketException {
        WebSocketFactory wsFactory = new WebSocketFactory().setConnectionTimeout(55000);
        WebSocket socket = wsFactory.createSocket(URI.create(Host)).addProtocol("json");//.addHeader("Sec-WebSocket-Protocol", "json")
        //WebSocket socket = wsFactory.createSocket(URI.create(HOST + "?Authorization=" + DUMMY_JWT_TOKEN));
        socket.addListener(new WebSocketAdapter() {
            @Override
            public void onSendingHandshake(WebSocket websocket, String requestLine, List<String[]> headers) {
                if (WebSocketLog) System.out.println(requestLine);
                for (String[] header : headers) { //Print the header, "{name}: {value}"
                    if (WebSocketLog) System.out.format("%s: %s\n", header[0], header[1]);
                }
            }
            @Override
            public void onConnected(WebSocket websocket, Map<String, List<String>> headers) {
                if (WebSocketLog) System.out.println("Success! WebSocket - Connected!");
            }
            @Override
            public void onTextMessage(WebSocket websocket, String text) {
                if (WebSocketLog) System.out.printf("MessageToClient: %s%n", text); ListMessage.add(text);
            }
            @Override
            public void onDisconnected(WebSocket websocket, WebSocketFrame serverCloseFrame, WebSocketFrame clientCloseFrame, boolean closedByServer) {
                if (WebSocketLog) System.out.println("Disconnecting...");
                if (WebSocketLog) System.out.printf(" Opcode: %d%n", serverCloseFrame.getOpcode());
            }
            @Override
            public void onPongFrame(WebSocket websocket, WebSocketFrame frame) {
                if (WebSocketLog) System.out.printf("Received some pong..!! Payload text: %s%n", frame.getPayloadText());
                System.out.printf(" Opcode: %d%n", frame.getOpcode());
            }
            @Override
            public void onPingFrame(WebSocket websocket, WebSocketFrame frame) {
                if (WebSocketLog) System.out.printf("I have been pinged by server at %s%n", LocalDateTime.now());
                websocket.sendPong("Ponging from client");
            }
            @Override
            public void onTextFrame(WebSocket websocket, WebSocketFrame frame) {
                if (WebSocketLog) System.out.printf("onTextFrame - %s%n", LocalDateTime.now());
                websocket.sendPong("onTextFrame from client");
            }
            @Override
            public void onError(WebSocket websocket, WebSocketException cause) {
                System.out.printf("I have received exception %s%n", cause.getMessage());
            }
        }).connect();
        return socket;
    }

    private static BufferedReader getInput() {
        return new BufferedReader(new InputStreamReader(System.in));
    }
}
Hard Core
  • 1
  • 1