ví dụ đơn giản về ứng dụng khách javax.websocket


104

Ai đó có thể vui lòng cung cấp cho tôi ví dụ rất đơn giản về ứng dụng websocket sử dụng javax.websocketkhông?

Tôi muốn kết nối với websocket (ws: //socket.example.com: 1234), gửi tin nhắn (thêm kênh) và nghe tin nhắn. Tất cả tin nhắn (đã gửi và đã nghe) đều ở định dạng JSON.

Và btw thư viện này có phải là thư viện tốt nhất cho giao tiếp websocket đơn giản không?

Câu trả lời:


120

Tôi đã tìm thấy một ví dụ tuyệt vời bằng cách sử dụng javax.websocketở đây:

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

Đây là mã dựa trên ví dụ được liên kết ở trên:

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
Xin chào, làm cách nào để làm cho mã này hoạt động nếu websocketServer đang gửi một luồng thư liên tục và websocketClient cần sử dụng từng thư một? Tôi nhận được lỗi "Tin nhắn văn bản giải mã là quá lớn đối với bộ đệm đầu ra và các thiết bị đầu cuối không hỗ trợ tin nhắn một phần" sau khi chạy mã trong khoảng một phút
firstpostcommenter

Đảm bảo maven-import org.java-websocket.
Albert Hendriks

9
Mã này không thành công với lỗi: Không thể tìm thấy lớp triển khai.
Kirk Sefchik

2
@deathgaze javax.websocket api chỉ là thông số kỹ thuật không có triển khai đầy đủ, bạn có thể cần lấy tệp jar tyrus-standalone-client-1.9.jar và thử cùng một ví dụ sẽ giải quyết được vấn đề của bạn. tôi đã thử nghiệm với ví dụ của mình và nó đang hoạt động tốt. Hy vọng điều này sẽ giúp bạn.
SRK

@Martin Làm cách nào để gửi tin nhắn khi Mở. Ví dụ: Tôi cần gửi '{"type": "subscribe", "Symbol": "AAPL"}' khi mở websocket để đăng ký.
Buddhismka

40

TooTallNate có một phía khách hàng đơn giản https://github.com/TooTallNate/Java-WebSocket

Chỉ cần thêm java_websocket.jar trong thư mục dist vào dự án của bạn.

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

// và để đóng websocket

 mWs.close();

4
Làm việc trong Windows 7, windows 8 và OS X sư tử núi bằng eclipse, máy chủ là Ubuntu.
TCassells vào

1
tại sao bạn chọn thư viện này thay vì javax?
BvuRVKyUVlViVIc7

2
gây ra nó rõ ràng là đơn giản
Kyle Luke

4
những thay đổi nào cần thiết để hỗ trợ giao thức wss (ws bảo mật)?
Mihailo Stupar

2
Thư viện tuyệt vời, nhưng nó có vấn đề với wss. Dự án có một số vấn đề mở và nhà phát triển nhận xét rằng anh ta không còn thời gian nữa.
SiKing

18

Hãy xem các ví dụ Java EE 7 này từ Arun Gupta.

Tôi đã tách nó trên github .

Chủ yếu

/**
 * @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();
    }
}

Bạn nên đề cập rằng nó yêu cầu sự phụ thuộc vào websocket được vận chuyển riêng
Java Main


1

Sử dụng thư viện này org.java_websocket

Điều đầu tiên bạn nên nhập thư viện đó trong build.gradle

repositories {
 mavenCentral()
 }

sau đó thêm việc triển khai trong phụ thuộc {}

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

Sau đó, bạn có thể sử dụng mã này

Trong hoạt động của bạn, khai báo đối tượng cho Websocketclient như

private WebSocketClient mWebSocketClient;

sau đó thêm phương thức này để gọi lại

 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

Tôi có Spring 4.2 trong dự án của mình và nhiều triển khai SockJS Stomp thường hoạt động tốt với các triển khai Spring Boot. Việc triển khai này từ Baeldung đã hoạt động (đối với tôi mà không thay đổi từ Spring 4.2 thành 5). Sau khi Sử dụng các phụ thuộc được đề cập trong blog của anh ấy, nó vẫn cho tôi ClassNotFoundError. Tôi đã thêm phụ thuộc bên dưới để sửa chữa nó.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.