Server Sent Events: JavaScript events not working - javascript

I have written a small piece of code for generating server sent events and a corresponding JavaScript client to log all the messages. When i send the request, I can see in network tab of chrome that browser is receiving all the messages from server but in JavaScript only open event listener is triggered and message listener is never triggered. I have spent good amount of time on this without any success.
Here is my Java code which generates SSE:
#GET
#Path("/updates/sse")
#Produces(MediaType.SERVER_SENT_EVENTS)
public void publishUpdates(#Context SseEventSink sseEventSink) {
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
final OutboundSseEvent event = sse.newEventBuilder()
.name("message-to-client")
.data(String.class, "Hello world " + i + "!")
.build();
sseEventSink.send(event);
}
}).start();
}
Here is my JavaScript code to handle response:
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("/gra/services/updates/sse");
source.addEventListener('message', function(e) {
console.log("message");
console.log(e.data);
}, false);
source.addEventListener('open', function(e) {
// Connection was opened.
console.log("open");
}, false);
source.addEventListener('error', function(e) {
console.log("error");
console.log(e);
if (e.readyState == EventSource.CLOSED) {
// Connection was closed.
}
}, false);
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
Here is what I get in console in chrome. Only open listener is invoked:
and here is what I can see in Network tab in chrome:
I am trying to figure out if browser is receiving the event data why message listener is not being invoked.

See the example in documentation for EventSource:
/* The event "message" is a special case, as it
* will capture events without an event field
* as well as events that have the specific type
* `event: message` It will not trigger on any
* other event type.
*/
sse.addEventListener("message", function(e) {
console.log(e.data)
})
Your message type is message-to-client, not "nothing".

Related

JavaScript beforeunload event fails to fire in Chrome

There are many discussions of the Window: beforeunload event on Stack Overflow.
My specific problem is that my beforeunload event is not being called when a user closes a tab in Chrome (v91.0.) if the page is processing other JavaScript.
Is there anyway to guarantee the firing of the beforeunload event?
Specifically what I am trying to do is when a user closes a tab or the browser the beforeunload event is called and that listener function makes a call to another function that makes an Ajax call to an action class that signals the server that the user is no longer active (and resources can be released); maybe there is a better way to do this.
Here is the code for the listener:
window.addEventListener('beforeunload', function (e) {
setExternalUserStatus(false);
});
Here is the code for the AJAX call :
function setExternalUserStatus(externalUserStatus) {
if (!xmlhttpLogger) {
createXMLHttpRequestLogger();
}
xmlhttpLogger.open("POST", "../../geospatial/setExternalUserStatus.action?externalUserStatus=" + externalUserStatus);
xmlhttpLogger.setRequestHeader("pragma", "no-cache");
xmlhttpLogger.setRequestHeader("Cache-Control", "no-cache,max-age=0");
xmlhttpLogger.send(null);
xmlhttpLogger.onreadystatechange = function () {
if (xmlhttpLogger.readyState === 4) {
if (xmlhttpLogger.status === 200) {
if (xmlhttpLogger.responseText.includes("updated")) {
console.debug("ExternalUserStatus updated.")
} else {
console.debug("ExternalUserStatus NOT updated.")
}
} else {
console.log("Server status: " + xmlhttpLogger.status)
}
}
}
}
Thx in advance.

chrome.runtime.onMessage listener is never fired

I'm trying to set a badge text specific for each tab in Chrome.
I've followed along with this answer https://stackoverflow.com/a/32168534/8126260 to do so, though the chrome.runtime.onMessage event handler is never being fired.
// tab specific badges https://stackoverflow.com/questions/32168449/how-can-i-get-different-badge-value-for-every-tab-on-chrome
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
console.log('runtime message');
if (message.badgeText) {
console.log('runtime message with badge text');
chrome.tabs.get(sender.tab.id, function(tab) {
if (chrome.runtime.lastError) {
return; // the prerendered tab has been nuked, happens in omnibox search
}
if (tab.index >= 0) { // tab is visible
chrome.browserAction.setBadgeText({tabId:tab.id, text:message.badgeText});
console.log('set message');
} else { // prerendered tab, invisible yet, happens quite rarely
var tabId = sender.tab.id, text = message.badgeText;
chrome.webNavigation.onCommitted.addListener(function update(details) {
if (details.tabId == tabId) {
chrome.browserAction.setBadgeText({tabId: tabId, text: text});
chrome.webNavigation.onCommitted.removeListener(update);
}
});
}
});
}
});
// block outgoing requests for help widgets
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
//send message
console.log('send message');
chrome.runtime.sendMessage({badgeText: "HELP"});
if (isDisabled) {
return { cancel: false } // this should return from the function (details) level
} else {
return { cancel: true }
}
},
{urls: [
"a bunch of urls irrelevant to this question"
]},
["blocking"]);
(the entire source code is on https://github.com/bcye/Hello-Goodbye)
Looking into the console of my background script, send message appears, meaning that chrome.runtime.sendMessage({badgeText: "HELP"}); should have been executed.
None of the console.log statements in the onMessage listener get executed though.
Solved it, as #wOxxOm said this is impossible.
Though webRequest passes a tabId in the details dictionary.
This can be used to replicate that.

Chrome extension: sendMessage from content to background getting response from popup

I am trying to send a message from a content script to my background script. When the background receives the message it sends data back to the content script in the callback.
My popup also has a listener for messages from the content script, but does not respond to a message meant for the background script.
Then content is receiving an undefined back from the callback, which I think is caused by the popup receiving the message but not responding.
The reference says:
Note: If multiple pages are listening for onMessage events, only the
first to call sendResponse() for a particular event will succeed in
sending the response. All other responses to that event will be
ignored.
So surely I should only get the response from my background script.
My content script does this:
function notifyReady() {
chrome.runtime.sendMessage({
type: 'ACTIVITY_HISTORY_READY'
},
function (response) {
console.log(">>>>Response: ", response);
if (response.type == 'HISTORY_DATA') {
processLog(response);
}
});
}
My background script listens like this:
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
console.log("received " + msg.type);
if (msg.type = 'ACTIVITY_HISTORY_READY' && historyData) {
if (historyData) {
sendResponse({
type: "HISTORY_DATA",
position: historyData.position,
company: historyData.company
});
historyData = '';
} else {
sendResponse({
type: "NO_DATA"
});
}
}
});
And the listener in my popup is:
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
if (msg.type == 'JOB_DETAILS') {
sendResponse("OK!");
document.getElementById('position').value = msg.position;
document.getElementById('company').value = msg.company;
document.getElementById('url').value = sender.tab.url;
}
});
if (msg.type = 'ACTIVITY_HISTORY_READY' && historyData) {
note that if historyData is falsey you are not sending any response. The else branch of the second if can never be taken.
You should remove historyData from the first if. The popup code has nothing to do with this.

SOCKJS reply upon SOCKET_CREATED event

I am connection through Vertx eventbus (SockJS to my Java based backend. Everything work fine, However, I cannot find a way to send an initial message.
Is there a way to send back data when SockJS bridge receives SOCKET_CREATED to the sockjs browser side?
Thank you.
Taken from their documentation:
if (event.type() == SOCKET_CREATED || event.type() == SOCKET_CLOSED)
{
//...
vertx.eventBus().publish("fromServer", jmsg.toJSONString());
}
Your event instantiation may be different, but that would be how you check for the specific event and run code after it has occurred
You can check this code , where I'm using EventBus.
Here is the Reference code
this.eventBus = new EventBus(this.URL);
this.eventBus.onopen = (e) => {
this._opened = true;
console.log("open connection");
this.callHandlers('open', e);
this.eventBus.publish("http://localhost:8082", "USER LOGIN INFO");
this.eventBus.registerHandler("http://localhost:8081/pushNotification", function (error, message) {
console.log(message.body);
//$("<div title='Basic dialog'>Test message</div>").dialog();
});
}
this.eventBus.onclose = (e) => {
this.callHandlers('close', e);
}
}

emit to all after receiving a broadcast

I've got a little app that generates a code and stores it in mongodb(My chrome browser). Another user(My firefox browser) enters the given code and broadcasts it to let my chrome know that he's there.
Now i want my chrome browser to emit an agreement to itself and my firefox browser so they both get parsed by the same function the moment the agreement is emitted.
The point however is that i only get 1 console log in my terminal which leads me to think that only Chrome(or Firefox, which i doubt) is listening to the emit.
Can anyone take a look why not both browsers receive the 'agreement' emit?
My app.js: (The on connection part)
io.sockets.on('connection', function (socket) {
socket.on('code_game', function (data) {
if (codeToUse == data.code) {
//The receiving end received the proper code from the sending end
console.log(data.secondUser + ' is verbonden via de code: ' + data.code);
//Emit to all parties to let everyone know there's a connection
socket.emit('agreement', {
userOne: {
name: 'Timen',
code: codeToUse
},
userTwo: {
name: data.secondUser,
code: data.code
}
});
}
});
});
And the JS file being called in my view: (sendToFirstUser is Firefox in this case)
var receivingUsersCode = false;
var receivingUsersName = false;
var socket = io.connect('http://localhost');
socket.on('agreement', function (data) {
console.log("hooray");
});
function setReceivingData(code, username) {
receivingUsersCode = code;
receivingUsersName = username;
ding = 'drie';
$('#new_game').css('display', 'block');
$('.theCode').html(receivingUsersCode);
}
function sendToFirstUser(code, username) {
socket.emit('code_game', { code: code, secondUser: username});
}
I'm not sure I understand exactly what you're asking. But it seems to me like you're asking why both your Chrome and Firefox browser aren't emitting an 'agreement' event. If that's it, I think you've answered your own question:
"Another user(My firefox browser) enters the given code and broadcasts it to let my chrome know that he's there."
//Starts broadcasting to other clients
io.sockets.on('connection', function (socket) {
socket.broadcast.emit('code_game', { code: req.body.code, secondUser: req.body.secondUser});
});
Your firefox browser only emits to other clients (your chrome browser) through socket.broadcast.emit. So, only the chrome browser receives the 'code_game' event on the browser side. But in your browser side code, the client emits the 'agreement' event when it receives the 'code_game' event:
socket.on('code_game', function (data) {
if (receivingUsersCode == data.code) {
console.log(data.secondUser + ' is is connected via code: ' + data.code);
listenForMutualConnection();
socket.emit('agreement', {
userOne: {
name: receivingUsersName,
code: receivingUsersCode
},
userTwo: {
name: data.secondUser,
code: data.code
}
});
}
});
Since only the chrome browser is receiving the 'code_game' event, it's also the only one emitting the 'agreement' event.

Categories

Resources