Comments (1)
Hi @kinjalnyc - sorry for the late reply.
I didn't spend much time, but here's one way you can create multiple rooms, and have chat messages delivered to the targeted ones.
- Update HanlderMapping to accept query in url:
@Bean
public HandlerMapping webSocketHandlerMapping(ChatWebSocketHandler webSocketHandler) {
Map<String, WebSocketHandler> map = new HashMap<>();
map.put("/redis-chat/**", webSocketHandler);
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setCorsConfigurations(Collections.singletonMap("*", new CorsConfiguration().applyPermitDefaultValues()));
handlerMapping.setOrder(1);
handlerMapping.setUrlMap(map);
return handlerMapping;
}
- Add room field in the message:
public class ChatMessage {
private Integer id;
private String message;
private String hostname;
private Long usersOnline;
private String room;
}
- Update RedisChatMessagePublisher.publishChatMessage() method to accept room:
public Mono<Long> publishChatMessage(String message, String room) {
Integer totalChatMessage = chatMessageCounter.incrementAndGet();
return Mono.fromCallable(() -> {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
log.error("Error getting hostname.", e);
}
return "localhost";
}).map(hostName -> {
ChatMessage chatMessage = new ChatMessage(totalChatMessage, message, hostName, activeUserCounter.get(), room);
String chatString = "EMPTY_MESSAGE";
try {
chatString = objectMapper.writeValueAsString(chatMessage);
} catch (JsonProcessingException e) {
log.error("Error converting ChatMessage {} into string", chatMessage, e);
}
return chatString;
}).flatMap(chatString -> {
// Publish Message to Redis Channels
return reactiveStringRedisTemplate.convertAndSend(MESSAGE_TOPIC, chatString)
.doOnSuccess(aLong -> log.debug("Total of {} Messages published to Redis Topic.", totalChatMessage))
.doOnError(throwable -> log.error("Error publishing message.", throwable));
});
}
-
Update ChatWebSocketHandler.handle() method to get room from the URL:
public Mono handle(WebSocketSession webSocketSession) {String room = webSocketSession.getHandshakeInfo().getUri().getQuery().replace("room=", ""); Flux<WebSocketMessage> sendMessageFlux = chatMessageFluxSink.filter(chatMessage -> chatMessage.getRoom().equals(room)).flatMap(objectStringConverter::objectToString) .map(webSocketSession::textMessage) .doOnError(throwable -> log.error("Error Occurred while sending message to WebSocket.", throwable)); Mono<Void> outputMessage = webSocketSession.send(sendMessageFlux); Mono<Void> inputMessage = webSocketSession.receive() .flatMap(webSocketMessage -> redisChatMessagePublisher.publishChatMessage(webSocketMessage.getPayloadAsText(), room)) .doOnSubscribe(subscription -> { long activeUserCount = activeUserCounter.incrementAndGet(); log.info("User '{}' Connected. Total Active Users: {}", webSocketSession.getId(), activeUserCount); chatMessageSink.tryEmitNext(new ChatMessage(0, "CONNECTED", "CONNECTED", activeUserCount, room)); }) .doOnError(throwable -> log.error("Error Occurred while sending message to Redis.", throwable)) .doFinally(signalType -> { long activeUserCount = activeUserCounter.decrementAndGet(); log.info("User '{}' Disconnected. Total Active Users: {}", webSocketSession.getId(), activeUserCount); chatMessageSink.tryEmitNext(new ChatMessage(0, "DISCONNECTED", "DISCONNECTED", activeUserCount, room)); }) .then(); return Mono.zip(inputMessage, outputMessage).then();
}
-
And finally update the UI forms, to accept room before sending messages. You can run below JS in browser console to send and receive messages:
let host = location.hostname + (location.port ? ':' + location.port : '');
let wsProtocol = location.protocol === "https:" ? "wss://" : "ws://";
// connecting room=one
let room1 = new WebSocket(wsProtocol + host + "/redis-chat?room=one");
room1.onopen = openEvent => {
console.log("room1 opened", openEvent);
};
room1.onmessage = messageEvent => {
console.log("Message: from room1 ", messageEvent);
};
// connecting room=two
let room2 = new WebSocket(wsProtocol + host + "/redis-chat?room=two");
room2.onopen = openEvent => {
console.log("room2 opened", openEvent);
};
room2.onmessage = messageEvent => {
console.log("Message: from room2 ", messageEvent);
};
// Send messages:
room1.send('This message goes to all connected to room-1');
room2.send('This message goes to all connected to room-2');
room1.send('This message goes to all connected to room-1');
Hope this help!
from spring-redis-websocket.
Related Issues (3)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-redis-websocket.