2017-12-20 8 views
-2

とても小さいメッセージングアプリを作っています。私は、サーバからのメッセージを聞く1つの非同期タスクと、サーバにメッセージを送り、メッセージをエコーバックする別の非同期タスクを持っています。何らかの理由で、私は同時にサーバーを送受信できません。これは何が起こるかの順序です:アンドロイド - 同じIPとポートに2つのソケットを実行するにはどうすればいいですか?

1.ユーザーAがメッセージを入力して送信をクリックします。何も起こりません。 2.ユーザーB(リスニング非同期タスクをオフにしている)を送信し、メッセージを送信します。 その後、userAのメッセージがユーザーBに戻ってきます。なぜ私はユーザーAが同時にメッセージを送受信できないのか分かりません。ここに私の2つの非同期タスクがあります。

private class CommunicateWithServerAsyncTask extends AsyncTask<Void,Void,Void> 
    { 
     private String jsonReply = ""; 
     private String jsonOutputToServer = ""; 

     public CommunicateWithServerAsyncTask(String jsonMessage) 
     { 
      this.jsonOutputToServer = jsonMessage; 
     } 

     @Override 
     protected Void doInBackground(Void... params) 
     { 
      Log.d(SOCKET_TESTING_TAG,"break 1"); 
      try 
      { 
       Log.d(SOCKET_TESTING_TAG,"break 2"); 
       Socket socket = new Socket("ip",portNumber); 
       PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); 
       BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       printWriter.println(jsonOutputToServer); 
       printWriter.flush(); 
       jsonReply = bufferedReader.readLine(); 
       Log.d(SOCKET_TESTING_TAG,"break 2"); 
       if(jsonReply != null && !jsonReply.equals("")) 
       { 
        Log.d(SOCKET_TESTING_TAG,"break 3"); 
        Log.d(SOCKET_TESTING_TAG,"my message is " + jsonReply); 
       } 
       else 
       { 
        Log.d(SOCKET_TESTING_TAG,"break 4"); 
        Log.d(SOCKET_TESTING_TAG,"no message yet"); 
       } 
       printWriter.close(); 
       bufferedReader.close(); 
       socket.close(); 

      } 
      catch (IOException e) 
      { 
       Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage()); 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     public void onPostExecute(Void var) 
     { 
      displayMessageFromServer(jsonReply,false); 
     } 
    } 

第二非同期タスク

private class ListenForMessagesAsyncTask extends AsyncTask<Void,Void,Void> 
{ 
    private String jsonReply = ""; 
    //private BufferedReader bufferedReader; 

    @Override 
    protected Void doInBackground(Void... params) 
    { 
     Log.d(SOCKET_TESTING_TAG,"break A"); 
     try 
     { 
      Socket socket = new Socket("52.91.109.76",1234);; 
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      while (isListeningForMessages) 
      { 
       Log.d(SOCKET_TESTING_TAG,"break D"); 
       Log.d(SOCKET_TESTING_TAG,"my buffer reader value is " + String.valueOf(bufferedReader.ready())); 
       if(bufferedReader.ready()) 
       { 
        Log.d(SOCKET_TESTING_TAG,"break E"); 
        jsonReply = (String) bufferedReader.readLine(); 
        Log.d(SOCKET_TESTING_TAG,"break F"); 
        isListeningForMessages = false;//we have a reply, close the while loop and Async Task. 
        Log.d(SOCKET_TESTING_TAG,"my listening message is " + jsonReply); 
       } 
      } 
      bufferedReader.close(); 
      socket.close(); 

     } 
     catch (IOException e) 
     { 
      Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage()); 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    public void onPostExecute(Void var) 
    { 
     displayMessageFromServer(jsonReply,true); 
    } 

} 
+0

私は 'のreadLine(https://stackoverflow.com/q/47899231/207421というあなたの[前の質問](https://stackoverflow.com/q/47899231/207421)に私の答えにあなたに言いました) 'nullを返すことは、 'まだメッセージがありません'という意味ではなく、何を意味しているのでしょうか。 – EJP

+0

したがって、非同期タスクは、2つのデバイス上の異なるクライアントアプリケーションで使用されます。なぜあなたはあなたに言ったのですか? – greenapps

+0

異なるクライアントによって受信されるメッセージは、サーバーが送信する内容と送信者によって異なります。あなたはあなたのサーバーについて何も言わなかった。あなたはあなたのサーバーコードを投稿しませんでした。だから何が起こるべきかを私たちはどのように知るべきですか – greenapps

答えて

-1

私は、サーバーにメッセージを送信するために、ユーザ1のための非常に簡単な方法を望んでいました。サーバーは応答をエコーし​​、そのメッセージをユーザー2に送信します。

サーバーにメッセージを送信してエコー応答を取得するには、CommunicateWithServerAsyncTaskを参照してください。ここでは、ソケットオブジェクトを使用してサーバーに接続し、Typewriterクラスを使用してサーバーにメッセージを送信できます。次に、バッファーリーダークラスを使用して、サーバーからのメッセージ応答を待ち受けます。

ユーザー2がサーバーからユーザー1のメッセージを受信するためには、サーバーからの応答を継続的にリスンする必要があります。そのため、CommunicateWithServerAsyncTaskを実装しました。最初のAsyncTaskと同じコンセプトですが、whileループではsocketとbufferreaderオブジェクトが必要です。

これは、ソケット接続の基本を理解しようとしている人に役立ちます。この回答では、私はすでにあなたがどこかで実行されていると仮定し、クライアント側で助けが必要と仮定します。

public class MainActivity extends AppCompatActivity 
{ 
    private Button b_send; 
    private EditText et_message; 
    private TextView tv_response, userB_TV; 
    private boolean isSendButtonPressed; 
    private final String SOCKET_TESTING_TAG = "SOCKET_TESTING_TAG"; 
    private static boolean isListeningForMessages = true; 
    private Socket socket; 
    private BufferedReader bufferedReader; 
    private ListenForMessagesAsyncTask listenForMessagesAsyncTask; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     bindActivity(); 

    } 
    private void bindActivity() 
    { 
     b_send = (Button) findViewById(R.id.b_send); 
     et_message = (EditText) findViewById(R.id.et_message); 
     tv_response = (TextView) findViewById(R.id.tv_response); 
     userB_TV = (TextView) findViewById(R.id.tv_history); 
     tv_response.setMovementMethod(new ScrollingMovementMethod()); 
     b_send.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) 
      { 
       if(!et_message.getText().toString().isEmpty() && !isSendButtonPressed)//I do a couple checks to make sure the user doesn't send an empty string and that they don't keep tapping the button 
       { 
        isSendButtonPressed = true; 
        listenForMessagesAsyncTask.cancel(true); 
        try 
        { 
         socket.close(); 
         bufferedReader.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        CommunicateWithServerAsyncTask communicateWithServerAsyncTask = new CommunicateWithServerAsyncTask(convertMessageToJson(et_message.getText().toString())); 
        communicateWithServerAsyncTask.execute();//Note: you could do new CommunicateWithServerAsyncTask.execute(""); However, im just used to initiating async tasks this way. 

       } 
      } 
     }); 
     listenForMessagesAsyncTask = new ListenForMessagesAsyncTask(); 
     listenForMessagesAsyncTask.execute(); 
    } 

    private class CommunicateWithServerAsyncTask extends AsyncTask<Void,Void,Void> 
    { 
     private String jsonReply = ""; 
     private String jsonOutputToServer = ""; 

     public CommunicateWithServerAsyncTask(String jsonMessage) 
     { 
      this.jsonOutputToServer = jsonMessage; 
     } 

     @Override 
     protected Void doInBackground(Void... params) 
     { 
      try 
      { 
       Socket socket = new Socket("ip",portNumber); 
       PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); 
       BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       printWriter.println(jsonOutputToServer); 
       printWriter.flush(); 
       jsonReply = bufferedReader.readLine(); 
       if(jsonReply != null && !jsonReply.equals("")) 
       { 
        Log.d(SOCKET_TESTING_TAG,"my message is " + jsonReply); 
       } 
       else 
       { 
        Log.d(SOCKET_TESTING_TAG,"no message yet"); 
       } 
       printWriter.close(); 
       bufferedReader.close(); 
       socket.close(); 

      } 
      catch (IOException e) 
      { 
       Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage()); 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     public void onPostExecute(Void var) 
     { 
      displayMessageFromServer(jsonReply,false); 
     } 
    } 

    private class ListenForMessagesAsyncTask extends AsyncTask<Void,Void,Void> 
    { 
     private String jsonReply = ""; 
     //private BufferedReader bufferedReader; 

     @Override 
     protected Void doInBackground(Void... params) 
     { 
      try 
      { 
       socket = new Socket("ip",portNumber);; 
       bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       while (isListeningForMessages) 
       { 
        //Log.d(SOCKET_TESTING_TAG,"break D"); 
        if(bufferedReader.ready()) 
        { 
         Log.d(SOCKET_TESTING_TAG,"break E"); 
         jsonReply = (String) bufferedReader.readLine(); 
         Log.d(SOCKET_TESTING_TAG,"break F"); 
         isListeningForMessages = false;//we have a reply, close the while loop and Async Task. 
         Log.d(SOCKET_TESTING_TAG,"my listening message is " + jsonReply); 
        } 
       } 
       bufferedReader.close(); 
       socket.close(); 

      } 
      catch (IOException e) 
      { 
       Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage()); 
       e.printStackTrace(); 
      } 

      return null; 
     } 

     @Override 
     public void onPostExecute(Void var) 
     { 
      displayMessageFromServer(jsonReply,true); 
     } 

    } 
+0

これは、何が違うのか、それがなぜ優れているのかを述べない限り、誰にもあまり役に立ちません。 – EJP

+0

@EJP大丈夫です – TheQ

関連する問題