Exemple simple de client javax.websocket

104

Quelqu'un peut-il me fournir un exemple très simple d'utilisation du client Websocket javax.websocket?

Je veux me connecter à websocket (ws: //socket.example.com: 1234), envoyer un message (ajouter un canal) et écouter les messages. Tous les messages (envoyés et écoutés) sont au format JSON.

Et btw est-ce que cette bibliothèque est la meilleure pour une communication websocket simple?

Martin
la source

Réponses:

120

J'ai trouvé un excellent exemple en utilisant javax.websocketici:

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

Voici le code basé sur l'exemple lié ci-dessus:

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);
        }
    }

    /**
     * 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
la source
1
Salut, comment faire fonctionner ce code si le websocketServer envoie un flux continu de messages et que websocketClient doit consommer les messages un par un? J'obtiens l'erreur "Le message texte décodé était trop gros pour le tampon de sortie et le point de terminaison ne prend pas en charge les messages partiels" après avoir exécuté le code pendant environ une minute
firstpostcommenter
Assurez-vous de maven-import org.java-websocket.
Albert Hendriks
9
Ce code échoue avec l'erreur: Impossible de trouver une classe d'implémentation.
Kirk Sefchik
2
@deathgaze javax.websocket api est que la spécification n'a pas d'implémentation complète, vous devrez peut-être prendre le fichier jar tyrus-standalone-client-1.9.jar et essayer le même exemple qui devrait résoudre votre problème. J'ai testé avec mon exemple et cela fonctionne très bien. J'espère que ceci vous aidera.
SRK
@Martin Comment puis-je envoyer un message sur Open. Exemple: je dois envoyer '{"type": "subscribe", "symbol": "AAPL"}' à l'ouverture du websocket pour m'abonner.
Buddhika
40

TooTallNate a un côté client simple https://github.com/TooTallNate/Java-WebSocket

Ajoutez simplement le java_websocket.jar dans le dossier dist de votre projet.

 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);

// et pour fermer websocket

 mWs.close();
TCassells
la source
4
Travaillé sous Windows 7, Windows 8 et OS X mountain lion en utilisant eclipse, le serveur était Ubuntu.
TCassells
1
pourquoi choisiriez-vous cette bibliothèque au lieu de celles javax?
BvuRVKyUVlViVIc7
2
car c'est évidemment plus simple
Kyle Luke
4
Quels changements sont nécessaires pour prendre en charge le protocole wss (ws sécurisé)?
Mihailo Stupar
2
Excellente bibliothèque, mais elle a des problèmes avec wss. Le projet a plusieurs problèmes en suspens, et le développeur commente qu'il n'a plus le temps.
SiKing
18

Jetez un œil à ces exemples Java EE 7 d'Arun Gupta.

Je l'ai fourché sur github .

Principale

/**
 * @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();
    }
}
Koekiebox
la source
Vous devez mentionner qu'il nécessite la dépendance websocket expédiée séparément
Java Main
1

Utilisez cette bibliothèque org.java_websocket

La première chose que vous devez importer cette bibliothèque dans build.gradle

repositories {
 mavenCentral()
 }

puis ajoutez l'implémentation dans la dépendance {}

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

Ensuite, vous pouvez utiliser ce code

Dans votre activité, déclarez un objet pour Websocketclient comme

private WebSocketClient mWebSocketClient;

puis ajoutez cette méthode pour le rappel

 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
la source
-2

J'ai Spring 4.2 dans mon projet et de nombreuses implémentations SockJS Stomp fonctionnent généralement bien avec les implémentations Spring Boot. Cette implémentation de Baeldung a fonctionné (pour moi sans passer de Spring 4.2 à 5). Après avoir utilisé les dépendances mentionnées dans son blog, cela m'a toujours donné ClassNotFoundError. J'ai ajouté la dépendance ci-dessous pour le réparer.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>
veritas
la source