javax.websocket client semplice esempio


104

Qualcuno può fornirmi un esempio molto semplice di utilizzo del client WebSocket javax.websocket?

Voglio connettermi a websocket (ws: //socket.example.com: 1234), inviare un messaggio (aggiungere canale) e ascoltare i messaggi. Tutti i messaggi (inviati e ascoltati) sono in formato JSON.

E a proposito, questa libreria è la migliore per una semplice comunicazione websocket?

Risposte:


120

Ho trovato un ottimo esempio usando javax.websocketqui:

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

Di seguito il codice basato sull'esempio collegato sopra:

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

1
Ciao, come far funzionare questo codice se il websocketServer invia un flusso continuo di messaggi e websocketClient ha bisogno di consumare i messaggi uno per uno? Ottengo l'errore "Il messaggio di testo decodificato era troppo grande per il buffer di output e l'endpoint non supporta i messaggi parziali" dopo aver eseguito il codice per circa un minuto
firstpostcommenter

Assicurati di eseguire maven-import org.java-websocket.
Albert Hendriks

9
Questo codice non riesce con l'errore: Impossibile trovare una classe di implementazione.
Kirk Sefchik

2
@deathgaze javax.websocket api è solo che la specifica non ha un'implementazione completa, potresti dover prendere il file jar tyrus-standalone-client-1.9.jar e provare lo stesso esempio che dovrebbe risolvere il tuo problema. ho provato con il mio esempio e funziona bene. spero che questo ti possa aiutare.
SRK

@Martin Come posso inviare un messaggio su Open. Esempio: devo inviare "{" type ":" subscribe "," symbol ":" AAPL "} 'all'apertura del websocket per iscrivermi.
Buddhika

40

TooTallNate ha un semplice lato client https://github.com/TooTallNate/Java-WebSocket

Basta aggiungere java_websocket.jar nella cartella dist nel tuo progetto.

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

// e per chiudere websocket

 mWs.close();

4
Funzionava con Windows 7, Windows 8 e OS X Mountain Lion utilizzando eclipse, il server era Ubuntu.
TCassells

1
perché sceglieresti questa libreria invece di quelle javax?
BvuRVKyUVlViVIc7

2
perché è ovviamente più semplice
Kyle Luke

4
quali modifiche sono necessarie per supportare il protocollo wss (secure ws)?
Mihailo Stupar

2
Ottima libreria, ma ha problemi con wss. Il progetto ha diversi problemi aperti e lo sviluppatore commenta che non ha più tempo.
SiKing

18

Dai un'occhiata a questi esempi di Java EE 7 da Arun Gupta.

L'ho biforcato su 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();
    }
}

Dovresti menzionare che richiede la dipendenza websocket fornita separatamente
Java Main


1

Usa questa libreria org.java_websocket

Per prima cosa dovresti importare quella libreria in build.gradle

repositories {
 mavenCentral()
 }

quindi aggiungi l'implementazione in dipendenza {}

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

Quindi puoi usare questo codice

Nella tua attività dichiara oggetto per Websocketclient like

private WebSocketClient mWebSocketClient;

quindi aggiungi questo metodo per la richiamata

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

}


-2

Ho Spring 4.2 nel mio progetto e molte implementazioni di SockJS Stomp di solito funzionano bene con le implementazioni di Spring Boot. Questa implementazione di Baeldung ha funzionato (per me senza cambiare dalla primavera 4.2 alla 5). Dopo aver utilizzato le dipendenze menzionate nel suo blog, mi ha comunque dato ClassNotFoundError. Ho aggiunto la seguente dipendenza per risolverlo.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.