Skip to content

๐Ÿ’ฌ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ํ”„๋กœ๊ทธ๋žจ ๐Ÿ’ฌ

Notifications You must be signed in to change notification settings

BeomjunLee/webSocketChat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

24 Commits
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ์„œ๋น„์Šค

STOMP ํ๋ฆ„


  1. ํด๋ผ์ด์–ธํŠธ(Sender)๊ฐ€ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๋ฉด STOMP ํ†ต์‹ ์œผ๋กœ ์„œ๋ฒ„์— ๋ฉ”์„ธ์ง€๊ฐ€ ์ „๋‹ฌ๋œ๋‹ค.

  2. Controller์˜ @MessageMapping์— ์˜ํ•ด ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ›๋Š”๋‹ค.

  3. Controller์˜ @SendTo๋กœ ํŠน์ • topic์„(/1) ๊ตฌ๋…(/room) ํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค.
    (๊ตฌ๋…์€ /room ์œผ๋กœ ๋ณด๋ฉด๋˜๊ณ  ํŠน์ • topic์€ ์ฑ„ํŒ…๋ฐฉ id์ธ /1๋กœ ๋ณด๋ฉด๋œ๋‹ค. -> /room/1)

๋‚ด ๋ธ”๋กœ๊ทธ์—์„œ ์ƒ์„ธ ์„ค๋ช… ๋ณด๊ธฐ(ํฌ์ŠคํŒ…)

https://blog.naver.com/qjawnswkd/222283176175

1. Gradle ์˜์กด์„ฑ ์„ค์ •

	implementation 'org.springframework.boot:spring-boot-starter-websocket'
	implementation 'org.webjars:webjars-locator-core'
	implementation 'org.webjars:sockjs-client:1.0.2'
	implementation 'org.webjars:stomp-websocket:2.3.3'
	implementation 'org.webjars:bootstrap:3.3.7'
	implementation 'org.webjars:jquery:3.1.1-1'

2. WebSocketConfig ์„ค์ •

@Configuration
@RequiredArgsConstructor
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/send");       //ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ณด๋‚ธ ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ›์„ prefix
        registry.enableSimpleBroker("/room");    //ํ•ด๋‹น ์ฃผ์†Œ๋ฅผ ๊ตฌ๋…ํ•˜๊ณ  ์žˆ๋Š” ํด๋ผ์ด์–ธํŠธ๋“ค์—๊ฒŒ ๋ฉ”์„ธ์ง€ ์ „๋‹ฌ
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws-stomp")   //SockJS ์—ฐ๊ฒฐ ์ฃผ์†Œ
                .withSockJS(); //๋ฒ„์ „ ๋‚ฎ์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ ์ ์šฉ ๊ฐ€๋Šฅ
        // ์ฃผ์†Œ : ws://localhost:8080/ws-stomp
    }
}

3. ์ปจํŠธ๋กค๋Ÿฌ

@Controller
@RequiredArgsConstructor
public class ChatController {

    private final ChatService chatService;

    @MessageMapping("/{roomId}") //์—ฌ๊ธฐ๋กœ ์ „์†ก๋˜๋ฉด ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ -> WebSocketConfig prefixes ์—์„œ ์ ์šฉํ•œ๊ฑด ์•ž์— ์ƒ๋žต
    @SendTo("/room/{roomId}")   //๊ตฌ๋…ํ•˜๊ณ  ์žˆ๋Š” ์žฅ์†Œ๋กœ ๋ฉ”์‹œ์ง€ ์ „์†ก (๋ชฉ์ ์ง€)  -> WebSocketConfig Broker ์—์„œ ์ ์šฉํ•œ๊ฑด ์•ž์— ๋ถ™์–ด์ค˜์•ผ๋จ
    public ChatMessage test(@DestinationVariable Long roomId, ChatMessage message) {

        //์ฑ„ํŒ… ์ €์žฅ
        Chat chat = chatService.createChat(roomId, message.getSender(), message.getMessage());
        return ChatMessage.builder()
                .roomId(roomId)
                .sender(chat.getSender())
                .message(chat.getMessage())
                .build();
    }
}

4.ํด๋ผ์ด์–ธํŠธ

<script th:inline="javascript">
    var stompClient = null;
    var roomId = [[${roomId}]];
    var chatList = [[${chatList}]];

    function setConnected(connected) {
        $("#connect").prop("disabled", connected);
        $("#disconnect").prop("disabled", !connected);
        if (connected) {
            $("#conversation").show();
        }
        else {
            $("#conversation").hide();
        }
        $("#chatting").html("");
    }

    function connect() {
        var socket = new SockJS('/ws-stomp');
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function (frame) {
            setConnected(true);
            console.log('Connected: ' + frame);
            loadChat(chatList)  //์ €์žฅ๋œ ์ฑ„ํŒ… ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

            //๊ตฌ๋…
            stompClient.subscribe('/room/'+roomId, function (chatMessage) {
                showChat(JSON.parse(chatMessage.body));
            });
        });
    }

    function disconnect() {
        if (stompClient !== null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
    }

    //html ์—์„œ ์ž…๋ ฅ๊ฐ’, roomId ๋ฅผ ๋ฐ›์•„์„œ Controller ๋กœ ์ „๋‹ฌ
    function sendChat() {
        stompClient.send("/send/"+roomId, {},
            JSON.stringify({
                'sender': $("#sender").val(),
                'message' : $("#message").val()
            }));
    }

    //์ €์žฅ๋œ ์ฑ„ํŒ… ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
    function loadChat(chatList){
        if(chatList != null) {
            for(chat in chatList) {
                $("#chatting").append(
                    "<tr><td>" + "[" + chatList[chat].sender + "]" + chatList[chat].message + "</td></tr>"
                );
            }
        }
    }

    //๋ณด๋‚ธ ์ฑ„ํŒ… ๋ณด๊ธฐ
    function showChat(chatMessage) {
        $("#chatting").append(
            "<tr><td>" + "[" + chatMessage.sender + "]" + chatMessage.message + "</td></tr>"
        );
    }

    $(function () {
        $("form").on('submit', function (e) {
            e.preventDefault();
        });
        $( "#connect" ).click(function() { connect(); });
        $( "#disconnect" ).click(function() { disconnect(); });
        $( "#send" ).click(function() { sendChat(); });
    });
</script>
<script>
    //์ฐฝ ํ‚ค๋ฉด ๋ฐ”๋กœ ์—ฐ๊ฒฐ
    window.onload = function (){
        connect();
    }

    window.BeforeUnloadEvent = function (){
        disconnect();
    }
</script>

Redis ์ถ”๊ฐ€์ค‘

์ฑ„ํŒ… ๋กœ๊ทธ Redis์— ์ €์žฅ

About

๐Ÿ’ฌ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ํ”„๋กœ๊ทธ๋žจ ๐Ÿ’ฌ

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published