Openbare chatruimtes implementeren
Ontwikkel functionaliteit waarmee gebruikers kunnen deelnemen aan openbare chatruimtes in broadcaststijl.
Openbare chatruimtes implementeren is een gratis WebSockets en realtime systemen met Spring-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject WebSockets en realtime systemen met Spring. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus WebSockets en realtime systemen met Spring bevat in totaal 4 lessen.
Openbare chatruimtes uitgelegd
Welkom! In deze les bouwen we openbare chatruimtes. Dit zijn gemeenschappelijke ruimtes waar veel gebruikers berichten kunnen versturen en ontvangen die voor iedereen in die ruimte zichtbaar zijn.
Denk aan een algemeen discussie kanaal in een berichtenapp. Het belangrijkste kenmerk is hier uitzendcommunicatie: één bericht dat door een gebruiker wordt verstuurd, wordt onmiddellijk doorgestuurd naar alle andere gebruikers die zich op dat moment in de ruimte bevinden.
STOMP-topics voor ruimtes
In Spring met STOMP gebruiken we topics om chatruimtes weer te geven. Een topic is vergelijkbaar met een kanaal waarop clients zich kunnen abonneren. Berichten die naar een topic worden verstuurd, worden naar al zijn abonnees uitgezonden.
- Voor openbare ruimtes gebruiken we vaak een gemeenschappelijk topicpad zoals
/topic/public-chat. - Clients abonneren zich op dit topic om berichten te ontvangen.
- Clients versturen berichten naar een specifieke applicatiebestemming, waarna de server deze doorstuurt naar het topic.
Eenvoudig model van een chatbericht
Voordat we de chatlogica implementeren, hebben we een eenvoudige structuur voor onze berichten nodig. Zo begrijpt iedereen welke gegevens worden verstuurd.
Een eenvoudig ChatMessage kan het berichttype type bevatten (bijvoorbeeld CHAT, JOIN en LEAVE), de naam van de sender en de daadwerkelijke content. Hier volgt een kort overzicht:
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 + "'}";
}
}Chatcontroller aan de serverzijde
Om binnenkomende chatberichten af te handelen en uit te zenden, maken we een Spring-@Controller. Deze controller luistert naar berichten die naar een specifieke toepassingsbestemming worden verzonden (bijvoorbeeld /app/chat.sendMessage) en gebruikt vervolgens een SimpMessageSendingOperations (vaak SimpMessagingTemplate) om ze naar ons openbare onderwerp (/topic/public-chat) uit te zenden.
Probeer dit voorbeeld uit te voeren:
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");
}
}Gebruikers die deelnemen uitzenden
Wanneer een gebruiker voor het eerst verbinding maakt of expliciet deelneemt aan een chatruimte, is het een goede gewoonte om alle anderen hiervan op de hoogte te stellen. Dat doen we door een speciaal bericht van het type JOIN te verzenden.
Onze @MessageMapping kan deze deelnamemomenten detecteren en naar hetzelfde openbare onderwerp uitzenden. Zo weten alle clients wie de chatruimte is binnengekomen.
We breiden onze ChatController uit om JOIN-berichten af te handelen:
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");
}
}Client: verbinding maken en abonneren
Aan de clientzijde (bijvoorbeeld met JavaScript en SockJS/STOMP.js) is de eerste stap het tot stand brengen van een WebSocket-verbinding en vervolgens abonneren op het openbare chatonderwerp.
De client gebruikt de STOMP-client om verbinding te maken met het /ws-eindpunt en abonneert zich vervolgens op /topic/public-chat om alle uitgezonden berichten te ontvangen.
// 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'
}));
});Client: chatberichten verzenden
Zodra clients verbonden zijn en een abonnement hebben, kunnen ze chatberichten naar de server verzenden. Deze berichten worden verzonden naar de toepassingsbestemming (bijvoorbeeld /app/chat.sendMessage) waar onze Spring-controller naar luistert.
De server verwerkt dit bericht vervolgens en zendt het terug naar alle abonnees van /topic/public-chat, inclusief de afzender.
// 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!');De volledige chatstroom
We brengen de volledige stroom voor een openbare chatruimte in beeld:
- Client maakt verbinding: De browser van een gebruiker maakt verbinding met het WebSocket-eindpunt (
/ws). - Client abonneert zich: De client abonneert zich op het openbare onderwerp (
/topic/public-chat) om berichten te ontvangen. - Client neemt deel: De client verzendt een
JOIN-bericht naar de server (/app/chat.addUser). - Server zendt deelname uit: De server ontvangt het
JOIN-bericht en zendt het uit naar/topic/public-chat. Alle clients ontvangen de melding dat een gebruiker heeft deelgenomen. - Client verzendt chatbericht: Een client verzendt een
CHAT-bericht naar de server (/app/chat.sendMessage). - Server zendt chatbericht uit: De server ontvangt het
CHAT-bericht en zendt het uit naar/topic/public-chat. Alle clients ontvangen het chatbericht.
Aanbevolen werkwijzen voor openbare chats
Houd bij het bouwen van openbare chatruimtes rekening met deze punten voor een betere gebruikerservaring en serverprestaties:
- Berichtgeschiedenis: Implementeer een manier om eerdere berichten op te slaan en op te halen voor nieuwe gebruikers die aan de chatruimte deelnemen.
- Aanwezigheid van gebruikers: Houd actieve gebruikers in een chatruimte bij (bijvoorbeeld met een kaart in het geheugen of een database).
- Frequentiebeperking: Voorkom spam door te beperken hoe vaak een gebruiker berichten kan verzenden.
- Moderatie: Bied moderators hulpmiddelen om ongepaste berichten te verwijderen of gebruikers te blokkeren.
- Schaalbaarheid: Overweeg voor openbare chats op grote schaal externe berichtenmakelaars zoals RabbitMQ of Kafka.
Controle van openbare chatruimtes
Welke van de volgende uitspraken zijn waar over het implementeren van openbare chatruimtes met Spring WebSockets en STOMP?
Samenvatting: openbare chatruimtes
In deze les heb je geleerd hoe je openbare chatruimtes met een uitzendmodel implementeert met Spring WebSockets en STOMP.
- We hebben gezien hoe STOMP-onderwerpen (bijvoorbeeld
/topic/public-chat) als kanalen voor chatruimtes dienen. - Je hebt geleerd hoe je
@MessageMappingenSimpMessageSendingOperationsop de server gebruikt om binnenkomende berichten af te handelen en uit te zenden. - We hebben onderzocht hoe je gebeurtenissen waarbij gebruikers deelnemen afhandelt en alle deelnemers hiervan op de hoogte stelt.
- Tot slot hebben we de interactie aan de clientzijde en belangrijke aanbevolen werkwijzen voor betrouwbare chattoepassingen besproken.
Vervolgens gaan we aan de slag met privéberichten tussen twee personen!
Leer WebSockets en realtime systemen met Spring met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 12
- Lessen
- 48
Veelgestelde vragen
Is de les “Openbare chatruimtes implementeren” gratis?
Ja — de volledige tekst van “Openbare chatruimtes implementeren” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus WebSockets en realtime systemen met Spring wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus WebSockets en realtime systemen met Spring bevat in totaal 4 lessen.
Wat leer ik in “Openbare chatruimtes implementeren”?
Ontwikkel functionaliteit waarmee gebruikers kunnen deelnemen aan openbare chatruimtes in broadcaststijl. Je oefent met WebSockets en realtime systemen met Spring door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met WebSockets en realtime systemen met Spring te beginnen?
Ervaring vooraf is niet nodig. WebSockets en realtime systemen met Spring op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.
Hoe lang duurt de les “Openbare chatruimtes implementeren”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over WebSockets en realtime systemen met Spring?
Ja. Elke les over WebSockets en realtime systemen met Spring bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Een chatberichtenmodel ontwerpen
- Openbare chatruimtes implementeren
- Privéberichten met STOMP
- Typindicatoren en online aanwezigheid