2015-02-07 3 views
0

При развертывании приложения локально на Tomcat 7.0.54, а затем подключиться к ws: // localhost: 8080/request/subscription/messenger/xxxx все работает отлично.Не удается подключиться к tomcat java websocket удаленно, но локально может

Но при развертывании как .war на удаленном сервере (Tomcat 8.0.18 - websocket-api.jar находится в папке lib) невозможно подключиться, скажем ws: //myshost.com: 8080/request/подписка/Пейджер/хххх

FF в Firebug выходов "не может установить соединение с сервером" "NetworkError: 404 Not Found - http://myshost.com:8080/request/subscription/messenger/xxxx"

JS код WS-клиент:

  var webSocket; 
      var messages = document.getElementById("messages"); 
      var token = document.getElementById("token").value; 
//   var tokenTo = document.getElementById("token_to").value; 
      var subscrContext = document.getElementById("context").value; 
      var host = document.getElementById("host").value; 
//   var port = document.getElementById("port").value; 

      function openSocket(){ 
       // Ensures only one connection is open at a time 
       if(webSocket !== undefined && webSocket.readyState !== WebSocket.CLOSED){ 
        writeResponse("WebSocket is already opened."); 
        return; 
       } 
       // Create a new instance of the websocket 
       var wsUrl = "ws://"+host+":8080/request/subscription/"+subscrContext+"/"+token; 
       console.log(wsUrl); 
       webSocket = new WebSocket(wsUrl); 

       /** 
       * Binds functions to the listeners for the websocket. 
       */ 
       webSocket.onopen = function(event){ 
        // For reasons I can't determine, onopen gets called twice 
        // and the first time event.data is undefined. 
        // Leave a comment if you know the answer. 
        if(event.data === undefined) 
         return; 

        writeResponse(event.data); 
       }; 

       webSocket.onmessage = function(event){ 
//     var json = JSON.parse(event.data); 
        writeResponse(event.data); 
       }; 

       webSocket.onclose = function(event){ 
        writeResponse(event.data); 
       }; 
      } 

      /** 
      * Sends the value of the text input to the server 
      */ 
      function send(){ 
       var text = document.getElementById("messageinput").value; 
//    var json = { 
//     'action':'send_message', 
//     'uid':123, 
//     'text':text 
//    }; 
       webSocket.send(text); 
      } 

      function closeSocket(){ 
       webSocket.close(); 
      } 

      function writeResponse(text){ 
       messages.innerHTML += "<br/>" + text; 
      } 

      function clear() { 
       messages.innerHTML = ''; 
      }   

Java ws-server-endpoin т код

@ServerEndpoint(value = "/subscription/{context}/{token}", encoders = {MessageEncoder.class}, decoders = {MessageDecoder.class}) 
public class SubscriptionServer implements Commons { 

    private Queries q; 

// private ByteBuffer buff; 

    private int currentUserId; 

    private static final int   
      ERR_REQ_PARAM = 802; 

    // storing sessions for messenger 
    public static Map<Integer, Session> usersMessenger = new HashMap<>(), 
    // storing sessions for road 
    usersRoad = new HashMap<>(); 

    public static Map<Integer, List<Integer>> userPosts = new HashMap<>(); 

    private static final Map<Integer, String> 
      errUserMsg = new HashMap<>(), 
      errSysMsg = new HashMap<>(); 

    private String token; 

    private final static String 
      CONTEXT_MESSENGER = "messenger", 
      CONTEXT_ROAD = "road"; 

    @OnOpen 
    public void onOpen(@PathParam("context") String context, 
      @PathParam("token") String grossToken, Session sess) throws IOException, 
      ClassNotFoundException, SQLException, EncodeException, JSONException { 

    token = Helper.getToken(grossToken); 
    currentUserId = Helper.getUserId(grossToken);  

    Logger.log("open user: "+currentUserId); 

// sess.getBasicRemote().sendObject(
//   new JSONObject().put("token", token).put("uid", currentUserId)); 

    q = new Queries(); 

    if (q.checkToken(token, currentUserId) > 0) { 

     subscribeUser(currentUserId, sess, context); 

     sess.getBasicRemote().sendObject(new JSONObject() 
       .put("token", token).put("user_id", currentUserId)); 
    } else { 
     sess.getBasicRemote().sendObject(Helper.getErrorMessage(ERR_TOKEN, 
       "Этот аккаунт используется с другого устройства.", "Этот аккаунт используется с другого устройства.")); 
     sess.close();  
    } 

// System.out.println("User with id: " + sess.getId() + " has been connected!"); 

    } 

    @OnMessage 
    public void onMessage(@PathParam("context") String context, JSONObject json, Session sess) throws IOException, JSONException, EncodeException { 

// System.out.println("User with sid: "+sess.getId()+" sending msg:"+json.getString("text")); 
// JSONObject json = new JSONObject(msg); 
// Logger.log(json.toString()); 
// sess.getBasicRemote().sendText("Received message:"+json); 

    // ping - pong 
    if (json.has("ping") && json.getInt("ping")==1) { 
     sess.getBasicRemote().sendObject(new JSONObject().put("pong", 1)); 
     return; 
    } 

    switch (context) { 
     case CONTEXT_MESSENGER: 
     sendMessageEvent(json.getInt("user_id"), json, sess); 
     break; 
     case CONTEXT_ROAD: 
     sendRoadEvents(currentUserId, json, sess); 
     break; 
    } 

// String message = "Received message int bytes: "+msg; 
//  
// byte[] bytes = message.getBytes("UTF-16BE"); 
//  
// buff = ByteBuffer.allocate(bytes.length+1); 
//  
// buff.put(bytes); 
//  
// sess.getBasicRemote().sendBinary(buff); 
    } 

    @OnClose 
    public void onClose(Session sess, CloseReason reason, @PathParam("context") String context) 
      throws IOException, JSONException, EncodeException { 
    unsubscribeUser(currentUserId, context); 
    sess.getBasicRemote().sendObject(Helper.getSuccess(new JSONObject().put("reason", "ServerEndpoint timeout"))); 
    } 

    private void subscribeUser(int userId, Session sess, String context) { 

    Logger.log("subscribe user: "+userId); 

    SubscriptionQueries subscrQueries = new SubscriptionQueries(); 

    try { 
     // check tmp memory table - send if contains some  
     List<String> jsonList = subscrQueries.getSubscriptionTmp(userId); 

     if (!jsonList.isEmpty()) { 
     sess.getBasicRemote().sendObject(new JSONObject().put("success", jsonList)); 
     } 

     switch (context) { 
     case CONTEXT_MESSENGER: 
      usersMessenger.put(userId, sess); 
      sess.getBasicRemote().sendObject(Helper.getSuccess()); 
      break; 
     case CONTEXT_ROAD: 
      usersRoad.put(userId, sess); 
//   int startIndex = (request.getParameter("start_index") == null) ? 0 : Integer.parseInt(request.getParameter("start_index")); 
//   int quantity = (request.getParameter("quantity") == null) ? 20 : Integer.parseInt(request.getParameter("quantity")); 
      // last 20 posts user sees when open road 
      int startIndex = 0; 
      int quantity = 20; 
      List<Integer> posts = subscrQueries.getUserPosts(startIndex, quantity); 
      userPosts.put(userId, posts); 
      sess.getBasicRemote().sendObject(Helper.getSuccess()); 
      break; 
     } 

    } catch (ClassNotFoundException | SQLException | IOException | JSONException | EncodeException ex) { 
     Logger.log(Arrays.toString(ex.getStackTrace()), "error.log"); 
     Logger.log(ex.getMessage(), "error.log"); 
    } 

    } 

    private void unsubscribeUser(int userId, String context) throws JSONException, IOException, EncodeException { 

    Session sess; 

    switch (context) { 
     case CONTEXT_MESSENGER: 
     sess = usersMessenger.remove(userId); 
     sess.getBasicRemote().sendObject(Helper.getSuccess()); 
     break; 
     case CONTEXT_ROAD: 
     sess = usersRoad.remove(userId); 
     userPosts.remove(userId); 
     sess.getBasicRemote().sendObject(Helper.getSuccess()); 
     break; 
    } 
    } 

    private void sendMessageEvent(int userId, JSONObject json, Session sess) throws IOException, EncodeException, JSONException { 

    if (usersMessenger.containsKey(userId)) { 

     Session userSess = usersMessenger.get(userId); 
     userSess.getBasicRemote().sendObject(json); 

    } else { // tmp memory tbl in DB 
     SubscriptionQueries subscrQueries = new SubscriptionQueries(); 
     try { 
     subscrQueries.setSubscriptionTmp(userId, json.toString()); 
     } catch (ClassNotFoundException | SQLException ex) { 
     Logger.log(Arrays.toString(ex.getStackTrace()), "error.log"); 
     Logger.log(ex.getMessage(), "error.log"); 
     } 
    } 

    sess.getBasicRemote().sendObject(Helper.getSuccess()); 

    } 

    private void sendRoadEvents(int currentUserId, JSONObject json, Session sess) throws JSONException, IOException, EncodeException { 
    // send to all users online, that where subscribed on these (say 20 last) posts 
    // likes, comments, deletes, comment responses 
    int userId; 
    Session userSess; 

    if (json.isNull("post_id")) { 
     sess.getBasicRemote().sendObject(Helper.getErrorMessage(ERR_REQ_PARAM, 
       "Нет обязательного параметра post_id", "Нет обязательного параметра post_id")); 
     return; 
    } 

// sess.getBasicRemote().sendObject(new JSONObject().put("User Roads: ", usersRoad)); 
//  
// sess.getBasicRemote().sendObject(new JSONObject().put("Users posts: ", userPosts)); 

     for (Entry<Integer, Session> user : usersRoad.entrySet()) { 

     userId = user.getKey(); 
     userSess = user.getValue(); 

     // ensure - not equals to this user 
     if (currentUserId != userId && userPosts.containsKey(userId)) { 

      List<Integer> posts = userPosts.get(userId); 

      sess.getBasicRemote().sendObject(new JSONObject().put("Users posts: ", posts)); 

      if (!posts.isEmpty() && posts.contains(json.getInt("post_id"))) { 

      userSess.getBasicRemote().sendObject(json); 

      } 

     } 

     } 
     // success after all 
     sess.getBasicRemote().sendObject(Helper.getSuccess()); 

    } 

    private void setErrors() { 

    errSysMsg.put(ERR_REQ_PARAM, "Нет обязательного параметра"); 
    errUserMsg.put(ERR_REQ_PARAM, "Нет обязательного параметра"); 

    } 

} 

Сервер работает на 100% - проверил несколько раз HTTP запросов в других контекстах с сервлетов, которые были определены в web.xml - все стандартно и каждый запрос работает.

+0

Какой взлом? Люди, где U? Кто-нибудь помогает мне в этом. Никто не знает, как работает розеток. –

ответ

1

Ответ был умный и просто, как это должно быть:

1) расширить HttpServlet

2) Перекрыть метод doGet получить GET с Params

Он нужен для получения WebSocket рукопожатия и Upgrade заголовки.

PS, но на локальном хосте он работал нормально без HttpServlet и doGet, потому что это тот же самый компьютер и сокет-сервер, открытый на localhost (скажем, на порту 8080), не нуждается в рукопожатии по http, эта вещь трудно определить - Надеюсь, что это будет полезно для кого-то.

Смежные вопросы