2014-02-26 5 views
1

Я пишу приложение для Android-чата, и прямо сейчас у меня возникла проблема с организацией запроса-запроса сервера.Формат сообщений и алгоритм запроса-ответа

В моих сообщениях чата представлены в формате JSON с полем TransactionId, который уникален для определенного набора пары запроса-ответа. Например, запрос, чтобы установить сообщение прочитанным:

{Type : "READ_MESSAGE", Sender : "Alice", Recievier : "server", Body : "123456", 
    TransactionId : "550e8400-e29b-41d4-a716-446655440000"} 

и соответствующего ответа:

{Type : "READ_MESSAGE", Sender : "server", Recievier : "Alice", Body : "1", TransactionId : "550e8400-e29b-41d4-a716-446655440000"} 

Id здесь используется для identificate, для которого запрос ответ пришел, например, в случае, когда я ожидая 5 различных ответов READ_MESSAGE.

Но вот в чем проблема. Мой клиент android состоит из одного потока, который принимает входящие сообщения и отдельный поток на исходящее сообщение. Поэтому я не могу ждать ответа в ветке сообщений исходящего, и сейчас я использую этот код:

private void sendJSON(final String JSON) { 
    Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      runnable.out.println(JSON); 
      JSONMessage json = new JSONMessage(JSON); 
      //After 5 seconds we should check: was message sent successfully? 
      try { 
       Thread.sleep(5000L); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      sendMessageToUI(json.getTransactionId(), CHECK_IF_SENT); 
     } 

    }); 
    t.start(); 
} 

и

private void proceeIncoming() { 
    while (!SocketClient.this.toExit) { 
     try { 
      String str = SocketClient.this.in.readLine(); 
      if (str != null) { 
       JSONMessage recievedMsg = new JSONMessage(str); 
       switch (recievedMsg.getType()) { 
        case MESSAGE: 
         SocketService.this.sendJSON(new JSONMessage.Builder(MessageType.RECEIVED_MESSAGE, 
           Global.getUserPref().getString("Username", ""), 
           "server", 
           recievedMsg.getTransactionId()).build().toString()); 
         SocketService.this.sendMessageToUI(str, MSG_SEND_JSON_MESSAGE); 
         History.writeJSON(str); 
         break; 
        case RECEIVED_MESSAGE: 
         SocketService.this.sendMessageToUI(recievedMsg.getTransactionId(), SUCCESSFULLY_SENT_MESSAGE); 
         break; 
        case READ_MESSAGE: 
         SocketService.this.sendMessageToUI(recievedMsg.getTransactionId(), READ_MESSAGE); 
         break; 
        default: 
         break; 
       } 
      } 
     } catch (IOException e) { 
      Log.i(Global.LOG_TAG, "IOException"); 
      reconnect(1000); 
     } 
    } 
    try { 
     SocketClient.this.in.close(); 
     SocketClient.this.out.close(); 
     SocketClient.this.socket.close(); 
    } catch (IOException e) { 
     Log.e(Global.LOG_TAG, "Error closing client"); 
    } 

} 

Затем активность в интерфейсе обрабатывает сообщение. Это работает, но в целом для меня это похоже на клочок.

Не только это довольно запутанно, но я также должен хранить TransactionId в своем классе Message, чтобы иметь возможность искать сообщения с помощью этого идентификатора, что просто неправильно, и потому что этот идентификатор создан клиентом, я не могу убедитесь в его уникальности, поэтому возможно, что запрос базы данных по этому идентификатору даст мне несколько результатов.

Есть ли другой способ сделать это?

ответ

0

Похоже, что нет хорошего решения, поэтому я решил открыть новое соединение для каждого запроса и послушать ответ только для этого запроса.

0

Я хотел бы предложить с 3 темы:

  1. один для главного приложения (UI)
  2. One для отправки сообщений. Ваше приложение должно помещать сообщения в синхронизированную очередь. Поток, который отправляет сообщения, считывает из этой очереди и блокирует, когда в очереди нет ничего. Кажется, что у вас переполнено 1 сообщение (разговор?).
  3. Один для чтения (получения) сообщений и отправки событий в пользовательский интерфейс при появлении нового сообщения.

Что касается уникальности Вашего ID, это идентификатор только для сообщения (странно), беседу, чат ...

Клиент должен отправить сообщение с ID не на сервер, говоря эй, я хочу отправить сообщение этому человеку/комнате. Если вам нужен идентификатор, тогда сервер может генерировать его во время его обработки, а затем клиенты получат сообщение с идентификатором. Не уверен, что они с ней сделают.

Сообщение должно иметь поле «to/destination» (которое у него уже есть), которое должно быть достаточным для объединения сообщений в цепочку.

+0

Основная проблема с этим подходом (или я не совсем понял) - это что делать, когда я жду нескольких ответов за раз?Например, представьте себе, что я отправил 5 сообщений, и теперь я жду 5 ответов от сервера, что они были получены и какие у них теперь есть (для этого мне нужны). И давайте предположим, что 2 из них не могут быть отправлены. Итак, как я знаю, какие сообщения действительно были отправлены, а какие нет, если в данный момент у меня нет идентификаторов на стороне клиента? – sadolit

+0

ваши сообщения чтения потока просто читают любое сообщение. Я не уверен, как вы можете заранее знать, сколько сообщений вы собираетесь получать, если только вы не можете получить сообщение, если вы отправили его?!? Если вам действительно нужен идентификатор, вы можете иметь во время инициализации сервер назначить уникальный идентификатор каждому клиенту, и поэтому клиент использует этот идентификатор в качестве первой части идентификаторов сообщений MSN, которые он создает, чтобы гарантировать, что 2-й клиент не может сгенерировать тот же идентификатор , – XSen

+0

Думаю, я не прояснил ситуацию. Взгляните на этот пример: [link] (http://vk.com/pages?oid=-17680044&p=messages.markAsRead) Как вы видите, ответ на запрос не содержит никаких следов идентификатора сообщений или таких , Но что, если моему приложению нужно проследить результат такой операции? Откуда я знаю, какое сообщение было прочитано? Возможно ли это? Или для этого примера: [link] (http://vk.com/pages?oid=-17680044&p=messages.send) Если я отправлю несколько сообщений, я получу несколько ответов, а затем, откуда я точно знаю, что ids были присвоены сообщениям? – sadolit

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