0
WebSocketを使用して2つのスタンドアロンのjar間の通信を確実にします。最初は埋め込まれたJettyを起動し、WebSocketをデプロイし、2つ目はJetty WebSocketクライアントで、コマンドを送信してサーバー部分の処理を待機します。Jetty WebSocketで接続が失われたことを検出する方法
サーバー:
import java.io.IOException;
import javax.websocket.*;
@ClientEndpoint
@ServerEndpoint(value = "/websocket-api", encoders = { NotificationEncoder.class }, decoders = { NotificationDecoder.class })
public class APIWebsocket {
private static final Logger log = LoggerFactory.getLogger(APIWebsocket.class);
@OnOpen
public void open(Session session) {
log.info("Session opened...");
}
@OnClose
public void close(Session session) throws IOException {
session.close();
log.info("Session closed !");
}
@OnError
public void onError(Throwable error) {
log.error("Error during websocket session : {}", error.getMessage());
log.debug("{}", error);
}
@OnMessage
public void handleMessage(String message, Session session) {
log.info("Message received : {}", message);
List<Data> datas = JSONHelper.toCollection(message);
for (Data data : datas){
// do process with average time 30sec...
// send notification of processing
Notification unitNotification= new Notification("PROCESSED");
session.getBasicRemote().sendObject(unitNotification);
}
// Build and send end notification message
Notification endProcessNotification = new Notification("END OF PROCESS");
session.getBasicRemote().sendObject(endProcessNotification);
} catch (EncodeException | IOException e) {
log.error(e.getMessage(), e);
// Manage error
} finally {
try {
session.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
// Manage error
}
}
}
}
クライアント:
import java.io.IOException;
import java.net.URI;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.client.WebSocketClient;
public class WebsocketClient extends WebSocketAdapter {
private static final Logger log = LoggerFactory.getLogger(WebsocketClient.class);
private Session session = null;
public APIWebsocketClient(String uri) {
try {
WebSocketClient client = new WebSocketClient();
client.setMaxIdleTimeout(35 * 1000L);
client.start();
client.connect(this, new URI(uri)).get();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
public void startProcess(String datas) {
try {
session.getRemote().sendString(datas);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
@Override
public void onWebSocketText(String message) {
log.info("Message received : {}", message);
}
@Override
public void onWebSocketClose(int statusCode, String reason) {
log.info("Websocket closed ! [statusCode={}, reason={}]", statusCode, reason);
this.session.close();
}
@Override
public void onWebSocketConnect(Session session) {
this.session = session;
log.info("Websocket Client details : {}-{}", session.getLocalAddress().getHostName(), session
.getLocalAddress().getAddress().getHostAddress());
}
@Override
public void onWebSocketError(Throwable cause) {
log.error("Error during websocket execution : {}", cause.getMessage(), cause);
if (this.session != null) {
this.session.close();
}
}
}
私の目標は、ネットワーク通信は、クライアントとサーバー間で失われたかどうかを検出することです。ネットワークの損失をシミュレートすると、ネットワークワイヤを切断することにより、WebSocketはサーバー側とクライアント側の両方で通信エラーを検出するはずです。
クライアントとサーバー間のネットワーク損失をどのように検出できるか考えていますか?
サーバー側はいくつかの処理を実行し、それぞれの処理の状態を別々に送信する必要があります(サーバーの更新されたソースコードを確認できます) 現在、ネットワーク接続の損失をシミュレートしようとすると、 WebScoketがまだ閉じていなければ、その処理を終了し、接続の再開に戻る。 私の質問です:なぜ接続の喪失、@OnErrorイベントが発生していないのですか? 「This is Java」と言えば、接続損失を処理するロジックを追加する必要がありますか? –
Javaでのネットワーク接続の切断は、実際のネットワーク入出力が実行されている場合にのみ検出されます。接続(および接続を使用しようとする試み)がアイドル状態の場合、接続損失を示すイベントはありません。 –