Pracuję nad projektem open source, Storj. Piszę klienta Java, który łączy się z backendem websocket Node.js. Klient korzysta z Tyrusa. Komunikat powinien udać się następująco:Klient sieci web Tyrus @OnMessage nigdy nie był wywoływany - Storj Projekt open source
- Połącz
- Klient wysyła żeton uwierzytelniający (tekst).
- Serwer wysyła plik z powrotem (plik binarny).
- Serwer zamyka połączenie.
Mam problemy, ponieważ moja wiadomość @OnMessage nigdy nie zostanie wywołana. Próbowałem z prostym klientem javascript online tutaj na ten sam URL i z tym samym tokenem: https://www.websocket.org/echo.html
Otrzymuję odpowiedź za pomocą tego, co mówi mi, że coś jest nie tak z projektem Java.
Przed pobraniem pliku, na wcześniejszym etapie, mogę przesłać plik bez żadnych problemów. Jednak ten krok nie wymaga wywołania funkcji @OnMessage (po prostu powoduje przesłanie pliku, a następnie serwer rozłącza się z wiadomością), więc nie jestem pewien, czy moja wiadomość @OnMessage jest zawsze aktywna.
Oto odpowiedni kod dla websocket (dostępne także na Github): https://github.com/NutterzUK/storj-java-bridge-client/blob/master/storj-client/src/main/java/storj/io/client/websockets/WebsocketFileRetriever.java
package storj.io.client.websockets;
import com.google.gson.Gson;
import storj.io.restclient.model.FilePointer;
import javax.websocket.*;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;
/**
* Created by steve on 12/07/2016.
*/
@ClientEndpoint
public class WebsocketFileRetriever {
private Logger logger = Logger.getLogger(this.getClass().getName());
private Gson gson = new Gson();
private FilePointer filePointer;
private File outputFile;
private AuthorizationModel authModel;
private CountDownLatch latch;
public WebsocketFileRetriever(FilePointer filePointer, File outputFile, CountDownLatch latch){
this.filePointer = filePointer;
this.latch = latch;
this.outputFile = outputFile;
authModel = new AuthorizationModel();
authModel.setToken(filePointer.getToken());
authModel.setOperation(filePointer.getOperation());
authModel.setHash(filePointer.getHash());
}
@OnMessage
public void onMessage(String s){
logger.info("Received ... " + s);
}
@OnMessage
public void onMessage(ByteBuffer message, Session session) {
logger.info("Received ...." + message);
}
@OnOpen
public void onOpen(Session session, EndpointConfig endpointConfig) {
logger.info("Opened");
try {
session.getBasicRemote().sendText(gson.toJson(authModel), true);
} catch (IOException e) {
e.printStackTrace();
}
logger.info("sent: " + gson.toJson(authModel));
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
logger.info("Closed Websocket: " + closeReason.getCloseCode() + " " + closeReason.getReasonPhrase());
//latch.countDown();
}
@OnError
public void onError(Session session, Throwable t) {
t.printStackTrace();
}
}
I kod, który rozpoczyna ten websocket, dostępny tutaj https://github.com/NutterzUK/storj-java-bridge-client/blob/master/storj-client/src/main/java/storj/io/client/DefaultStorjClient.java:
CountDownLatch latch;
latch = new CountDownLatch(1);
ClientManager wsClient = ClientManager.createClient();
try {
wsClient.setDefaultMaxBinaryMessageBufferSize(Integer.MAX_VALUE);
wsClient.setDefaultMaxTextMessageBufferSize(Integer.MAX_VALUE);
logger.info("CONNECTING TO: " + "ws://" + pointer.getFarmer().getAddress() + ":" + pointer.getFarmer().getPort());
final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
wsClient.connectToServer(new WebsocketFileRetriever(pointer, encryptedOutputFile, latch), cec, new URI("ws://" + pointer.getFarmer().getAddress() + ":" + pointer.getFarmer().getPort()));
latch.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
I próbowałem również uaktualnić Tyrusa do najnowszej wersji i otrzymałem taki sam wynik. Jakieś pomysły?
Wyjście z tego kodu jest:
Aug 25, 2016 8:55:31 PM storj.io.client.DefaultStorjClient downloadFile
INFO: CONNECTING TO: ws://164.storj.eu:8607
Aug 25, 2016 8:55:35 PM storj.io.client.websockets.WebsocketFileRetriever onOpen
INFO: Opened
Aug 25, 2016 8:55:35 PM storj.io.client.websockets.WebsocketFileRetriever onOpen
INFO: sent: {"token":"06c36d4bac4f07ee1751068b5b2230f22e884b38","hash":"837b79bec927a1d8fa7fedd2ea0bb276e0d86e0f","operation":"PULL"}
Aug 25, 2016 8:56:11 PM storj.io.client.websockets.WebsocketFileRetriever onClose
INFO: Closed Websocket: NORMAL_CLOSURE Closing
Po wysłaniu wiadomości, że wisi na chwilę przed komunikatem „NORMAL_CLOSURE” z @OnClose.
Update: Naprawdę łatwy sposób uruchomić to odtworzyć problem
Dodałem nazwę użytkownika i hasło testowy do repozytorium git, więc kod dostępny jest tutaj: https://github.com/NutterzUK/storj-java-bridge-client
Aby uruchom go, wystarczy uruchomić storj.io.client.main.MainTest
Szybkie przejrzenie tego, co robi. Najpierw wyśle trochę żądań HTTP, aby uzyskać token. Użyje tego tokena do połączenia się z czyjąś maszyną poprzez websocket, a ten token wyśle jako tekst. W odpowiedzi powinien otrzymać plik jako bajty.
Zanim się połączy, wydrukuje token i adres, z którym ma się połączyć. Zawiesza się na chwilę przed zamknięciem i nie jest wywoływana żadna metoda onMessage. Do testowania, jeśli umieścisz tam plik System.exit (Uncomment Line 152 w DefaultStorjClient.java), to się nie połączy, więc możesz użyć tego tokena w innym kliencie. Przetestowałem używając https://www.websocket.org/echo.html (Upewnij się, że Twoja przeglądarka zezwala na niebezpieczne adresy URL, ponieważ nie jest to "wss", aby to zrobić, musisz kliknąć tarczę w prawym górnym rogu.Widzę, że serwer odpowiada:
Pokazuje to, że obiekt blob jest rzeczywiście wysyłany w odpowiedzi na wiadomość tekstową, ale wiadomość @OnMessage w Tyrusie nigdy nie zostaje zwolniona.
Serwer JS wysyła to jako "blob", może to być związane/lub problem? – ThePerson
Byłoby miło mieć coś testowalnego. Mam na myśli ... Połączyłem się z usługą, ale nie mogę wysłać mi pliku, więc nie mogę sprawdzić, czy Tyrus może otrzymać wiadomość z twojego serwera. W każdym razie Tyrus pracuje również z serwerem echa, więc nie jest to naprawdę przydatny test. (po prostu wskaż klienta tyrus na "ws: //echo.websocket.org" i wyślij wiadomość). –
Dzięki. Tak, działa z serwerem echa, ale echo, którego nie sądzę, odsyła bajty. Myślę, że jeśli założysz konto na storj.io (To nic nie kosztuje), możesz uruchomić "testmain" i wysłać plik, aby go przetestować. Wszystko dzieje się na Githubie, niestety jestem naprawdę zdumiony, dlaczego tak się dzieje, więc dodam nagrodę za to pytanie za 7 godzin, kiedy będę mógł. – ThePerson