Герою не удается обработать веб-сокет
Я пытаюсь использовать веб-сокет с искрой, и я использую / чат в качестве URL-адреса конечной точки. Ниже мой код.
@ServerEndpoint("/chat")
public class Main {
public static void main(String[] args) {
port(Integer.valueOf(System.getenv("PORT")));
Spark.staticFileLocation("/public");
}
private static final Set<Session> sessions = Collections
.synchronizedSet(new HashSet<Session>());
private static final HashMap<String, String> nameSessionPair = new HashMap<String, String>();
private JSONUtils jsonUtils = new JSONUtils();
public static Map<String, String> getQueryMap(String query) {
Map<String, String> map = Maps.newHashMap();
if (query != null) {
String[] params = query.split("&");
for (String param : params) {
String[] nameval = param.split("=");
map.put(nameval[0], nameval[1]);
}
}
return map;
}
@OnOpen
public void onOpen(Session session) {
System.out.println(session.getId() + " has opened a connection");
Map<String, String> queryParams = getQueryMap(session.getQueryString());
String name = "";
if (queryParams.containsKey("name")) {
name = queryParams.get("name");
try {
name = URLDecoder.decode(name, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
nameSessionPair.put(session.getId(), name);
}
sessions.add(session);
try {
session.getBasicRemote().sendText(
jsonUtils.getClientDetailsJson(session.getId(),
"Your session details"));
} catch (IOException e) {
e.printStackTrace();
}
sendMessageToAll(session.getId(), name, " joined conversation!", true,
false);
}
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message from " + session.getId() + ": " + message);
String msg = null;
try {
JSONObject jObj = new JSONObject(message);
msg = jObj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
sendMessageToAll(session.getId(), nameSessionPair.get(session.getId()),
msg, false, false);
}
@OnClose
public void onClose(Session session) {
System.out.println("Session " + session.getId() + " has ended");
String name = nameSessionPair.get(session.getId());
sessions.remove(session);
sendMessageToAll(session.getId(), name, " left conversation!", false,
true);
}
private void sendMessageToAll(String sessionId, String name,
String message, boolean isNewClient, boolean isExit) {
for (Session s : sessions) {
String json = null;
if (isNewClient) {
json = jsonUtils.getNewClientJson(sessionId, name, message,
sessions.size());
} else if (isExit) {
json = jsonUtils.getClientExitJson(sessionId, name, message,
sessions.size());
} else {
json = jsonUtils
.getSendAllMessageJson(sessionId, name, message);
}
try {
System.out.println("Sending Message To: " + sessionId + ", "
+ json);
s.getBasicRemote().sendText(json);
} catch (IOException e) {
System.out.println("error in sending. " + s.getId() + ", "
+ e.getMessage());
e.printStackTrace();
}
}
}
}
Проблема в том, что onOpen
метод никогда не вызывается, и когда пользователь достигает URL-адреса конечной точки, он выдает ошибку 404. Почему это так? Я развернул его с помощью heroku, и я использовал socket_url в качестве имени моего сайта, и я оставил порт пустым в моем файле js.
Как я могу разобраться в этом?
1 ответ
Решение
Этот код не будет работать с примером из Heroku.com. Это потому, что бегуны с котами и джетами не поддерживают аннотации к веб-сокетам (не знаю причину). Вы сможете запустить его с помощью встроенного Jetty. Пример основного метода, pom для maven и procfile для heroku вы можете найти по адресу privateblog.info:
web: java $JAVA_OPTS -cp target/JettyServer-0.0.1-SNAPSHOT-jar-with-dependencies.jar info.privateblog.Proxy $PORT