javax.websocket客户端简单示例


104

有人可以给我提供一个非常简单的websocket客户端使用示例javax.websocket吗?

我想连接到websocket(ws://socket.example.com:1234),发送消息(添加频道)并收听消息。所有消息(已发送和已收听)均为JSON格式。

顺便说一句,这个库最适合简单的WebSocket通信吗?

Answers:


120

我在javax.websocket这里找到了一个很好的例子:

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

这里的代码基于上面链接的示例:

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
嗨,如果websocketServer发送连续的消息流并且websocketClient需要一一消耗消息,如何使此代码起作用?运行代码约一分钟后,我收到错误消息“解码的文本消息对于输出缓冲区太大,并且端点不支持部分消息”
firstpostcommenter

确保Maven导入org.java-websocket。
艾伯特·亨德里克斯

9
此代码失败,并显示以下错误:找不到实现类。
柯克·塞夫奇克

2
@deathgaze javax.websocket api仅是规范没有完整的实现,您可能需要获取jar文件tyrus-standalone-client-1.9.jar并尝试可以解决您问题的相同示例。我用我的例子进行了测试,它工作正常。希望这会帮助你。
SRK

@Martin如何在Open上发送消息。示例:我需要在打开Websocket时发送'{“ type”:“ subscribe”,“ symbol”:“ AAPL”}'进行订阅。
Buddhika

40

TooTallNate有一个简单的客户端https://github.com/TooTallNate/Java-WebSocket

只需将dist文件夹中的java_websocket.jar添加到您的项目中即可。

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

//并关闭websocket

 mWs.close();

4
使用Eclipse在Windows 7,Windows 8和OS X美洲狮中工作,服务器为Ubuntu。
TCassells,2015年

1
为什么选择该库而不是Javax库?
BvuRVKyUVlViVIc7 7'26

2
因为它显然更简单
凯尔·卢克

4
支持wss协议(安全的ws)需要哪些更改?
Mihailo Stupar

2
很棒的图书馆,但是wss有问题。该项目有几个未解决的问题,开发人员评论说他没有时间了。
斯金

18

看看Arun Gupta的Java EE 7示例。

在github上分叉了它。

主要

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

客户端端点

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

您应该提到,它要求单独提供websocket依赖关系
Java Main


1

使用此库org.java_websocket

首先,您应该在build.gradle中导入该库

repositories {
 mavenCentral()
 }

然后在依赖项中添加实现{}

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

然后您可以使用此代码

在您的活动中声明Websocketclient的对象,例如

private WebSocketClient mWebSocketClient;

然后添加此方法进行回调

 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

我的项目中有Spring 4.2,许多SockJS Stomp实现通常可以与Spring Boot实现一起很好地工作。Baeldung的此实现奏效了(对我来说,从Spring 4.2更改为5)。使用他的博客中提到的依赖关系后,它仍然给我ClassNotFoundError。我添加了以下依赖项来修复它。

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.