I'm trying to re-start the Server sent events after i have stopped it on a button click.
So I stop the event like so:
if(typeof(EventSource)!=="undefined") {
//create an object, passing it the name and location of the server side script
var eSource = new EventSource("mypage.php");
//detect message receipt
eSource.onmessage = function(event) {
//write the received data to the page
document.getElementById("serverData").innerHTML = event.data;
if(event.data !=""){
alert('success');
///Close it here///////////
event.target.close();
}
};
}
else {
document.getElementById("serverData").innerHTML="Whoops! Your browser doesn't receive server-sent events.";
}
Now I need to restart the same SSE like so (if possible at all):
$('#someBtn').click(function(){
//////this is actually my assumption and there is no such a function///
event.target.start();
});
Could someone please advise on this?
Any help would be appreciated.
Related
The websockets server example works as expected. On browser refresh (e.g. S-F5 with chrome), the websocket disconnects, still working as expected. After refresh, the user has to give name again to connect to the server.
How would you capture the refresh-event and keep the user connected? E.g.
Is this doable only on server side or does the client require modifications as well? Haskell examples or links to such would be nice as well as hints on how to do this!
How would you capture the refresh-event...
There isn't really such a thing as a refresh event to detect (I would love to be proved wrong in this!)
... and keep the user connected...
The refresh, or rather, the leaving of the page before loading it again, causes the websocket to disconnect, and (especially if this is the only page on the site that is open), there isn't really much you can do about it.
So the only thing that can be done, is have some sort of auto-reconnect the next time the page loads. A solution that allows this is one where..
when the name is initially entered, the name is saved somewhere in the browser;
when the page reloads, it checks for a previously saved name;
and if it's found, it connects again using that name.
Local storage is one such place to save this, as in the below example, modified from https://github.com/jaspervdj/websockets/tree/master/example to save/retrieve the name from local storage.
$(document).ready(function () {
var savedUser = sessionStorage.getItem("rejoin-user");
if (savedUser) {
joinChat(savedUser);
}
$('#join-form').submit(function () {
joinChat($('#user').val())
});
function joinChat(user) {
sessionStorage.setItem("rejoin-user", user);
$('#warnings').html('');
var ws = createChatSocket();
ws.onopen = function() {
ws.send('Hi! I am ' + user);
};
ws.onmessage = function(event) {
if(event.data.match('^Welcome! Users: ')) {
/* Calculate the list of initial users */
var str = event.data.replace(/^Welcome! Users: /, '');
if(str != "") {
users = str.split(", ");
refreshUsers();
}
$('#join-section').hide();
$('#chat-section').show();
$('#users-section').show();
ws.onmessage = onMessage;
$('#message-form').submit(function () {
var text = $('#text').val();
ws.send(text);
$('#text').val('');
return false;
});
} else {
$('#warnings').append(event.data);
ws.close();
}
};
$('#join').append('Connecting...');
return false;
};
});
... Is this doable only on server side or does the client require modifications as well?
It definitely needs something done in the client to auto-reconnect. The bare bones version above needs no changes to the server, but if you wanted something fancier, like having the cases of initial connect and auto reconnect handled/shown differently somehow, then the server might need to be modified.
I have shiny app and I'm having unload event that display message when user don't save data, but it also shown when R is not running anymore (closed or crashed). Is there a way to detect if shiny app is not connected to the server?
Found in in js events doc, so my code look like this:
var connected = false;
$(document).on('shiny:disconnected', function(event) {
connected = false;
}).on('shiny:connected', function(event) {
connected = true;
});
$(window).unload(function() {
if (connected) {
return "Are you sure?";
}
});
I noticed that whenever my server is offline, and i switch it back online, it receives a ton of socket events, that have been fired while server was down. ( events that are ... by now outdated ).
Is there a way to stop socket.io from re-emitting the events after they have not received a response for x seconds ?.
When all else fails with open source libraries, you go study the code and see what you can figure out. After spending some time doing that with the socket.io source code...
The crux of the issue seems to be this code that is here in socket.emit():
if (this.connected) {
this.packet(packet);
} else {
this.sendBuffer.push(packet);
}
If the socket is not connected, all data sent via .emit() is buffered in the sendBuffer. Then, when the socket connects again, we see this:
Socket.prototype.onconnect = function(){
this.connected = true;
this.disconnected = false;
this.emit('connect');
this.emitBuffered();
};
Socket.prototype.emitBuffered = function(){
var i;
for (i = 0; i < this.receiveBuffer.length; i++) {
emit.apply(this, this.receiveBuffer[i]);
}
this.receiveBuffer = [];
for (i = 0; i < this.sendBuffer.length; i++) {
this.packet(this.sendBuffer[i]);
}
this.sendBuffer = [];
};
So, this fully explains why it buffers all data sent while the connection is down and then sends it all upon reconnect.
Now, as to how to prevent it from sending this buffered data, here's a theory that I will try to test later tonight when I have more time.
Two things look like they present an opportunity. The socket notifies of the connect event before it sends the buffered data and the sendBuffer is a public property of the socket. So, it looks like you can just do this in the client code (clear the buffer upon connect):
// clear previously buffered data when reconnecting
socket.on('connect', function() {
socket.sendBuffer = [];
});
I just tested it, and it works just fine. I have a client socket that sends an increasing counter message to the server every second. I take the server down for 5 seconds, then when I bring the server back up before adding this code, all the queued up messages arrive on the server. No counts are missed.
When, I then add the three lines of code above, any messages sent while the server is down are not sent to the server (technically, they are cleared from the send buffer before being sent). It works.
FYI, another possibility would be to just not call .emit() when the socket is not connected. So, you could just create your own function or method that would only try to .emit() when the socket is actually connected, thus nothing would ever get into the sendBuffer.
Socket.prototype.emitWhenConnected = function(msg, data) {
if (this.connected) {
return this.emit(msg, data);
} else {
// do nothing?
return this;
}
}
Or, more dangerously, you could override .emit() to make it work this way (not my recommendation).
Volatile events are events that will not be sent if the underlying connection is not ready (a bit like UDP, in terms of reliability).
https://socket.io/docs/v4/emitting-events/#volatile-events
socket.volatile.emit("hello", "might or might not be received");
I am trying to connect computer "a" to computer "b" using webrtc and print out the "Click" on computer "b" when the mouse is clicked on computer "a"'s canvas. I already created a working webrtc example where I make a connection between computer "a" and "b" and send messages between them using textboxes(chat).
I know to Attach a click event to the document. When the user clicks anywhere in the document, output "Click" will be displayed.
document.addEventListener("click", function(){
message.value= "Click!";
});
And these are some of the webrtc functions I have, I didnt post all my webRTC functions because I dont wanna make the question longer, it already is.
// a nice wrapper to send data
function send (room, key, data) {
roomRef.child(room).child(key).set(data);
}
// wrapper function to receive data
function recv (room, type, cb) {
roomRef.child(room).child(type).on("value", function (snapshot, key) {
var data = snapshot.val();
if (data) { cb(data); }
});
}
// get references to the document tags
var chatlog = document.getElementById("chatlog");
var message = document.getElementById("message");
function bindEvents () {
channel.onopen = function () { console.log("Channel Open"); }
channel.onmessage = function (e) {
// add the message to the chat log
chatlog.innerHTML += "<div>Peer says: " + e.data + "</div>";
};
}
// send a message the textbox throught
// the data channel for a chat program
function sendMessage () {
var msg = message.value;
channel.send(msg);
message.value = "";
}
My question is I dont know how to connect these two codes together or even if i did, I am not sure if it would work. So my question is how can I click on the canvas on computer "a" and get the textbox to print out "Click" on computer "b".
Thanks for reading
You could look into node.js and socket.io.
With these two you could connect multiple clients together and have a real-time communication between them. Other alternative is to use ajax with php, and make one browser to poll for new commands from server, and other browser to send them to server.
You're mostly there. What you can do is, after setting the message.value property, is call the sendMessage() function. This should trigger the application to send the correct value through the WebRTC Connection.
Is there a way to get notified if a certain send() has finished? As i noticed the send() function is not blocking and the code continuous. Is there a simple way to either make it blocking or getting somehow notified if the send is finished?
You could rely on Socket.bufferedamount (never tried)
http://www.whatwg.org/specs/web-apps/current-work/multipage/network.html#dom-websocket-bufferedamount
var socket = new WebSocket('ws://game.example.com:12010/updates');
socket.onopen = function () {
setInterval(function() {
if (socket.bufferedAmount == 0){
// Im' not busy anymore - set a flag or something like that
}
}, 50);
};
Or implement an acknowledge answer from the server for every client message (tried, works fine)