MapleStory Finger Point

๐Ÿ”˜ ํ”„๋กœ์ ํŠธ

[Project] WebSocket ์›น ์†Œ์ผ“ ๊ตฌํ˜„ (์‹ค์‹œ๊ฐ„ ์œ„์น˜ ์ •๋ณด)

HYEJU01 2025. 2. 12. 02:43

 

 

WebSocket ์„ ์จ๋ณด์ž

 

ํ”„๋กœ์ ํŠธ์—์„œ ์‹ค์‹œ๊ฐ„ ์œ„์น˜์ •๋ณด๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

 


โœ… ์›น์†Œ์ผ“์— ์ ‘์†ํ•˜๋ฉด ์ ‘์†ํ•œ ์œ ์ € ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

โœ… ์‚ฌ์šฉ์ž ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋ ๋•Œ๋งˆ๋‹ค ์†Œ์ผ“์œผ๋กœ ์œ„์น˜์ •๋ณด๋ฅผ ๋ณด๋‚ด๋ฉด, ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ํ•ด๋‹น ์‚ฌ์šฉ์ž์˜ ์œ„์น˜์ •๋ณด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

โœ… ์ด๋•Œ, ์†Œ์ผ“์œผ๋กœ userId ๋ฅผ ๋ณด๋‚ด๋ฉด ์ž๋™์œผ๋กœ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๋ฐ›์•„์˜จ ์œ„์น˜(์œ„๋„,๊ฒฝ๋„)๋„ ํ•จ๊ป˜ ํฌํ•จํ•ด์„œ ๋‹ค๋ฅธ ์†Œ์ผ“ ์œ ์ €๋“ค์—๊ฒŒ ๋ณด๋‚ธ๋‹ค.

 

 

 

์‹ค์‹œ๊ฐ„ ์œ„์น˜์ •๋ณด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ณ„์†ํ•ด์„œ ์œ„์น˜๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•œ๋ฐ...

์ด๊ฑธ HTTP ๋กœ ๊ตฌํ˜„ ํ•˜๊ธฐ์—๋Š” ๋งค์šฐ ํž˜๋“ค๋‹ค. HTTP ์˜ ํŠน์ง• ๋•Œ๋ฌธ์ธ๋ฐ, ๋‹จ๋ฐฉํ–ฅํ†ต์‹ ์ธ ์  (์š”์ฒญ์„ ํ•ด์•ผ๋งŒ ์‘๋‹ต์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Œ)

์š”์ฒญ์„ ํ• ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กญ๊ฒŒ ์—ฐ๊ฒฐํ•ด์•ผํ•˜๋Š” ๋“ฑ ๋งŽ์€ ๋‹จ์ ์ด ์žˆ๋‹ค. ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ’€๋ง์ด๋ผ๋Š” ๊ฐœ๋…์ด ๋‚˜์˜ค๊ธด ํ•˜๋Š”๋ฐ ์ด๊ฑด ์ฃผ๊ธฐ์ ์œผ๋กœ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋„ˆ๋ฌด ์‹ฌํ•˜๊ณ , ์‹ค์‹œ๊ฐ„ ์„ฑ๋„ ๋‚ฎ๋‹ค.

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” WebSocket ์„ ์“ด๋‹ค. ์›น์†Œ์ผ“์€ ํ•œ๋ฒˆ ์—ฐ๊ฒฐํ•˜๋ฉด ๊ณ„์†ํ•ด์„œ ์—ฐ๊ฒฐ์ด ์œ ์ง€๋˜๋ฉฐ, ์–‘๋ฐฉํ–ฅ ํ†ต์‹ (์ „์ด์ค‘ ํ†ต์‹ )์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋˜ํ•œ ์š”์ฒญ์ด ์—†๋”๋ผ๋„ ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ๋กœ ์‘๋‹ต์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ณ  ์˜ค๋ฒ„ํ—ค๋“œ๋„ ์ ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์‹œ๊ฐ„์ด ํ•„์š”ํ•œ ์‹œ์Šคํ…œ์—์„œ๋Š” ์›น์†Œ์ผ“์„ ์“ฐ๊ฒŒ๋œ๋‹ค ! ๐Ÿ˜€

 

 

 

WebSocket ์›น ์†Œ์ผ“ ๊ฐœ๋…

HTTPํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ(Request) โ†’ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ต(Response)์‘๋‹ต ํ›„ ์—ฐ๊ฒฐ์ด ๋‹ซํž˜ (Stateless)์ƒˆ๋กœ์šด ์š”์ฒญ๋งˆ๋‹ค ๋‹ค์‹œ ์—ฐ๊ฒฐ ํ•„์š”์ฃผ๋กœ ๋‹จ๋ฐฉํ–ฅ ํ†ต์‹  (ํด๋ผ์ด์–ธํŠธ โ†’ ์„œ๋ฒ„)๋ฐ์ดํ„ฐ๋ฅผ ํ—ค๋”์— ํฌํ•จ์‹œ์ผœ์„œ ์ „๋‹ฌํ•จ ํด

hyejux.tistory.com

 


 

 

 

build gradle ์ถ”๊ฐ€ 

 

 

 

 


 

config ์„ค์ • ๊ตฌํ˜„

 

 

์›น์†Œ์ผ“์„ ์“ฐ๊ธฐ ์œ„ํ•ด์„œ๋Š” Config (์›น ์†Œ์ผ“ ์„ค์ •ํŒŒ์ผ) ๊ณผ Handler(์†Œ์ผ“ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ) ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ค˜์•ผํ•œ๋‹ค.

 

 

 

config.java

 

์›น ์†Œ์ผ“ ํ™œ์„ฑํ™”, ์—”๋“œํฌ์ธํŠธ ์„ค์ •

 

WebSocketConfigurer ๊ตฌํ˜„

@EnableWebSocket ์›น ์†Œ์ผ“ ํ™œ์„ฑํ™” ์–ด๋…ธํ…Œ์ด์…˜

package com.sanchat.api.config;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration // ์Šคํ”„๋ง์„ค์ •ํŒŒ์ผ
@EnableWebSocket // ์†Œ์ผ“ ์‚ฌ์šฉ
@RequiredArgsConstructor
public class MapWebSocketConfig implements WebSocketConfigurer {
private final MapWebSocketHandler mapWebSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(mapWebSocketHandler, "/tracking") // ์š”์ฒญ ํ—ˆ์šฉ ๊ฒฝ๋กœ
.setAllowedOrigins("*"); // ์„œ๋ฒ„๊ฐ€ ๋‹ฌ๋ผ๋„ ํ—ˆ์šฉ Cors
}
}

 

 


 

Handler ํ•ธ๋“ค๋Ÿฌ ๊ตฌํ˜„

 

 

Handler.java

 

๋”๋ณด๊ธฐ
package com.sanchat.api.config;
import ch.qos.logback.core.net.SyslogOutputStream;
import ch.qos.logback.core.net.server.Client;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.sanchat.api.dto.DogDTO;
import com.sanchat.api.dto.UserDTO;
import com.sanchat.api.dto.UserMDTO;
import com.sanchat.api.service.UserService;
import lombok.Builder;
import org.apache.catalina.User;
import org.apache.tomcat.util.json.JSONParser;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Component // bean ์œผ๋กœ ๋“ฑ๋ก
public class MapWebSocketHandler extends TextWebSocketHandler {
@Autowired
UserService userService;
/**
* ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” MAP (์ ‘์†ํ•œ ์‚ฌ์šฉ์ž ๋ฆฌ์ŠคํŠธ)
* userID , UserMDTO ์ €์žฅ
*/
Map<String, UserMDTO> userList = new HashMap<>();
/**
* ํ˜„์žฌ ์ ‘์†ํ•œ ํด๋ผ์ด์–ธํŠธ (WebSocket ์„ธ์…˜) ๋ชฉ๋ก ์ €์žฅ
*/
private static final ConcurrentHashMap<String, WebSocketSession> CLIENTS =
new ConcurrentHashMap<String, WebSocketSession>();
/**
* ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›น์†Œ์ผ“ ์—ฐ๊ฒฐ์— ์„ฑ๊ณต ์‹œ ํ˜ธ์ถœ
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
CLIENTS.put(session.getId(), session);
// ํ˜„์žฌ ์ ‘์† ์ค‘์ธ ์‚ฌ์šฉ์ž ๋ชฉ๋ก์„ JSON์œผ๋กœ ๋ณ€ํ™˜
JSONObject response = new JSONObject();
response.put("type", "USER_LIST"); // ๋ฉ”์‹œ์ง€ ํƒ€์ž…์„ USER_LIST๋กœ ์„ค์ •
List<JSONObject> userArray = new ArrayList<>();
for (UserMDTO user : userList.values()) {
System.out.println(user.getUserId() + session.getId());
JSONObject userJson = new JSONObject();
userJson.put("userId", user.getUserId());
userJson.put("userName", user.getUserName());
userJson.put("photo", user.getPhoto());
userJson.put("userIntro", user.getUserIntro());
userJson.put("latitude", user.getLatitude());
userJson.put("longitude", user.getLongitude());
userJson.put("dogList", user.getDogList());
userArray.add(userJson);
}
response.put("users", userArray);
// ์ƒˆ๋กœ ์ ‘์†ํ•œ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ˜„์žฌ ์ ‘์† ์ค‘์ธ ์‚ฌ์šฉ์ž ๋ชฉ๋ก ์ „์†ก
session.sendMessage(new TextMessage(response.toString()));
}
/**
* ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ผ ๋•Œ ํ˜ธ์ถœ
* (์‚ฌ์šฉ์ž ์œ„์น˜ ์ €์žฅ, ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ์— ๋ฉ”์„ธ์ง€ ์ „๋‹ฌ)
*/
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
String id = session.getId(); //๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ ์›น์†Œ์ผ“ ์„ธ์…˜ ์•„์ด๋””
// ๋ฐ›์€ ๋ฉ”์‹œ์ง€๋ฅผ JSON ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜
JSONObject jsonObject = new JSONObject(String.valueOf(message.getPayload()));
// ํ•„์š”ํ•œ ์ •๋ณด ์ถ”์ถœ
String userId = jsonObject.getString("userId");
String latitude = jsonObject.getString("latitude");
String longitude = jsonObject.getString("longitude");
String type = jsonObject.getString("type"); // LOCATION, CLOSE , USER_LIST..
UserDTO userDTO = userService.getUser(userId); // ์‚ฌ์šฉ์ž ์ •๋ณด ์กฐํšŒํ•ด์˜ค๊ธฐ
// ์‚ฌ์šฉ์ž ์œ„์น˜ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” UserDTO ๊ฐ์ฒด ์ƒ์„ฑ
UserMDTO userMDTO = new UserMDTO();
userMDTO.setUserId(userId);
userMDTO.setPhoto(userDTO.getPhoto().getPhotoUrl());
userMDTO.setUserName(userDTO.getUserName());
userMDTO.setUserIntro(userDTO.getUserIntro());
List<String> dogList = new ArrayList<>();
for(DogDTO dDto : userDTO.getDogList()){
dogList.add(dDto.getDogName());
}
userMDTO.setDogList(dogList);
// ์œ„๋„, ๊ฒฝ๋„
userMDTO.setLatitude(Double.parseDouble(latitude));
userMDTO.setLongitude(Double.parseDouble(longitude));
// ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ userList(Map) ์— ์ €์žฅ
userList.put(session.getId(), userMDTO);
System.out.println(id +" :: " + userId + " ๋‹˜์˜ ์œ„์น˜ ์ •๋ณด | " +latitude + " | " +longitude + type );
// ๋ฉ”์„ธ์ง€ type = "CLOSE" ๋ฉด ์—ฐ๊ฒฐ ์ข…๋ฃŒ, ์„ธ์…˜ ์ œ๊ฑฐ
switch(type) {
case "CLOSE" :
CLIENTS.remove(session.getId());
userList.remove(session.getId());
break;
default:
break;
}
// ํ˜„์ œ ์ ‘์† ์ค‘์ธ ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ (์ž์‹ ์€ ์ œ์™ธ)
CLIENTS.entrySet().forEach(arg -> {
if(!arg.getKey().equals(id)) { // ์ž์‹ ์ด ์•„๋‹ˆ๋ฉด ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
try {
// ์œ„์น˜ ์ •๋ณด๋„ ํฌํ•จํ•˜์—ฌ ์ „๋‹ฌ
JSONObject response = new JSONObject();
response.put("type", "LOCATION"); // ๋ฉ”์‹œ์ง€ ํƒ€์ž…์€ LOCATION
response.put("userId", userMDTO.getUserId());
response.put("userName", userMDTO.getUserName());
response.put("latitude", userMDTO.getLatitude());
response.put("longitude", userMDTO.getLongitude());
response.put("photo", userMDTO.getPhoto());
response.put("dogList", userMDTO.getDogList());
// ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฉ”์‹œ์ง€ ์ „์†ก
arg.getValue().sendMessage(new TextMessage(response.toString()));
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
});
}
/**
* WebSocket ์ „์†ก ์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ํ˜ธ์ถœ๋จ
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
}
/**
* ํด๋ผ์ด์–ธํŠธ์™€์˜ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋  ๋•Œ ํ˜ธ์ถœ๋จ
* - ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ๋ฅผ CLIENTS ๋ชฉ๋ก์—์„œ ์ œ๊ฑฐ
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
CLIENTS.remove(session.getId());
userList.remove(session.getId());
}
/**
* ๋ถ€๋ถ„ ๋ฉ”์‹œ์ง€๋ฅผ ์ง€์›ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ (ํ˜„์žฌ๋Š” false)
*/
@Override
public boolean supportsPartialMessages() {
return false;
}
}



 

 

 

 

 TextWebSocketHandler : ํ…์ŠคํŠธ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์›น์†Œ์ผ“ ํ•ธ๋“ค๋Ÿฌ 

 

  • afterConnectionEstablished() : ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›น์†Œ์ผ“์— ์—ฐ๊ฒฐ๋  ๋•Œ ์‹คํ–‰
  • handleTextMessage() : ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ๋•Œ ์‹คํ–‰
  • afterConnectionClosed() : ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฐ๊ฒฐ์„ ์ข…๋ฃŒํ•  ๋•Œ ์‹คํ–‰

 

์œ„ ์„ธ๊ฐœ์˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ์ฃผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

 

 

/**
* ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” MAP (์ ‘์†ํ•œ ์‚ฌ์šฉ์ž ๋ฆฌ์ŠคํŠธ)
* userID , UserMDTO ์ €์žฅ
*/
Map<String, UserMDTO> userList = new HashMap<>();

 

Map ์„ ์ด์šฉํ•ด์„œ ์ ‘์†ํ•œ ์œ ์ €๋“ค์˜ ์ตœ์‹  ์œ„์น˜๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.  key ๋Š” sesstionId 

 

 

/**
* ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›น์†Œ์ผ“ ์—ฐ๊ฒฐ์— ์„ฑ๊ณต ์‹œ ํ˜ธ์ถœ
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
CLIENTS.put(session.getId(), session); // ํด๋ผ์ด์–ธํŠธ ์„ธ์…˜์„ ์ €์žฅ
// ํ˜„์žฌ ์ ‘์† ์ค‘์ธ ์‚ฌ์šฉ์ž ๋ชฉ๋ก์„ JSON์œผ๋กœ ๋ณ€ํ™˜
JSONObject response = new JSONObject();
response.put("type", "USER_LIST"); // ๋ฉ”์‹œ์ง€ ํƒ€์ž…์„ USER_LIST๋กœ ์„ค์ •
List<JSONObject> userArray = new ArrayList<>();
for (UserMDTO user : userList.values()) {
System.out.println(user.getUserId() + session.getId());
JSONObject userJson = new JSONObject();
userJson.put("userId", user.getUserId());
userJson.put("userName", user.getUserName());
userJson.put("photo", user.getPhoto());
userJson.put("userIntro", user.getUserIntro());
userJson.put("latitude", user.getLatitude());
userJson.put("longitude", user.getLongitude());
userJson.put("dogList", user.getDogList());
userArray.add(userJson);
}
response.put("users", userArray);
// ์ƒˆ๋กœ ์ ‘์†ํ•œ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ˜„์žฌ ์ ‘์† ์ค‘์ธ ์‚ฌ์šฉ์ž ๋ชฉ๋ก ์ „์†ก
session.sendMessage(new TextMessage(response.toString()));
}

 

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›น ์†Œ์ผ“ ์—ฐ๊ฒฐ์— ์„ฑ๊ณตํ•˜๋ฉด, ์†Œ์ผ“์— ์ ‘์† ํ•ด ์žˆ๋Š” ์œ ์ € ๋ฆฌ์ŠคํŠธ๋ฅผ JSON ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „์†กํ•œ๋‹ค.

 

 

String id = session.getId(); //๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ ์›น์†Œ์ผ“ ์„ธ์…˜ ์•„์ด๋””
// ๋ฐ›์€ ๋ฉ”์‹œ์ง€๋ฅผ JSON ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜
JSONObject jsonObject = new JSONObject(String.valueOf(message.getPayload()));
// ํ•„์š”ํ•œ ์ •๋ณด ์ถ”์ถœ
String userId = jsonObject.getString("userId");
String latitude = jsonObject.getString("latitude");
String longitude = jsonObject.getString("longitude");
String type = jsonObject.getString("type"); // LOCATION, CLOSE , USER_LIST..
UserDTO userDTO = userService.getUser(userId); // ์‚ฌ์šฉ์ž ์ •๋ณด ์กฐํšŒํ•ด์˜ค๊ธฐ
// ์‚ฌ์šฉ์ž ์œ„์น˜ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” UserDTO ๊ฐ์ฒด ์ƒ์„ฑ
UserMDTO userMDTO = new UserMDTO();
userMDTO.setUserId(userId);
userMDTO.setPhoto(userDTO.getPhoto().getPhotoUrl());
userMDTO.setUserName(userDTO.getUserName());
userMDTO.setUserIntro(userDTO.getUserIntro());
List<String> dogList = new ArrayList<>();
for(DogDTO dDto : userDTO.getDogList()){
dogList.add(dDto.getDogName());
}
userMDTO.setDogList(dogList);
// ์œ„๋„, ๊ฒฝ๋„
userMDTO.setLatitude(Double.parseDouble(latitude));
userMDTO.setLongitude(Double.parseDouble(longitude));

 

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ผ๋•Œ๋งˆ๋‹ค ์‹คํ–‰ ์ฝ”๋“œ์ด๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ (์‚ฌ์šฉ์ž์ •๋ณด+์œ„์น˜(์œ„๋„,๊ฒฝ๋„)) ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ ๋‹ค.

 

// ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ userList(Map) ์— ์ €์žฅ
userList.put(session.getId(), userMDTO);
// ํ˜„์ œ ์ ‘์† ์ค‘์ธ ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ (์ž์‹ ์€ ์ œ์™ธ)
CLIENTS.entrySet().forEach(arg -> {
if(!arg.getKey().equals(id)) { // ์ž์‹ ์ด ์•„๋‹ˆ๋ฉด ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
try {
// ์œ„์น˜ ์ •๋ณด๋„ ํฌํ•จํ•˜์—ฌ ์ „๋‹ฌ
JSONObject response = new JSONObject();
response.put("type", "LOCATION"); // ๋ฉ”์‹œ์ง€ ํƒ€์ž…์€ LOCATION
response.put("userId", userMDTO.getUserId());
response.put("userName", userMDTO.getUserName());
response.put("latitude", userMDTO.getLatitude());
response.put("longitude", userMDTO.getLongitude());
response.put("photo", userMDTO.getPhoto());
response.put("dogList", userMDTO.getDogList());
// ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฉ”์‹œ์ง€ ์ „์†ก
arg.getValue().sendMessage(new TextMessage(response.toString()));
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
});

 

 

->  userList ์—๋„ ์ถ”๊ฐ€ํ•˜๊ณ 

->  JSON ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋‚˜๋ฅผ ์ œ์™ธํ•œ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ๋“ค์—๊ฒŒ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค.

 

// ๋ฉ”์„ธ์ง€ type = "CLOSE" ๋ฉด ์—ฐ๊ฒฐ ์ข…๋ฃŒ, ์„ธ์…˜ ์ œ๊ฑฐ
switch(type) {
case "CLOSE" :
CLIENTS.remove(session.getId());
userList.remove(session.getId());
break;
default:
break;
}

 

/**
* ํด๋ผ์ด์–ธํŠธ์™€์˜ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋  ๋•Œ ํ˜ธ์ถœ๋จ
* - ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ๋ฅผ CLIENTS ๋ชฉ๋ก์—์„œ ์ œ๊ฑฐ
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
CLIENTS.remove(session.getId());
userList.remove(session.getId());
}

 

 

-  ๋ฉ”์„ธ์ง€ ํƒ€์ž…์ด CLOSE ์ผ๋•Œ์—๋Š” ์„ธ์…˜์„ ์ œ๊ฑฐํ•ด์„œ ์—ฐ๊ฒฐ์„ ์ข…๋ฃŒ์‹œํ‚ค๊ณ 

- afterConnectionClosed ์—๋„ ์„ธ์…˜ ์ œ๊ฑฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ค€๋‹ค  => ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋œ ํ›„ ํ˜ธ์ถœ๋จ 

 

 


 

 

ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ

 

 

 

ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํฌ๋กฌ ํ™•์žฅํ”„๋กœ๊ทธ๋žจ์ธ Browser WebSocket Client ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

 

 

 

ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ์„ค์ •ํ•ด๋‘” endpoint ์ฃผ์†Œ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ์›น์†Œ์ผ“์— ์—ฐ๊ฒฐ๋œ๋‹ค

 

 

 

 

 

โœ… ํ…Œ์ŠคํŠธ 1) ์†Œ์ผ“์— ์ ‘์†ํ•œ ์œ ์ € ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ 

 

 

1) arin84 ๊ฐ€ ์ ‘์†ํ•˜๋ฉด -> ํ˜„์žฌ ์†Œ์ผ“์— ์žˆ๋Š” ์œ ์ € ๋ฆฌ์ŠคํŠธ (arin84 ๊ฐ€ ์ฒ˜์Œ์ด๋ฏ€๋กœ ์•„๋ฌด๋„ ์—†์Œ)

2) ์ดํ›„ ์œ„์น˜์ •๋ณด๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ธ๋‹ค. 

 

 

3) doyoon90 ์ด ์†Œ์ผ“์— ์ ‘์†ํ•˜๋ฉด ๋ฏธ๋ฆฌ ์ ‘์†ํ•ด ์žˆ๋˜ arin84์˜ ์ •๋ณด๊ฐ€ ๋œฌ๋‹ค. 

4) ์ดํ›„ ์œ„์น˜์ •๋ณด๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ธ๋‹ค.

 

 


โœ… ํ…Œ์ŠคํŠธ 2 ) ์†Œ์ผ“์— ์ ‘์†ํ•œ ์‚ฌ๋žŒ์—๊ฒŒ ์ž์‹ ์˜ ์ •๋ณด ์ „๋‹ฌ (๋ฉ”์„ธ์ง€ ์ „๋‹ฌ)

 

 

5) arin84 ๋Š” doyoon90 ์ด ์ ‘์†ํ•ด์„œ ๋ณด๋‚ธ ์œ„์น˜์ •๋ณด๋ฅผ ๋ฐ›๊ฒŒ ๋œ๋‹ค.

 

 

 

โœ… ํ…Œ์ŠคํŠธ 3 ) ์†Œ์ผ“ ์ข…๋ฃŒ ํ…Œ์ŠคํŠธ 

 

 

6) doyoon90 ์ด ์ ‘์†์„ ์ข…๋ฃŒํ•˜๊ณ  ์ƒˆ๋กœ์šด yeye91 ์ด ์ ‘์†ํ•ด๋ณด์ž. (์ด๋Ÿฐ๊ฒฝ์šฐ ๋ฆฌ์ŠคํŠธ์—๋Š” arin84๋งŒ ์กด์žฌํ•ด์•ผํ•จ)

 

 

yeye91

 

7) arin84 ๋งŒ ์†Œ์ผ“์— ์กด์žฌํ•˜๊ฒŒ๋œ๋‹ค. 

 

 

8) ์ฆ‰ ์ข…๋ฃŒ๋˜์–ด์„œ yeye91 ์ด ๋ณด๋‚ด๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค. arin84 ๋งŒ ๊ณ„์†ํ•ด์„œ ๋ฐ›์Œ