Meteor client disconnected event on server - javascript

Simple question, maybe simple answer: how do I know on the server that a certain client has disconnected? Basic use case: the serve would need to know if a player has dropped the connection.

In the publish function, you can watch socket close event as follows.
this.session.socket.on "close", -> # do your thing

Meteor.publish("yourPublishFunction", function()
{
var id = this._session.userId;
this._session.socket.on("close", Meteor.bindEnvironment(function()
{
console.log(id); // called once the user disconnects
}, function(e){console.log(e)}));
return YourCollection.find({});
});

I've created a pretty comprehensive package to keep track of all logged-in sessions from every user, as well as their IP addresses and activity:
https://github.com/mizzao/meteor-user-status
To watch for disconnects, you can just do the following, which catches both logouts and browser closes:
UserStatus.on "sessionLogout", (userId, sessionId) ->
console.log(userId + " with session " + sessionId + " logged out")
You can also check out the code and do something similar for yourself.

Maybe (in the server code)
Meteor.default_server.sessions.length
or
Meteor.default_server.stream_server.open_sockets.length

you can do one thing make a event on server and call it from browser with ajax which call after some small time interval settimeinterval using with session values into header and if server din`t get request from user it means he dropped connection

Related

SignalR multi user live chat desynchronisation

I have a live chat in which multiple people would be connected simultaneously. All public messaging works fine, but sometimes private messaging to a specific id doesn't work. I believe i narrowed it down to when people disconnected and reconnected that they connected to a different instance (perhaps IIS had recycled and started a new hub).
I thought I had fixed it, but I haven't and now I'm here because I'm stuck. What I thought would fix it was changing the connection variable within the startChat() function to refresh it with the correct information.
This is a cut down version of the code, as I didnt thing the rest would be necesary.
Issue is that when connected to signalR recipients of a message directly to them doean't come through, even though the chat Id it's being sent to it correct. Possible hub/socket mismatch?
var chat = $.connection.chatHub;
$(document).ready(function () {
// Start the chat connection.
startChat();
//restart chat if disconnected
$.connection.hub.disconnected(function () {
setTimeout(startChat(), 5000);
});
$.connection.hub.error(function (error) {
$('#messagebar').html('Chat ' + error + '. If this message doesn\'t go away, refresh your page.');
});
chat.client.addToChat = function (response) {
$('#chat-' + response.Type).prepend(response.Message);
};
});
function startChat() {
chat = $.connection.chatHub;
$.connection.hub.start().done(function () {
//get recent chat from db and insert to page.
//also saves user's chat id to their user for lookup when private messaging
$.ajax({
method: 'POST',
url: '/api/Chat/SetupChat/'
});
$('#messagebar').html('Connected to chat.');
});
}
Any help appreciated, Thanks.
Not sure exactly how your message is going missing, but you should send messages to a User instead of by connection id. This way you be able to identify on the server that a User has at least one connection, and send messages to all connections for that User. if a given connection id is no longer valid, but another one is (because the client has refreshed the page for example) the message wont be lost.
From the docs https://learn.microsoft.com/en-us/aspnet/core/signalr/groups:
The user identifier for a connection can be accessed by the
Context.UserIdentifier property in the hub.
public Task SendPrivateMessage(string user, string message)
{
return Clients.User(user).SendAsync("ReceiveMessage", message);
}
Not sure how this relates exactly to your server code, but you could add it if you're unclear how to progress.

How to close connection to sse flux with javascript-client?

I build a server-send-event endpoint with spring webflux. My javascript app subscribes to that endpoint and receives the published events correctly. BUT when call
EventSource.close() it seems the publisher is not informed that the client closed the connection.
Hence, the publisher is still thinking that there is a subscription, and publishes events to that.
The event stream is potentially never ending, so I never get a complete signal on the publisher side, which means the client has to close the connection.
I think that this happens because the close() call can't reach the underlying flux.
Do you have any solution or workaround for this problem?
#GetMapping(value = INSTANCE_UPDATE_ENDPOINT + "/{dealId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<InstanceUpdatedQuery>> getInstanceUpdateEventStreamForDeal(#PathVariable final String dealId) {
return this.instanceUpdatedApplicationEventFlux
.filter(instanceUpdatedEvent -> instanceUpdatedEvent.getDealId().equals(dealId))
.map(instanceUpdatedEvent -> ServerSentEvent.<InstanceUpdatedQuery>builder()
.id(instanceUpdatedEvent.getId())
.retry(Duration.ofSeconds(1))
.data(new InstanceUpdatedQuery(instanceUpdatedEvent))
.build())
}
You should add a handler to catch the doOnNext(Signal) and then detect the close signal and respond to it

strophe.js, I use attach() to restore a Bosh session but get 'Status' ATTACHED to CONNFAIL and to DISCONNECTED

I use strophe.js to build a simple IM(web).
I have 2 pages:index.html(for login) and myChat.html(main chat view).
And when I login to openfire server by jid and password in index.html
connection = new Strophe.Connection(BOSH_SERVICE);
connection.connect($("#inputName").val()+"#openfireserver", $("#inputPassword").val(), onConnect);
Then I save jid,sid,rid in COOKIE in callback 'onConnect', and go to myChat.html
if (status == Strophe.Status.CONNECTED) {
console.log("success");
connected = true;
$.cookie('jid', connection.jid);
$.cookie('sid', connection._proto.sid);
$.cookie('rid', connection._proto.rid);
location.href='myChat.html';
}
In myChat.html, I use connection.attach() to restore the BOSH session.
var jid=$.cookie('jid');
var sid=$.cookie('sid');
var rid=$.cookie('rid');
connection = new Strophe.Connection(BOSH_SERVICE);
connection.attach(jid,sid,parseInt(rid,10)+1,onConnectAttach);
At first, in callback 'onConnectAttach', the status==Strophe.Status.ATTACHED,
but wait 1-3 mins, status will turn into Strophe.Status.CONNFAIL and Strophe.Status.CONNECTED!
If I use connection.connect() to re-connect the server, it will keep session all the time.
So I can not understand where I make the mistake? Why the status will change after I use attach()?
Got it.
connection.attach(jid,sid,parseInt(rid,10)+1,onConnectAttach);
It's wrong, because I look through some questions about "attach" function and I find someone say that 'rid' must be added one.
But, by my test, I don't need to do that.just:
connection.attach(jid,sid,rid,onConnectAttach);

how to my receiver is typing a message and show on my browser

i want to check the user is typing a message and want to display it in my chat box, i know setting database flag and checking it by timeinterval function, but i think it should be slow method, is there any way to check it? by the users's machine ip/id .
Hi Use Websocket for this
use this link this will help you
https://www.sanwebe.com/2013/05/chat-using-websocket-php-socket
You can implement web sockets on your server, so you can pass events between your clients and server.
you can check Ratchet: http://socketo.me/ for php or Socket.io for Nodejs.
Than you can bind on "keyup" an event to notify server of typing, i suggest to throttle the events so you wont end with too many request :)
i think socket.io is what you looking for http://socket.io/get-started/chat/
I have found that using sockets is the only good solution for achieving that. https://wisembly.github.io/elephant.io/ .
PHP server side:
use ElephantIO\Client as Elephant;
$elephant = new Elephant('http://localhost:8000', 'socket.io', 1, false, true, true);
$elephant->init();
$elephant->send(
ElephantIOClient::TYPE_EVENT,
null,
null,
json_encode(array('name' => 'foo', 'args' => 'bar'))
);
$elephant->close();
echo 'tryin to send `bar` to the event `foo`';
Socket.io server side:
var io = require('socket.io').listen(8000);
io.sockets.on('connection', function (socket) {
console.log('user connected!');
socket.on('foo', function (data) {
console.log('here we are in action event and data is: ' + data);
});
});

Removing someone from a user hash on navigating away from a page / page close

I'm building a Node.js / Socket.io project.
I have a hash of Users based on their websocket id. When a user makes the following request i'd like to add them to a group of users viewing that page.
app.get('/board/:id', function(req, res){}
I'd like to keep something like
Browsing = {
username : id,
username : id,
...
}
However i'm unsure how to remove a user lets say if they navigate off the page. Is there some kind of function that gets called upon page leave?
Partial Solution:The following seems to do the trick on Chrome:
$(window).unload(function(){
var username = $('#username').text();
var pid = currentProject;
var data = {
username: username,
id : pid
}
socket.emit('leaving-page', data);
})
... Is there some kind of function that gets called upon page
leave? ...
Yes, but it is not reliable.
The way the people keep track of who is online and who isn't, is usually like this:
Add the time when the user last refreshed/visited a page
set a limit to you consider them offline
You could intercept the event which corresponds to leaving a page. There are several ways to do it, have a look at the following links and let me know if any suits your needs and if I can answer any more explicit questions about them:
Intercept page exit event
Best way to detect when a user leaves a web page?
jquery unload
with the last link you could do something like this:
$(window).unload(function() {
//remove the user from your json object with delete json_object[key];
});
Hope this helps.
Since you're using Socket.io, the server will know when the user has left the page because the socket will be disconnected. Simply listen for the disconnect event.
io.sockets.on('connection', function (socket) {
...
socket.on('disconnect', function () {
// The user on `socket` has closed the page
});
});
Better yet, take advantage of namespaces and let Socket.io handle all of the connection/disconnection (it's doing it anyway -- no need to duplicate effort).
On the client,
socket = io.connect('http://example.com/pagename');
pagename need not point to a valid URL on your domain – it's just the namespace you'll use in the server code:
io.sockets.clients('pagename')
Gets you all of the clients currently connected to the pagename namespace.

Categories