Disconnect node-xmpp client - javascript

I am looking at node-xmpp and node-simple-xmpp and I am trying to make a simple client.
Everything works fine, except the disconnect.
I have made the following file after the example of simple-xmpp:
var xmpp = require('simple-xmpp');
xmpp.on('online', function() {
console.log('Yes, I\'m connected!');
xmpp.send('test2#example.com', 'Hello test');
// OK UNTIL HERE, DISCONNECT NOW
});
xmpp.connect({jid: 'test#example.com/webchat', password: 'test', reconnect: 'false'});
But I don't know how to disconnect. I tried to send a stanza with unavailable type:
stanza = new xmpp.Element('presence', {from: 'test#example.com', type: 'unavailable'});
xmpp.conn.send(stanza);
delete xmpp;
This is causing the client to go temporarily offline, but the problem is, it reconnects after a few seconds and keeps sending 'presence' stanza.
I have also tried calling xmpp.conn.end(), which also disconnects but it gives an error afterwards:
node_modules/simple-xmpp/node_modules/node-xmpp/lib/xmpp/connection.js:100
if (!this.socket.writable) {
^
TypeError: Cannot read property 'writable' of undefined
So, what am I doing wrong? I am sure there is an easy way to disconnect.

In the first case, <presence type='unavailable'/> does not always actually disconnect you; in your server, it looks like it might be, but your client is auto-reconnecting. delete xmpp is not actually causing your object to be cleaned up, it's just removing it from the local namespace.
In the second case send() isn't writing your stanza to the underlying socket immediately. If you close the socket with end() right afterwards, the socket is closed when the write actually happens.
If you add a short timeout after you call send(), before calling end() it will work. To make it good, you'll want your library developers to give you a callback when send() has actually written to the socket.

You should also check this out https://www.rfc-editor.org/rfc/rfc7395
In short if client is using to open connection it should use to kill that same connection.
To be more precise:
<close xmlns="urn:ietf:params:xml:ns:xmpp-framing" />
Solution of "Joe Hildebrand" also solved my problem, but this seemed more proper way for me.

Related

Socket.io kick specific user

I have an event from the client side that passes the socket id to be kicked to the server, socket.emit('kick', socketId);.
My intention is to find the socket using this socketId server side, and then call socketToBeKicked.disconnect(). How do I find the specific socket? I tried looking at other posts but most of the solutions do not work anymore. Or is there a better way that I can implement the kick function?
I figured out a solution. Instead of trying to find the socket obj on the server side, we can emit an event from the server to the client to that is going to get kicked and emit another event back to the server to get the client's socket obj.
client.js
socket.emit('kick', socketId); // sent by the host
socket.on('kick helper', () => { // sent by the user getting kicked
socket.emit('kick helper');
}
server.js
socket.on('kick', (socketId) => {
socket.to(socketId).emit('kick helper');
}
socket.on('kick helper', () => { // now this socket obj is the user getting kicked
socket.disconnect();
}
It still feels like quite a long way around to get the socket object of the user to be kicked. Please share if you have a better solution, I would love to know!

No ACK recieved in Gun.js

I am using Gun.js and on load I am putting a value in.
This is for a new website, and I have already tried making everything when the page loads instead of just in a script tag.
var mid = Date.now().toString() + "and" + (Math.round(Math.random()) + Math.round(Math.random())).toString();
var gun = Gun('https://gunjs.herokuapp.com/gun');
gun.get(`tictac/toe${mid}`).put({
"type": "test"
});
I expect it not to produce an error, but it is producing an error:
{err: "Error: No ACK received yet.", lack: true}
I don't know what to do.
#Mikey ,
No ACK received yet lack: true means that GUN has not received an acknowledgement that the data was correctly saved. This means your data may not be backed up.
Often times this happens because on other peers someone is running GUN as require('gun/gun') which does NOT include default storage adapters. On other (non-browser) peers, you should include GUN as require('gun') which DOES include default adapters (transport, storage, etc.).
In this case, it looks like you are connected to a testing peer (gunjs.herokuapp), please note that this is not for production use cases, and could be part of the problem.
For us to figure out what is going wrong, I highly encourage you to join our super friendly community ( https://gitter.im/amark/gun ) to help you out.

How to keep a websocket connection in OPEN readystate after send?

I am new to websockets.
In my setup I have a trivial websocket server written in Go (playground)
I make a WebSocket object, set up its onmessage callback and call its send method to test.
var w = new WebSocket("ws://localhost:12345/echo")
w.onmessage = (msg) => {
console.log(msg.data)
}
w.onopen = () => {
w.send("Hello") // this fires OK
}
What I expect to happen based on the server code is to receive the "Hello" message and to keep sending "yahoo" every 1.5s to the client. What actually happens is "Hello" is sent, but none of the "yahoo"'s make it thru. It seems somewhere along the WebSocket.readystate becomes 3 (CLOSED).
To clarify, the server receives and prints "Hello" then actually fires a "yahoo" message every 1.5s, but the connection is closed by then so the onmessage callback never fires.
Am I missing or misunderstanding anything?
EDIT: Ran across comparison github.com/gorilla vs. golang.org/x/net, claims golang.org/x/net websocket implementation does not support pong. This may be the confirmation of it.
EDIT: Package golang.org/x/net/websocket closes the websocket connection when the handler ServeHTTP function returns. By default a websocket connection is tied to an instance of the handler.
When the handler function returns, in your case EchoServer the socket will be automatically closed by the http framework.
Since you start a go routine for the loop writing the yahooresponse to the client the EchoServer function will terminate (and therefor closing the socket) before it has time to send a response.
The solution is to remove the spawning of the go routine and just do the loop inside the EchoServer.

Meteor client disconnected event on server

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

JSJaC + Openfire: no connection with some users

ok, I'm finally at my wits' end. I have a have an XMPP server (Openfire) running, and trying to connect via JavaScript using JSJaC. The strange thing is that I can establish a connection for some users, but not for all. I can reproduce the following behavior: create two accounts (username/password), namely r/pwd and rr/pwd with the result:
r/pwd works
rr/pwd doesn't work.
So far, each account with a user name consisting of only one character works. This is strange enough. On the other side, old accounts, e.g., alice/a work. The whole connection problem is quite new, and I cannot trace it to any changes I've made.
And to make my confusion complete with any instant messenger supporting XMPP, all accounts work, incl., e.g., rr/pwd. So assume, the error must be somewhere in my JavaScript code. Here's he relevant snippet:
...
oArgs = new Object();
oArgs.domain = this.server;
oArgs.resource = this.resource;
oArgs.username = "r";
oArgs.pass = "pwd";
this.connection.connect(oArgs);
The code above works, but setting oArgs.username = "rr", and it fails.
I would be grateful for any hints. I'm quite sure that it must be something really stupid I miss here.
Christian
Adding oArgs.authtype = 'nonsasl' to the argument list when creating the xmpp connection using JSJaC solved my problem. I haven't tried Joe's command to alter the SASL settings in Openfire; I'm scared to ruing my running system :).

Categories