Saya mengalami masalah dalam membuat server websocket Tyrus mandiri yang sangat sederhana berfungsi. Saya membuat ini berfungsi dalam keadaan yang sangat spesifik yang tidak masuk akal bagi saya.
Kasus yang berfungsi dengan benar adalah saat saya mendefinisikan kelas titik akhir server tingkat atas (dalam filenya sendiri) dan membubuhi keterangan dengan @ServerEndpoint. Kelas ini mencakup metode yang dianotasi dengan @OnOpen, @OnMessage, dan @OnClose, semuanya umum. Saya meneruskan kelas ini ke konstruktor Server. Klien sederhana saya dapat terhubung ke server ini, dan berhasil mengirimkan pesan yang diterima oleh server.
Masalahnya terjadi ketika saya mengubah kelas titik akhir server tingkat atas menjadi kelas dalam dari kelas yang menginisialisasi server (ini adalah SATU-SATUNYA perubahan yang saya buat). Dalam hal ini klien saya dapat terhubung dan metode @OnOpen klien dipanggil. Namun server tidak membuat instance titik akhir server dan, akibatnya, metode @OnOpen tidak pernah dipanggil. Jelas, penerimaan pesan server tidak terjadi.
Apakah ada persyaratan di Tyrus bahwa kelas titik akhir server yang dianotasi tidak boleh menjadi kelas dalam? Jika tidak, apakah ada izin khusus pada kelas titik akhir server (semuanya telah dipublikasikan untuk mencoba membuatnya berfungsi tetapi tidak berhasil)? Saya menggunakan Tyrus 1.9 dengan JDK 1.7 di Mac, OSX 1.9.5.
Server sederhana (termasuk dan dikonfigurasi untuk menggunakan titik akhir server dalam yang gagal):
package tyrus.example;
import java.util.concurrent.TimeUnit;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.glassfish.tyrus.server.Server;
public class SimpleServer
{
private static final String HOST_ADDR = "localhost";
private static final int HOST_PORT = 8025;
public static void main(String[] args) {
Server websocketServer = new Server(HOST_ADDR, HOST_PORT, "/ws", null, InnerSimpleServerEndpoint.class);
try {
websocketServer.start();
Thread.sleep(TimeUnit.MINUTES.toMillis(5));
}
catch (Exception e) {
e.printStackTrace();
}
websocketServer.stop();
System.out.println("Done.");
}
@ServerEndpoint("/myapp")
public class InnerSimpleServerEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("Connection received for "+session.getRequestURI());
}
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message received: "+message);
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
System.out.println("Session closed, reason: "+closeReason);
}
}
}
Klien sederhana:
package tyrus.example;
import java.io.IOException;
import java.net.URI;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import org.glassfish.tyrus.client.ClientManager;
public class SimpleClient
{
private static final String DEF_WS_URL = "ws://localhost:8025/ws/myapp";
public static void main(String[] args) {
ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
ClientManager client = ClientManager.createClient();
try {
client.connectToServer(new ClientEndpoint(), cec, new URI(DEF_WS_URL));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Done.");
}
private static class ClientEndpoint extends Endpoint {
@Override
public void onOpen(Session session, EndpointConfig config) {
System.out.println("ClientEndpoint: server session opened: "+session);
session.addMessageHandler(new MessageHandler.Whole<String>() {
@Override
public void onMessage(String message) {
System.out.println("ClientEndpoint: received message: "+message);
}
});
try {
session.getBasicRemote().sendText("Hello server!");
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
Dan terakhir titik akhir server kelas non-dalam yang berfungsi saat server menggunakannya:
package tyrus.example;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/myapp")
public class SimpleServerEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("Connection received for "+session.getRequestURI());
}
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message received: "+message);
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
System.out.println("Session closed, reason: "+closeReason);
}
}