Julkisten chat-huoneiden toteuttaminen
Kehittäkää toiminnallisuus, jonka avulla käyttäjät voivat liittyä julkisiin yleislähetyksen kaltaisiin chat-huoneisiin ja osallistua niissä keskusteluun.
Julkisten chat-huoneiden toteuttaminen on ilmainen WebSockets ja reaaliaikaiset järjestelmät Springillä-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu WebSockets ja reaaliaikaiset järjestelmät Springillä-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. WebSockets ja reaaliaikaiset järjestelmät Springillä-kurssilla on yhteensä 4 oppituntia.
Julkiset chat-huoneet selitettynä
Tervetuloa! Tässä oppitunnissa rakennamme julkisia chat-huoneita. Ne ovat yhteisiä tiloja, joissa useat käyttäjät voivat lähettää ja vastaanottaa viestejä, jotka näkyvät kaikille huoneessa oleville.
Ajattele viestisovelluksen yleistä keskustelukanavaa. Keskeinen ominaisuus on yleislähetysviestintä: yhden käyttäjän lähettämä viesti välitetään välittömästi kaikille muille käyttäjille, jotka ovat parhaillaan huoneessa.
STOMP-aiheet huoneita varten
Springissä ja STOMPissa käytämme aiheita chat-huoneiden esittämiseen. Aihe on kanavan kaltainen kohde, jonka asiakkaat voivat tilata. Aiheeseen lähetetyt viestit lähetetään kaikille sen tilaajille.
- Julkisissa huoneissa käytetään usein yhteistä aihepolkua, kuten
/topic/public-chat. - Asiakkaat tilaavat tämän aiheen vastaanottaakseen viestejä.
- Asiakkaat lähettävät viestejä tiettyyn sovelluskohteeseen, josta palvelin välittää ne edelleen aiheeseen.
Yksinkertainen chat-viestimalli
Ennen chat-logiikan toteuttamista tarvitsemme viesteille yksinkertaisen rakenteen. Näin varmistetaan, että kaikki ymmärtävät lähetettävän datan.
Perustason ChatMessage voi sisältää viestin type-tyypin (esimerkiksi CHAT, JOIN ja LEAVE), sender-lähettäjän nimen sekä varsinaisen content-sisällön. Tässä on lyhyt katsaus:
public class ChatMessage {
public enum MessageType {
CHAT,
JOIN,
LEAVE
}
private MessageType type;
private String content;
private String sender;
public ChatMessage() {}
public MessageType getType() { return type; }
public void setType(MessageType type) { this.type = type; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getSender() { return sender; }
public void setSender(String sender) { this.sender = sender; }
@Override
public String toString() {
return "ChatMessage{" + "type=" + type + ", sender='" + sender + "', content='" + content + "'}";
}
}Palvelinpuolen chat-ohjain
Saapuvien chat-viestien käsittelyä ja lähettämistä varten luomme Spring-@Controller-komponentin. Tämä komponentti kuuntelee tiettyyn sovelluskohteeseen (esimerkiksi /app/chat.sendMessage) lähetettyjä viestejä ja käyttää sitten SimpMessageSendingOperations-rajapintaa (usein SimpMessagingTemplate-toteutusta) niiden lähettämiseen julkiseen aiheeseemme (/topic/public-chat).
Kokeilkaa tämän esimerkin suorittamista:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
// ChatMessage POJO (for simplicity, included here)
class ChatMessage {
public enum MessageType { CHAT, JOIN, LEAVE }
private MessageType type;
private String content;
private String sender;
public ChatMessage() {}
public MessageType getType() { return type; }
public void setType(MessageType type) { this.type = type; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getSender() { return sender; }
public void setSender(String sender) { this.sender = sender; }
@Override
public String toString() {
return "ChatMessage{" + "type=" + type + ", sender='" + sender + "', content='" + content + "'}";
}
}
// WebSocket Configuration
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}
// Chat Controller
@Controller
class ChatController {
private final SimpMessageSendingOperations messagingTemplate;
public ChatController(SimpMessageSendingOperations messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
@MessageMapping("/chat.sendMessage")
public void sendMessage(@Payload ChatMessage chatMessage) {
System.out.println("Received CHAT message from " + chatMessage.getSender() + ": " + chatMessage.getContent());
messagingTemplate.convertAndSend("/topic/public-chat", chatMessage);
}
}
// Main Application
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
System.out.println("\n--- Spring Boot Chat Server Started ---");
System.out.println("Connect to ws://localhost:8080/ws");
System.out.println("Send CHAT messages to /app/chat.sendMessage and subscribe to /topic/public-chat");
}
}Käyttäjien liittymisen lähettäminen
Kun käyttäjä muodostaa ensimmäisen kerran yhteyden tai liittyy nimenomaisesti chat-huoneeseen, on hyvä käytäntö ilmoittaa siitä kaikille muille. Tämä voidaan tehdä lähettämällä erityinen JOIN-tyyppinen viesti.
@MessageMapping voi tunnistaa nämä liittymistapahtumat ja lähettää ne samaan julkiseen aiheeseen. Näin kaikki asiakkaat tietävät, kuka on liittynyt huoneeseen.
Laajennetaan ChatController-komponenttia käsittelemään JOIN-viestejä:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
class ChatMessage {
public enum MessageType { CHAT, JOIN, LEAVE }
private MessageType type;
private String content;
private String sender;
public ChatMessage() {}
public MessageType getType() { return type; }
public void setType(MessageType type) { this.type = type; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getSender() { return sender; }
public void setSender(String sender) { this.sender = sender; }
@Override
public String toString() {
return "ChatMessage{" + "type=" + type + ", sender='" + sender + "', content='" + content + "'}";
}
}
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}
@Controller
class ChatController {
private final SimpMessageSendingOperations messagingTemplate;
public ChatController(SimpMessageSendingOperations messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
@MessageMapping("/chat.sendMessage")
public void sendMessage(@Payload ChatMessage chatMessage) {
System.out.println("Received CHAT message from " + chatMessage.getSender() + ": " + chatMessage.getContent());
messagingTemplate.convertAndSend("/topic/public-chat", chatMessage);
}
@MessageMapping("/chat.addUser")
public void addUser(@Payload ChatMessage chatMessage) {
if (chatMessage.getType() == ChatMessage.MessageType.JOIN) {
System.out.println(chatMessage.getSender() + " JOINED the chat!");
messagingTemplate.convertAndSend("/topic/public-chat", chatMessage);
}
}
}
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
System.out.println("\n--- Spring Boot Chat Server Started with JOIN handling ---");
System.out.println("Connect to ws://localhost:8080/ws");
System.out.println("Send JOIN messages to /app/chat.addUser");
System.out.println("Send CHAT messages to /app/chat.sendMessage");
System.out.println("Subscribe to /topic/public-chat");
}
}Asiakas: yhteyden muodostaminen ja tilaaminen
Asiakaspuolella (esimerkiksi JavaScriptiä ja SockJS/STOMP.js:ää käytettäessä) ensimmäinen vaihe on WebSocket-yhteyden muodostaminen ja sen jälkeen julkisen chat-aiheen tilaaminen.
Asiakas käyttää STOMP-asiakasta yhteyden muodostamiseen /ws-päätepisteeseen ja tilaa sitten aiheen /topic/public-chat vastaanottaakseen kaikki lähetetyt viestit.
// Assuming SockJS and STOMP.js are loaded
var socket = new SockJS('/ws'); // Connect to our WebSocket endpoint
var stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame);
// Subscribe to the public chat topic
stompClient.subscribe('/topic/public-chat', function(message) {
var chatMessage = JSON.parse(message.body);
console.log('Received message: ' + chatMessage.content + ' from ' + chatMessage.sender);
// Update UI with the message
});
// Send a JOIN message (example)
stompClient.send("/app/chat.addUser", {}, JSON.stringify({
sender: 'User123',
type: 'JOIN'
}));
});Asiakas: chat-viestien lähettäminen
Kun yhteys on muodostettu ja aihe tilattu, asiakkaat voivat lähettää chat-viestejä palvelimelle. Viestit lähetetään sovelluskohteeseen (esimerkiksi /app/chat.sendMessage), jota Spring-komponenttimme kuuntelee.
Palvelin käsittelee viestin ja lähettää sen sitten takaisin kaikille kohteen /topic/public-chat tilaajille, myös viestin lähettäjälle.
// Function to send a chat message
function sendChatMessage(senderName, messageContent) {
if (stompClient && stompClient.connected) {
var chatMessage = {
sender: senderName,
content: messageContent,
type: 'CHAT'
};
stompClient.send("/app/chat.sendMessage", {}, JSON.stringify(chatMessage));
console.log("Sent: " + chatMessage.content);
} else {
console.log("STOMP client not connected.");
}
}
// Example usage:
// sendChatMessage('Alice', 'Hello everyone!');Chatin koko kulku
Hahmotellaan julkisen chat-huoneen koko kulku:
- Asiakas muodostaa yhteyden: Käyttäjän selain muodostaa yhteyden WebSocket-päätepisteeseen (
/ws). - Asiakas tilaa aiheen: Asiakas tilaa julkisen aiheen (
/topic/public-chat) vastaanottaakseen viestejä. - Asiakas liittyy: Asiakas lähettää
JOIN-viestin palvelimelle (/app/chat.addUser). - Palvelin lähettää liittymisilmoituksen: Palvelin vastaanottaa
JOIN-viestin ja lähettää sen aiheeseen/topic/public-chat. Kaikki asiakkaat vastaanottavat ilmoituksen käyttäjän liittymisestä. - Asiakas lähettää chat-viestin: Asiakas lähettää
CHAT-viestin palvelimelle (/app/chat.sendMessage). - Palvelin lähettää chat-viestin: Palvelin vastaanottaa
CHAT-viestin ja lähettää sen aiheeseen/topic/public-chat. Kaikki asiakkaat vastaanottavat chat-viestin.
Julkisen chatin parhaat käytännöt
Kun rakennatte julkisia chat-huoneita, huomioikaa seuraavat seikat paremman käyttökokemuksen ja palvelimen suorituskyvyn varmistamiseksi:
- Viestihistoria: Toteuttakaa tapa tallentaa aiemmat viestit ja hakea ne huoneeseen liittyville uusille käyttäjille.
- Käyttäjien läsnäolo: Seuratkaa huoneessa aktiivisia käyttäjiä (esimerkiksi muistissa olevan hajautustaulun tai tietokannan avulla).
- Taajuuden rajoittaminen: Estäkää roskapostitus rajoittamalla, kuinka usein käyttäjä voi lähettää viestejä.
- Moderointi: Tarjotkaa moderaattoreille työkalut sopimattomien viestien poistamiseen ja käyttäjien estämiseen.
- Skaalautuvuus: Harkitkaa suurissa julkisissa chateissa ulkoisia viestinvälittäjiä, kuten RabbitMQ:ta tai Kafkaa.
Julkisen chat-huoneen testi
Mitkä seuraavista väitteistä pitävät paikkansa toteutettaessa julkisia chat-huoneita Spring WebSocketsin ja STOMP:n avulla?
Kertaus: julkiset chat-huoneet
Tässä oppitunnissa opitte toteuttamaan julkisia, lähetyspohjaisia chat-huoneita Spring WebSocketsin ja STOMP:n avulla.
- Näimme, kuinka STOMP-aiheet (esimerkiksi
/topic/public-chat) toimivat huoneiden viestintäkanavina. - Opitte käyttämään palvelimella
@MessageMapping- jaSimpMessageSendingOperations-komponentteja saapuvien viestien käsittelyyn ja niiden lähettämiseen. - Tutustuimme käyttäjien liittymistapahtumien käsittelyyn ja kaikkien osallistujien ilmoittamiseen.
- Lopuksi käsittelimme lyhyesti asiakaspuolen toimintaa ja tärkeitä hyviä käytäntöjä vakaiden chat-sovellusten toteuttamiseksi.
Seuraavaksi perehdymme yksityisten kahdenkeskisten viestien toteuttamiseen!
Opi WebSockets ja reaaliaikaiset järjestelmät Springillä tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 12
- Oppitunnit
- 48
Usein kysytyt kysymykset
Onko oppitunti ”Julkisten chat-huoneiden toteuttaminen” ilmainen?
Kyllä – oppitunnin ”Julkisten chat-huoneiden toteuttaminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko WebSockets ja reaaliaikaiset järjestelmät Springillä-kurssin, päivitä CoddyKit PROhon. WebSockets ja reaaliaikaiset järjestelmät Springillä-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Julkisten chat-huoneiden toteuttaminen”?
Kehittäkää toiminnallisuus, jonka avulla käyttäjät voivat liittyä julkisiin yleislähetyksen kaltaisiin chat-huoneisiin ja osallistua niissä keskusteluun. Harjoittelet WebSockets ja reaaliaikaiset järjestelmät Springillä-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni WebSockets ja reaaliaikaiset järjestelmät Springillä-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin WebSockets ja reaaliaikaiset järjestelmät Springillä-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Julkisten chat-huoneiden toteuttaminen”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä WebSockets ja reaaliaikaiset järjestelmät Springillä-oppitunnilla?
Kyllä. Jokainen WebSockets ja reaaliaikaiset järjestelmät Springillä-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Chat-viestimallin suunnittelu
- Julkisten chat-huoneiden toteuttaminen
- Yksityisviestintä STOMP:lla
- Kirjoitusilmaisimet ja paikallaolo