【问题标题】:javax.websocket client simple examplejavax.websocket 客户端简单示例
【发布时间】:2014-12-14 16:23:33
【问题描述】:

谁能给我提供一个非常简单的使用javax.websocket的websocket客户端示例?

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

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

【问题讨论】:

    标签: java websocket


    【解决方案1】:

    我在这里找到了一个使用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);
            }
        }
    
       @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);
        }
    }
    

    【讨论】:

    • 您好,如果 websocketServer 正在发送连续的消息流并且 websocketClient 需要一一消费消息,如何使这段代码工作?运行代码大约一分钟后,我收到错误“解码的文本消息对于输出缓冲区来说太大,端点不支持部分消息”
    • 确保 maven-import org.java-websocket.
    • 此代码失败并出现错误:找不到实现类。
    • @deathgaze javax.websocket api 只是规范没有完整的实现,您可能需要获取 jar 文件 tyrus-standalone-client-1.9.jar 并尝试应该解决您问题的相同示例问题。我用我的例子进行了测试,它工作正常。希望这会对你有所帮助。
    • @Martin 如何在打开时发送消息。示例:我需要在打开 websocket 时发送 '{"type":"subscribe","symbol":"AAPL"}' 进行订阅。
    【解决方案2】:

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

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

    【讨论】:

    • 我添加了一个适用于 Spring MVC 的实现。为什么投反对票?
    • 春天没有受到质疑。其他依赖 java 的客户端应用程序(例如 android 应用程序)无法使用此功能
    • @MojioMS 但是有人会为 SpringMVC 打开这个问题并且我会提供这个答案的概率是多少? OP因为他有Java但没有spring mvc而忽略了这个答案不是更好吗?对于那些有 websocket 问题并且有 spring 的人来说,这个贡献可能很有用。
    • 好吧,我已经做到了——我们也称它为“错误”。我没有否决你的答案,只是想给出一个解释。在您的答案中添加某种“Spring 框架解决方案”标题可能会很有用。
    【解决方案3】:

    使用这个库 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();
    

    }

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 使用 Eclipse 在 Windows 7、Windows 8 和 OS X 山狮中工作,服务器是 Ubuntu。
      • 为什么你会选择这个库而不是 javax 的?
      • 因为它显然更简单
      • 需要哪些更改才能支持 wss 协议(安全 ws)?
      • 很棒的库,但是 wss 有问题。该项目有几个未解决的问题,开发人员认为他没有时间了。
      【解决方案5】:

      看看这个来自 Arun Gupta 的 Java EE 7 示例。

      我 fork 了 on 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 依赖
      猜你喜欢
      • 2011-09-04
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多