xmpp - ping pong - xmpp

So in order to know if there's still an active data connection, I'm sending a ping every like 5 minute interval, and waiting for the server to respond. So basically, I'm using the iq id as a key on this pinging method. I'll send a ping, and store the iq id, and i'll say assume that noDataConnection = true. Now, if I receive a pong with the same iq id, I assume that the connection is alive, so I'll set noDataConnection = false. However, if there's no data connection, i'll continue to send pings setting noDataConnection = true, and never receiving any so it will remain true unless it recovers and obtained a data connection.
Excerpt from http://xmpp.org/extensions/xep-0199.html#s2c:
PING:
<iq from='juliet#capulet.lit/balcony' to='capulet.lit' id='c2s1' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
PONG:
<iq from='capulet.lit' to='juliet#capulet.lit/balcony' id='c2s1' type='result'/>
My only concern about this, is what if I received an iq that isn't a result of my ping and my application will assume that noDataConnection = true, since the iq id that it receives doesn't match up to my ping iq id that is sent. Is there a way to know if the iq that I received is a result of my ping?
Thanks.

My solution is to prefix the iq id that i've sent with a text "ping", so basically if i received an iq prefix with "ping", then it is the pong of my ping.

Related

Reliable Message Delievery XMPP

In some of the cases server is not able to determine the state of the client at socket level, some of the time, user is not connected to the server because of connection drop the socket return success. Some of the message get drop, how can we overcome this issue.
Client c1 send message to Server S1 server send message to the Client2 c2, we can only determine the state of client connection on socket send if it returns success we can assume that the client is alive and the message has been successfully sent. However some time message get drop because the connection was no more and socket is not able to predict? how can overcome this problem.
socket m_Sock;
m_Sock.BeginSend(byteData, 0, byteData.Length, 0, out errCode, SendCallback, null
if error code is success we assume that the message has been successfully sent to this client how ever it does not notify immediately after the connection has been drop, after copule of seconds expected error code get return in this interval we lost messages
if(errCode == SocketError.Success)

UDP multiple client receiving from same source

I have a question where 2 or more client on host A try to receive from host B with exactly the same address and port number.
Suppose we have host A and there are 2 thread running on it. A.thread_a sends a packet to B port xxxx. Then it does recvfrom(B, xxxx). At the same time, A.thread_b does the same recvfrom() call with same IP and port number. B, after receiving request from A.thread_a, sends data by sendto(A, yyyy). Who would receive the response, A.thread_a or A.thread_b?
If you want to multiplex message-streams from multiple threads, you should put some sort of originator-ID in the message and have the peer return it in the response. – Martin James

How to send Udp packet 2 or 3 times after failed received packet in java?

I have send Udp packet to the Server. If the server is OK then I can receive the response packet nicely but when the server is down then I did not get any response packet. Anybody can help me that how can I send my packet to server multiple time when fail to receive the response packet. Moreover, want to keep alive the connection with server. Thanks in advance.
Well,
After you've sent the packet, you wait for the ACK (response) package from the server. You could use the DatagramSocket.setSoTimeout() to an appropriate time, if you get the Timeout Exception increment a counter, if that counter is less than 2/3 send the packet again and repeat these steps. If the counter is bigger than 2/3 the server is down, just quit.
According to Java documentation, receive will block until a package is received or a timeout has expired.
To keep the connection alive you need to implement a ping-pong. In another thread of your program, you send a Keep-Alive packet (any small packet will do) and wait for a response. I suggest using a different port number for this purpose so that these packets won't mess up with the normal data packets. These packets can be send every 2 seconds o 2 minutes depends on your particular needs. When the thread receives the ACK packet it will update a private time variable with the current time, for example:
lastTimeSeen = System.currentTimeMillis();
put a method in your thread class to access the value of that variable.

xmpp : handling incoming messages asynchronous

I am trying to write an implementation of XMPP client (no BOSH, direct TCP connection).
trying to figure out how to handle incoming messages in response to my own requests and to know which response relates to which request, most protocol tag the request with some unique id and the server sends that id with the response.
I have seen an ID parameters for IQ stanzas but they are reported to identify a session and not a unique message...
what is the best way to handle this issue ?
The ID attribute in IQ stanzas bind a request (get or set) to a response (result or error). For each request, a new ID should be used. That's the way to track responses for each request.
The new RFC 6120 has a good description of how IQs work. Make sure that you're matching both the sender and the id of the received stanza to ensure that someone else isn't guessing your id numbers. The typical pattern is to use a IQtracker, which you call like this (pseudo-code):
iq = create_xml_dom_that_is(<iq id='[counter++]' type='get' to='receiver'/>)
track(iq, callback)
where callback gets called when the we receive an iq stanza from the receiver with the expected id, or when some timespan has been reached without getting a response.

XEP-0124 / BOSH: Omit ACK in response

I'm reading the XEP-0124 / BOSH specification and do not understand the following sentence in chapter 9.1 Request Acknowledgements:
The only exception is that, after its
session creation response, the
connection manager SHOULD NOT include
an 'ack' attribute in any response if
the value would be the 'rid' of the
request being responded to.
In my words: I should not send an ACK if the respond is dedicated for the last and only request (in connection manager's queue).
But: There is a client with it's own state machine. Maybe the client already send a second request -- where the first one is not replied -- and expect to get two answers. In this case the client except a ACK with RID of the "older" request and the connection manager have to set ACK.
Conclusion: The connection mananager MUST set ACK as long multiple requests are allowed.
I'm not sure, but is this text paragraph dedicated only for the use case where no further request is send by the client but the session creation phase is finished successfully and the connection manager have to send "ping" messages to the client due to "wait" timeouts ?
So, as I read it:
If the highest RID (in sequence) that you have received is 11 (you might have received 14 after that, but it is out of sequence since 12 & 13 are missing), and you are responding on:
The same request, then you should not (it is recommended that you do not, but if you have a good reason to, then you may) send an 'ack' attribute.
An earlier held request (say RID 10) then you should set 'ack' to 11 since that is the highest in-sequence RID that you have received so far.
It's okay if the client sent multiple requests and the server doesn't yet know about them. This is because there is a chance that when the client sent 11, the server has no held connections and it will respond back on the same connection. In that case, there are 2 requests sent out (11 & 12), but the response for each one acks that same request since the server always has something to send back immediately.