Хочу написать многопользовательский чат. Задумка такова: пользователь открывает страничку чата, открывается канал по rsocket, и отправляется сообщение о том что новый пользователь присоединился. Когда вводится сообщение, это сообщение отсылается всем клиентам по открытым ранее каналам.
На данный момент я знаю как отрыть, канал на клиенте, но не знаю что передавать как data в requestChannel (знаю что для ввода будет textArea и рядом кнопка для отправки, в теории в requestChannel надо как то передать контент, который будет генериться при событии щелчка по кнопке). На стороне сервера - spring контроллер, который сохраняет RSocketRequester(скорее всего без толку).
Вопросы следующие:
* как правильно открыть канал на клиенте, передав в, socket.requestChannel({data: ..., metadata: ...}) в качестве даты по сути евент,?
* как отдавать с сервера сообщение присланное одним пользователем, всем пользователям?
Что у меня сейчас есть:
Клиент:
const {
RSocketClient,
JsonSerializer,
IdentitySerializer,
encodeRoute
} = require('rsocket-core');
const RSocketWebSocketClient = require('rsocket-websocket-client').default;
const WebSocket = require('ws');
function connect() {
return new RSocketClient({
serializers: {
data: JsonSerializer,
metadata: IdentitySerializer
},
setup: {
keepAlive: 60000,
lifetime: 180000,
dataMimeType: 'application/json',
metadataMimeType: 'message/x.rsocket.routing.v0',
},
transport: new RSocketWebSocketClient({
url: 'ws://localhost:8080/tweetsocket',
wsCreator: (url) => {
return new WebSocket(url)
}
}),
})
.connect();
}
const client = connect()
client.subscribe({
onComplete: socket => {
socket.requestChannel({
data: Buffer(JSON.stringify(createAndSendMessage())),
metadata: encodeRoute('chat')
}).subscribe({
onComplete: () => console.log('complete'),
onError: error => {
console.log(error);
},
onNext: payload => {
createAndDrawMessage()
},
onSubscribe: subscription => {
subscription.request(2147483647);
},
});
},
onError: error => {
console.log(error);
},
onSubscribe: cancel => { }
});
class Message {
sender
text
date
constructor(sender, text, date) {
this.sender = username
this.text = password
this.date = date
}
}
Сервер:
@Controller
public class SetUpController {
@ConnectMapping("chat")
public Mono<Void> handleSetUp(RSocketRequester requester, @Payload String token) {
ControllerUtils.tokenRSocketRequesterMap.put(token, requester);
return Mono.empty();
}
}
@Controller
public class ChatController {
protected JwtService jwtService;
@ConnectMapping("chat")
public Mono<Void> sendMessageForAll(Mono<Message> message) {
message.doOnNext(m -> ControllerUtils.tokenRSocketRequesterMap
.values()
.forEach(requester -> requester
.route("chat")
.data(message, Message.class)
.send()));
return Mono.empty();
}
}