Closed marinavelvet closed 1 year ago
Issue: Unable to Subscribe to Multiple Topics with SockJS Client
Solution:
To resolve the problem of not being able to subscribe to 'initial/queue' and 'dashboard/livestream' topics with SockJS Client, make the following changes in the code:
sendMessage = () => {
if (this.clientRef && this.clientRef.state && this.clientRef.state.connected) {
this.clientRef.sendMessage('/queue/initial', {}); // Change the topic to '/queue/initial'
}
};
In the render method, ensure that you are subscribing to both topics:
render() {
const { initialDataReceived, clientConnected } = this.state;
return (
<div>
{clientConnected && (
<SockJsClient
url="your_websocket_url_here" // Replace with your actual WebSocket URL
topics={['/queue/initial', '/dashboard/livestream']} // Subscribe to both topics here
onMessage={(msg) => this.handleMessage(msg)}
ref={(client) => { this.clientRef = client; }}
onConnect={() => { this.sendMessage(); }}
onDisconnect={this.handleDisconnect}
debug={true}
/>
)}
</div>
);
}
Remember to replace "your_websocket_url_here" with the correct WebSocket URL that connects to the backend server.
By implementing these changes, the SockJS Client should now successfully subscribe to both topics and receive messages accordingly.
If you encounter any further issues, feel free to ask for more assistance!
Thank you for your answer. I've tried doing what you suggested and it still reads/shows only '/topic/livestream'. Can it maybe really be the backend problem or is there some issue with the library? I'm getting this message from console: id:sub-0
Also, this is the Vanilla JS code that manages to subscribe to those topics, but it seems that SockJS library doesn't have the methods proposed here, like 'subscribe'. I'm posting it as it may be of some help:
var stompClient = null;
window.onload = connect();
function setConnected(connected) { $("#connect").prop("disabled", connected); $("#disconnect").prop("disabled", !connected);
// Hides whole #conversation table. Commented so data stays on page after disconnect.
// if (connected) { // $("#conversation").show(); // } // else { // $("#conversation").hide(); // }
// Deletes transactions. Commented so data stays on page after disconnect.
// $("#transactions").html(""); }
function connect() { var socket = new SockJS('/register'); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/echo', function (echo) { showEcho(JSON.parse(echo.body).response); }); stompClient.subscribe('/topic/livestream', function (statistics) { showStatistics(JSON.parse(statistics.body)); }); stompClient.subscribe('/user/queue/initial', function (statistics) { showStatistics(JSON.parse(statistics.body)); });
console.log('Before send to livestream');
// Send message to livestream to get initial data
stompClient.send("/dashboard/livestream", {}, "");
console.log('Sent to livestream');
});
}
function disconnect() { if (stompClient !== null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); }
function sendName() { stompClient.send("/dashboard/echo", {}, JSON.stringify({'request': $("#name").val()})); console.log('Sent to echo'); }
function showEcho(message) { $("#transactions").prepend("
function showStatistics(message) {
console.log("Message:" + message);
if (message.totalNGCs !== null) {
document.getElementById("circulating_supply").innerHTML = message.totalNGCs;
}
if (message.dashboardFiguresData !== null) {
document.getElementById("number_of_addresses").innerHTML = message.dashboardFiguresData.numberOfAddresses;
document.getElementById("average_per_address").innerHTML = message.dashboardFiguresData.averageAmountPerAddress;
}
if (message.dashboardTransactionDataQueue !== null) {
dtdq = message.dashboardTransactionDataQueue;
dtdq.forEach(dtd => {
$("#transactions").prepend("<tr><td>" + dtd.date + "</td>"
+ "<td>" + dtd.transactionId + "</td>"
+ "<td>" + "From: " + dtd.fromSerial + "<br>To: " + dtd.toSerial + "</td>"
+ "<td>" + dtd.amount + "</td></tr>");
})
}
}
$(function () { $("form").on('submit', function (e) { e.preventDefault(); }); $( "#connect" ).click(function() { connect(); }); $( "#disconnect" ).click(function() { disconnect(); }); $( "#send" ).click(function() { sendName(); }); });
Noted that I can't use this code because I need to rewrite in for React framework. Any help is much appreciated.
This issue is solved by adding componentDidUpdate method, so now the code looks like this:
class TableDataStream extends React.Component {
constructor(props) {
super(props);
this.state = {
clientConnected: false,
messages: [],
data: [],
circulatingSupply: '',
figures: ''
}
}
sendMessage = () => {
if (this.clientRef && this.clientRef.state && this.clientRef.state.connected) {
this.clientRef.sendMessage("/dashboard/livestream", {});
}
}
componentDidMount = () => {
this.setState({ clientConnected: true});
}
componentDidUpdate = () => {
if (this.state.clientConnected === true && this.clientRef && this.clientRef.state && this.clientRef.state.connected) {
this.clientRef.sendMessage("/dashboard/livestream", {});
this.setState({ clientConnected: false});
}
}
handleMessage = (event) => {
this.props.handleEvents(event);
}
handleDisconnect = () => {
console.log('SockJSClient is disconnected');
}
render() {
return (
<div>
<SockJsClient
url={window.ENVIRONMENT.REACT_APP_BACKEND_SERVICE_LOCATION + "/register"}
topics={["/user/queue/initial", "/topic/livestream"]}
onMessage={(msg) => { this.handleMessage(msg); }}
ref={(client) => {this.clientRef = client;}}
onConnect={() => {
this.setState({ clientConnected: true});
this.sendMessage();}}
onDisconnect={this.handleDisconnect}
debug={true}
/>
</div>
);
}
}
export default TableDataStream;
This issue is solved by adding componentDidUpdate method, so now the code looks like this:
class TableDataStream extends React.Component {
constructor(props) {
super(props);
this.state = {
clientConnected: false,
messages: [],
data: [],
circulatingSupply: '',
figures: ''
}
}
sendMessage = () => {
if (this.clientRef && this.clientRef.state && this.clientRef.state.connected) {
this.clientRef.sendMessage("/dashboard/livestream", {});
}
}
componentDidMount = () => {
this.setState({ clientConnected: true});
}
componentDidUpdate = () => {
if (this.state.clientConnected === true && this.clientRef && this.clientRef.state && this.clientRef.state.connected) {
this.clientRef.sendMessage("/dashboard/livestream", {});
this.setState({ clientConnected: false});
}
}
handleMessage = (event) => {
this.props.handleEvents(event);
}
handleDisconnect = () => {
console.log('SockJSClient is disconnected');
}
render() {
return (
<div>
<SockJsClient
url={window.ENVIRONMENT.REACT_APP_BACKEND_SERVICE_LOCATION + "/register"}
topics={["/user/queue/initial", "/topic/livestream"]}
onMessage={(msg) => { this.handleMessage(msg); }}
ref={(client) => {this.clientRef = client;}}
onConnect={() => {
this.setState({ clientConnected: true});
this.sendMessage();}}
onDisconnect={this.handleDisconnect}
debug={true}
/>
</div>
);
}
}
export default TableDataStream;
Hi, I can't get SockJS Client to subscribe to the 'initial/queue' and 'dashboard/livestream' topic. I only get 'topic/livestream', no matter what I do. Here is my code snippet, and also a reminder that in the backend everything is configured fine, so the problem is somewhere either in this logic or in SockJs library. Please help!
import React from 'react'; import SockJsClient from 'react-stomp';
class TableDataStream extends React.Component { constructor(props) { super(props); this.state = { clientConnected: false, messages: [], data: [], circulatingSupply: '', figures: '', initialDataReceived: false }; }
componentDidMount() { this.setState({ clientConnected: true }); }
componentWillUnmount() { this.setState({ clientConnected: false }); }
sendMessage = () => { if (this.clientRef && this.clientRef.state && this.clientRef.state.connected) { console.log(this.clientRef); console.log(this.clientRef.state); console.log(this.clientRef.state.connected); this.clientRef.sendMessage('/dashboard/livestream', {}); } };
handleMessage = (event) => { if (event.topic === '/queue/initial') {
this.setState({ initialDataReceived: true }); } this.props.handleEvents(event);
};
handleDisconnect = () => { console.log('SockJSClient is disconnected'); };
render() { const { initialDataReceived, clientConnected } = this.state;
return (
);
} }
export default TableDataStream