2017-02-03 6 views
1

Я хочу иметь клиента, который будет получать сообщения WS и хранить их для дальнейшего анализа.Tyrus - Сохранять сообщения, полученные клиентом

Я создал клиент на основе https://dzone.com/articles/sample-java-web-socket-client

К сожалению по каждому методу OnMessage называют поле, которое будет хранить значение является недействительным и сообщение не может быть добавлено.

Код

package com.sample.ws; 

import org.apache.log4j.Logger; 

import javax.websocket.*; 
import java.net.URI; 
import java.util.ArrayList; 
import java.util.List; 

import static java.lang.Thread.sleep; 

@ClientEndpoint 
public class WSClient { 
    private static final Logger LOG = Logger.getLogger(WSClient.class); 

    private List<String> testContext; 

    public static void main(String[] args) { 
     WSClient client = new WSClient(); 

     List testContext = new ArrayList<String>(); 
     client.setTestContext(testContext); 

     client.run(); 

     LOG.info("Final state: " + testContext); 
    } 

    private void run() { 
     LOG.info("Initial state: " + testContext); 

     WebSocketContainer container = null;// 
     Session session = null; 
     try { 
      container = ContainerProvider.getWebSocketContainer(); 
      session = container.connectToServer(com.sample.ws.WSClient.class, URI.create("ws://localhost:8080/wsserver-1.0/ratesrv")); 
      LOG.info("Connected to server"); 
      sleep(10000L); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (session != null) { 
       try { 
        session.close(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

    @OnMessage 
    private void onMessage(String message) { 
     //the new USD rate arrives from the websocket server side. 
     LOG.info("Received msg: " + message); 
     testContext.add(message); 
    } 

    private void setTestContext(List<String> testContext) { 
     this.testContext = testContext; 
    } 
} 

Вход

INFO WSClient - Initial state: [] 
INFO WSClient - Connected to server 
INFO WSClient - Received msg: USD Rate: 2.998 
Feb 03, 2017 5:52:22 PM org.glassfish.tyrus.core.AnnotatedEndpoint onError 
INFO: Unhandled exception in endpoint com.sample.ws.WSClient. 
java.lang.NullPointerException 
    at com.sample.ws.WSClient.onMessage(WSClient.java:55) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.glassfish.tyrus.core.AnnotatedEndpoint.callMethod(AnnotatedEndpoint.java:520) 
    at org.glassfish.tyrus.core.AnnotatedEndpoint.access$100(AnnotatedEndpoint.java:87) 
    at org.glassfish.tyrus.core.AnnotatedEndpoint$WholeHandler$1.onMessage(AnnotatedEndpoint.java:619) 
    at org.glassfish.tyrus.core.TyrusSession.notifyMessageHandlers(TyrusSession.java:576) 
    at org.glassfish.tyrus.core.TyrusEndpointWrapper.onMessage(TyrusEndpointWrapper.java:879) 
    at org.glassfish.tyrus.core.TyrusWebSocket.onMessage(TyrusWebSocket.java:216) 
    at org.glassfish.tyrus.core.frame.TextFrame.respond(TextFrame.java:139) 
    at org.glassfish.tyrus.core.ProtocolHandler.process(ProtocolHandler.java:807) 
    at org.glassfish.tyrus.client.TyrusClientEngine$TyrusReadHandler.handle(TyrusClientEngine.java:747) 
    at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientFilter$ProcessTask.execute(GrizzlyClientFilter.java:476) 
    at org.glassfish.tyrus.container.grizzly.client.TaskProcessor.processTask(TaskProcessor.java:114) 
    at org.glassfish.tyrus.container.grizzly.client.TaskProcessor.processTask(TaskProcessor.java:91) 
    at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientFilter.handleRead(GrizzlyClientFilter.java:272) 
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) 
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:526) 
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) 
    at java.lang.Thread.run(Thread.java:745) 
INFO WSClient - Final state: [] 

ответ

1

WebSocket клиент создает новый экземпляр и поле "TestContext" не заполняется там.

Сделать его статическим, и он начнет работать. Кроме того, вам необходимо сделать поток потокобезопасным. (то есть: CopyOnWriteArrayList).

Другим вариантом является вызов #connectToServer(Object, URI), который заставит клиента WebSocket использовать предоставленный экземпляр (а не создать новый). Опять же, вам необходимо убедиться, что ваша коллекция (и любые другие поля, к которым обращаются во время обработки) доступны в потокобезопасном режиме.

 Смежные вопросы

  • Нет связанных вопросов^_^