마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

소켓 데이터전송/소켓종료 관련 문의드립니다.

0 추천

웹소켓 통신을 하고있습니다.

https://github.com/pavelbucek/tyrus-client-android-test/blob/master/src/main/java/com/example/AndroidClientTest/MyActivity.java

위 소스를 사용하여 만들었습니다.

 

public class MainActivity extends BaseActivity {
    ThreadTest mThreadTest;

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

        mThreadTest = new ThreadTest(getApplicationContext());
    }
  ....

    public void click(View v) {
        switch (v.getId()) {
            case R.id.btn1:
                mThreadTest.socketConnect();
                break;

            case R.id.btn2:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mThreadTest.sendMessage("hihi~~~");
                    }
                }).start();
                break;

            case R.id.btn3:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mThreadTest.wsClose();
                    }
                }).start();
                break;
        }
    }

 

public class ThreadTest   {
    private Session session_ = null;
    private Context mContext;

    public ThreadTest(Context context){
        this.mContext = context;
    }

synchronized public void socketConnect() {

        final AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... voids) {
                try {
                    final ClientManager client = ClientManager.createClient();

                    Log.i(TAG, "### 1 AsyncTask.doInBackground");
                    client.connectToServer(new Endpoint() {
                        @Override
                        public void onOpen(Session session, EndpointConfig EndpointConfig) {
                            session_ = session;
                            try {
                                session.addMessageHandler(new MessageHandler.Whole<String>() {
                                    @Override
                                    public void onMessage(String message) {
                                        Log.i(TAG, "### 3 Tyrus Client onMessage: " + message);
                                    }
                                });

                                Log.i(TAG, "### 2 Tyrus Client onOpen");
//                                session.getBasicRemote().sendText("Do or do not, there is no try.");
                            } catch (Exception e) {
                                // do nothing
                            }
                        }

                        @Override
                        public void onClose(Session session, CloseReason closeReason) {
                            super.onClose(session, closeReason);
                            Log.i(TAG, "onClose :: session = "+(session == null ? "false":"true"));
                        }
                    }, ClientEndpointConfig.Builder.create().build(), URI.create("ws://echo.websocket.org"));

                } catch (DeploymentException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        };

        asyncTask.execute();
    }

    synchronized public boolean isConnected(){
        return session_ == null ? false : true;
    }

    public void sendMessage(String a) {
        if(isConnected()) {
            try {
                session_.getBasicRemote().sendText(a);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void wsClose(){
        if(isConnected()) {
            try {
                session_.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

서버로 메시지를 날릴때와 종료할때 android.os.NetworkOnMainThreadException 에러가 나서

new Thread(...) 로 처리를 해줬습니다.

궁금한 점은 

1. 메시지를 보낼때마다 혹은 소켓 종료시에  저렇게 단일Thread (new Thread.. )로 계속 띄워도 되는건가요?

2. 소켓 종료시 mThreadTest.wsClose(); 처리만 하고 onDestory 나 소스상에서 별다른 조치를 안해줘도 되는건가요??

더 나은방법이 있을거 같아서 문의드립니다. ㅠ

 

익명사용자 님이 2016년 5월 11일 질문

1개의 답변

0 추천
 
채택된 답변
메인(UI) 스레드에서 네트웍이나 IO작업을 하는 경우에 에러가 발생하고요..

소켓을 재 사용하는 방법으로는 Application 클래스에서 소켓을 유지하고 사용할 때마다 소켓 객체를 가져와서 사용하시면 될 것 같습니다.

이렇게 처리하시면 소켓 종료는 굳이 Activity나 Fragment에서 처리하지 않으셔도 됩니다.
mcsong (44,040 포인트) 님이 2016년 5월 12일 답변
답변 감사드립니다~ 혹 Application 클래스에서 소켓을 유지하고 사용할 때마다 소켓 객체를 가져와서 사용한다는게,,,, 위 소스에서 session을 Application에서 따로 저장하라는 말씀이신가요?
넵.. 그렇게 처리하시면 될 것 같네요..
아... 그렇게 처리를 해봤는데도 어쨋건 서버에 메시지를 보낼때마다 메인 Activity에서 new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mThreadTest.sendMessage("hihi~~~");
                    }
                }).start();  이런식으로 구현을 해야 에러가 안나서요,,, 액션이 일어날때마다 new Thread 를 계속 띄워서 처리해도 성능상 문제가 없는지요?
메인 스레드에서 I/O를 하면 화면이 멈추기 때문에 OS 차원에서 막고 있습니다. 그래서 매번 스레드를 생성해야 합니다. 앱에서 어느 정도로 사용하는지 모르겠지만, 아마도 크게 문제가 안 될 것 같은데.. 제가 개발하시는 앱의 도메인을 모르니 명확하지는 않겠네요..
아 ,, 감사합니다 ^^ 저렇게 처리하는게 혹시 무식한 방법일까바 문의드렸는데 친절한 답변 감사합니다. 즐거운 오후 되세요~
...