先ほどに続いて送受信部分
送信処理
- 画面の送信ボタンからSingleController#handleSendActionが呼ばれる。
- SingleController#handleSendActionから@ClientEndpointのsendメソッド(自分で作った普通のメソッド)を呼び出す。
- sendメソッド内でSession.getAsyncRemote().sendObject(dataObj)を呼び出す
- encodersに指定してあるClientEncoderクラスのencodeメソッドが呼び出される。
- encodeメソッドでエンコードされたデータ(JSON形式の文字列)がServerEndpointに送信される。
エコープログラムなのでServerEndpointで受信されたデータは(若干加工され)ClientEndpointに戻される。そのため、続けて受信処理が走る。
受信処理
- サーバからのデータがPushされる。
- @ClientEndpointのdecodersに指定してあるClientDecoderクラスのwillDecodeメソッドが呼び出され入力値がチェックされる。
- willDecodeの結果がtrueならば続けてdecodeメソッドが呼び出されてジェネリクスで指定した型(ClientData)にデコードされる。
- デコードされたデータを引数に@ClientEndpointの@OnMessageが呼び出される。ここはJavaFXのスレッド配下ではなく、WebSocketのスレッドに移っている。そのため、JavaFXのコントロールを直接操作することはできない。
- @OnMessageの中でPlatform.runLaterを呼び、JavaFXの画面操作(接続時処理ViewObj#write)の呼び出しを登録(?)する。
- JavaFXスレッドに戻り、JavaFXの画面操作が実行される。
(コントローラーの関連する部分)
public class SingleController implements Initializable {
@FXML
private void handleSendAction(ActionEvent event) {
System.out.println("SingleController#handleSendAction");
wsClient.send(msgInput.getText(), sess);
}
}
(ClientEndpointの関連する部分)
@ClientEndpoint( decoders = { ClientDecoder.class }, encoders = { ClientEncoder.class }) public class WSJsonSingleClient { @OnMessage public void onMessage(ClientData dataObj) { System.out.println("WSJsonSingleClient#onMessage"); final ClientData channeled = dataObj; Platform.runLater(new Runnable() { @Override public void run() { viewObj.write( channeled.getSessionId(), channeled.getMessageTimeString(), channeled.getMessage()); }; }); } public void send(String text,Session sess) { System.out.println("WSJsonSingleClient#send"); ClientData dataObj = new ClientData(text); sess.getAsyncRemote().sendObject(dataObj); } }
(ClientEncoder)
public class ClientEncoder implements Encoder.Text<ClientData> {
@Override
public void init(EndpointConfig paramEndpointConfig) {
System.out.println("ClientEncoder#init");
}
@Override
public void destroy() {
System.out.println("ClientEncoder#destroy");
}
@Override
public String encode(ClientData paramData) throws EncodeException {
System.out.println("ClientEncoder#encode");
JsonObject model = Json.createObjectBuilder()
.add("message", paramData.getMessage())
.add("messageTime",paramData.getMessageTime())
.build();
return model.toString();
}
}
(ClientDecoder)
public class ClientDecoder implements Decoder.Text<ClientData> {
@Override
public void destroy() {
System.out.println("ClientDecoder#destroy");
}
@Override
public void init(EndpointConfig arg0) {
System.out.println("ClientDecoder#init");
}
@Override
public ClientData decode(String inputString) throws DecodeException {
System.out.println("ClientDecoder#decode");
try{
JsonObject jsonObject = Json.createReader(new StringReader(inputString)).readObject();
return new ClientData(jsonObject);
} catch(Exception e){
e.printStackTrace();
throw new DecodeException(inputString,"ClientDecoder#decode失敗", (Throwable)e);
}
}
@Override
public boolean willDecode(String inputString) {
try {
System.out.println("ClientDecoder#willDecode");
Json.createReader(new StringReader(inputString)).readObject();
return true;
} catch (JsonException ex) {
ex.printStackTrace();
return false;
}
}
}
github:https://github.com/epea/test01/tree/WF_JSON_FX_SINGLE






