안녕하세요.
java 서버를 만들어서 안드로이드 게임을 하나 운영하고 있습니다. 변변치 않은 게임이었는데 스케일이 커져서 외국에 까지 서비스를 하는데 여기서 문제가 하나 발생하더군요.
모든 클라이언트에 문자열을 보내는 메서드를 아래와 같이 짜두었습니다.
private void broadcast(String message) {
for ( int i = al.size(); --i >= 0 ;) {
ClientThread ct = al.get(i);
if (!ct.writeMsg(message)) {
ct.close();
}
}
}
|
그리고 각 클라이언트가 가지고 있는 자신에게 메세지를 쏘는 메서드는 아래와 같습니다.
private boolean writeMsg( final String msg) {
if (!socket.isConnected()) {
close();
return false ;
}
new Thread() {
public void run() {
try {
dos.writeUTF(msg);
dos.flush();
} catch (Exception e) {}
};
}.start();
return true ;
}
|
분명 각종 강의 사이트나 책에서는 위의 코드와는 달리 그냥 dos.writeUTF("메세지"); 이런식으로 하면 잘 작동하였고, 국내 서비스 때도 별 문제 없었습니다. 그런데 해외 서비스 까지 이 상태로 가니깐 writeUTF 를 할 경우, 바로 밑의 버퍼비움으로 가지 않고 계속 붙잡고 있는 겁니다. 그래서 별수 없이 스레드로 감싸고 writeUTF를 해줘서 임시로 broadcast 를 할때 지연이 없도록 처리해뒀는데 이게 스레드가 되니깐 외국분들의 접속 끊김 현상이 심하다는 컴플레인과 별점1개 도배가 되더군요.
하지만 스레드 처리를 하지 않고 writeUTF 를 할 경우에는 broadcast 를 한번 하는데 10명의 유저가 접속해 있을경우 15초 정도나 걸리더군요. -_-; 대신 접속 끊김은 발생하지 않는다고 합니다.
왜 이런 문제가 발생하는 건가요? 너무 답답합니다. ㅠ_ㅠ