DE32FinalTeam2 / JavaWithKafka

0 stars 0 forks source link

채팅방에 카프카 입히기 #2

Closed GITSangWoo closed 2 days ago

GITSangWoo commented 3 days ago

[채팅방 코드 내용] java Stomp( websocket) 사용

websocketconfig.java

package com.websocket.socket.socket;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker //웹 소켓 메시지를 다룰 수 있게 허용
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic"); //발행자가 "/topic"의 경로로 메시지를 주면 구독자들에게 전달
        config.setApplicationDestinationPrefixes("/app"); // 발행자가 "/app"의 경로로 메시지를 주면 가공을 해서 구독자들에게 전달
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/gs-guide-websocket").withSockJS(); // 커넥션을 맺는 경로 설정. 만약 WebSocket을 사용할 수 없는 브라우저라면 다른 방식을 사용하도록 설정
    }

}

GreetingController.java

package com.websocket.socket.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.util.HtmlUtils;

import com.websocket.socket.greeting.Greeting;
import com.websocket.socket.message.HelloMessage;

@Controller
public class GreetingController {

    private static final String TOPIC = "abcdefg"; // Kafka 토픽 이름

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate; // KafkaTemplate 주입

    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        Thread.sleep(1000); // simulated delay

        // Kafka에 메시지를 전송
        String processedMessage = message.getName() + HtmlUtils.htmlEscape(message.getMessage());
        kafkaTemplate.send(TOPIC, processedMessage); // 메시지 전송

        return new Greeting(processedMessage); // 메시지 반환
    }
}

greeting.java

package com.websocket.socket.greeting;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Greeting {
    private String content;
}

HelloMessage.java

package com.websocket.socket.message;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class HelloMessage {
    private String name;
    private String message;
}

app.js

var stompClient = null;

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

function connect() {
    var socket = new SockJS('/gs-guide-websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/greetings', function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

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

// function sendName() {
//     stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
// }
function sendName() {
    const name = $("#name").val();
    const message = $("#message").val();
    stompClient.send("/app/hello", {}, JSON.stringify({'name': name, 'message': message}));
}

function showGreeting(message) {
    $("#greetings").append("<tr><td>" + message + "</td></tr>");
}

$(function () {
    $("form").on('submit', function (e) {
        e.preventDefault(); // 기본 폼 제출 방지
    });

    $("#connect").click(function() { connect(); });
    $("#disconnect").click(function() { disconnect(); });

    $("#send").click(function() { sendMessage(); });

    });
});

function sendMessage() {
    const message = $("#message").val();
    const name = $("#name").val();

    // 메시지 전송 로직 (예: stompClient.send 등)
    stompClient.send("/app/hello", {}, JSON.stringify({'name': name, 'message': message}));

    $("#message").val(''); // 입력 필드 초기화
}

index.html

<!-- <!DOCTYPE html>
<html>
<head>
    <title>Hello WebSocket</title>
    <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/main.css" rel="stylesheet">
    <script src="/webjars/jquery/jquery.min.js"></script>
    <script src="/webjars/sockjs-client/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/stomp.min.js"></script>
    <script src="/app.js"></script>
</head>
<body>
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
    enabled. Please enable
    Javascript and reload this page!</h2></noscript>
<div id="main-content" class="container">
    <div class="row">
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="connect">WebSocket connection:</label>
                    <button id="connect" class="btn btn-default" type="submit">Connect</button>
                    <button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect
                    </button>
                </div>
            </form>
        </div>
    <div class="row">
        <div class="col-md-12">
            <table id="conversation" class="table table-striped">
                <thead>
                <tr>
                    <th>ChatRoom</th>
                </tr>
                </thead>
                <tbody id="greetings">
                </tbody>
            </table>
        </div>
    </div>
    <div class="row" style="margin-top: 20px;">
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="name">What is your name?</label>
                    <input type="text" id="name" class="form-control" placeholder="Your name here..." style="margin-right: 10px;">
                </div>
            </form>
        </div>
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="message">Message:</label>
                    <input type="text" id="message" class="form-control" placeholder="Your message here..." style="margin-right: 10px;">
                </div>
                <button id="send" class="btn btn-default" type="button">Send</button>
            </form>
        </div>
    </div>
</div>
</body>
</html> -->
<!DOCTYPE html>
<html>
<head>
    <title>Hello WebSocket</title>
    <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/main.css" rel="stylesheet">
    <script src="/webjars/jquery/jquery.min.js"></script>
    <script src="/webjars/sockjs-client/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/stomp.min.js"></script>
    <script src="/app.js"></script>
    <style>
        /* 채팅 내용 영역 */
        #conversation {
            margin-bottom: 60px; /* 고정된 입력 필드 높이만큼 아래 여백 추가 */
        }
        /* 고정된 입력 영역 */
        #input-area {
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            background-color: white; /* 배경색 */
            padding: 10px; /* 패딩 */
            box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1); /* 그림자 */
        }
    </style>
</head>
<body>
<noscript>
    <h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
    enabled. Please enable Javascript and reload this page!</h2>
</noscript>
<div id="main-content" class="container">
    <div class="row">
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="connect">Chatting Room connection:</label>
                    <button id="connect" class="btn btn-default" type="button">Connect</button>
                    <button id="disconnect" class="btn btn-default" type="button" disabled="disabled">Disconnect</button>
                </div>
            </form>
        </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            <table id="conversation" class="table table-striped">
                <thead>
                <tr>
                    <th>Chatting Room</th>
                </tr>
                </thead>
                <tbody id="greetings">
                </tbody>
            </table>
        </div>
    </div>
</div>
<div id="input-area">
    <div class="row">
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="name">What is your name?</label>
                    <input type="text" id="name" class="form-control" placeholder="Your name here..." style="margin-right: 10px;">
                </div>
            </form>
        </div>
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="message">Message:</label>
                    <input type="text" id="message" class="form-control" placeholder="Your message here..." style="margin-right: 10px;">
                </div>
                <button id="send" class="btn btn-default" type="button">Send</button>
            </form>
        </div>
    </div>
</div>
</body>
</html>
hun0219 commented 2 days ago
hun0219 commented 2 days ago

@GITSangWoo 채팅방 대화내용 엔터쳐서 submit 기능 구현 해주세요

GITSangWoo commented 2 days ago

app.js

$(function () {
    $("form").on('submit', function (e) {
        e.preventDefault(); // 기본 폼 제출 방지
    });

    $("#connect").click(function() { connect(); });
    $("#disconnect").click(function() { disconnect(); });

    $("#send").click(function() { sendMessage(); });

    // 메시지 입력 필드에서 엔터 키 감지
    $("#message").keypress(function(e) {
        if (e.which === 13) { // 엔터 키 코드
            e.preventDefault(); // 기본 동작 방지
            sendMessage(); // 메시지 전송
        }
    });
});

엔터키 이슈 관련해서 기능 추가했습니다. 좋은 의견 감사합니다