We are using spring-integration for TCP communication, and see behaviour where a TcpConnectionCloseEvent is received just before a message on that connection.
This is a problem because we are using the TCP events to keep track of connections, etc. and it makes for much more complex scenarios when we need to accept messages on connections that we consider closed.
The same is the case the other way around - sometimes we receive a message for a connection that we do not yet know has been opened.
Is there any way to ensure the correct order of these events, even though they are asynchronous in nature?
(Thanks for the great answers here on stackoverflow, Gary).
Hmmm...
On the server side, the open event is published by the thread that accepts the new connection rather than the connection itself. While we could possibly do something there, it still wouldn't be foolproof when using NIO because the threading model there is much more complex and there would be no way to guarantee the order even if the connection itself published the event.
To be honest, we didn't anticipate the events would be used in this way - the primary driver (for the open events) was to allow an application to detect a new connection without the client actually sending anything (just connecting) - allowing a server-side application to accept a new connection, get a handle to the connection id so it can send a welcome message.
One workaround might be to use an event inbound channel adapter and a <delayer/> to delay the event delivery to your application (in the case of the close).
I don't really have a good solution for the late delivery of the open event; perhaps just treat an inbound message for a "new" connection as an "open" event (e.g. publish your own open event when you detect this condition on the thread that's processing the message, and ignore the "real" event).
Related
Say my client code is observing document additions using the added callback mechanism. By design and in perfect conditions, if documents 1,2,3...N are added, client callback should be fired N times.
Now let's say the network connection is lost for periods of time, are there any guarantees/invariants about the number of times that the client added callback will be fired? i.e. can callbacks be logically "lost" due to network issues
Excellent question! I was experimenting with this extensively recently as I was writing the serversync package. What I found is this:
If the timeout of the DDP ping is not reached, i.e., the disconnection is only very brief:
Business as usual, no events happen. I believe the default DDP ping timeout from the client is 30 seconds.
Else:
As long as you do not use the autopublish package on the server, the client will not fire its observeChanges handlers again upon reconnection. If you use autopublish, then added events will fire for each document of the collection.
You might be interested in knowing that under the hood, DDP does send added messages to the client upon each reconnection, i.e., on each reconnect DDP sends a full copy of the collection. This happens regardless of whether you use autopublish or not. However, the client seems to be smart enough to know which of these documents he already has, so he doesn't fire the actual observeChanges events for documents he already has, only for new, changed, and removed ones. This behavior of DDP may still be relevant to you if you anticipate a lot of disconnections, because it will increase your network traffic considerably -- especially when publishing large collections. I believe this is a ramification of the following note in the docs of onConnection:
Currently when a client reconnects to the server (such as after temporarily losing its Internet connection), it will get a new connection each time. The onConnection callbacks will be called again, and the new connection will have a new connection id.
In the future, when client reconnection is fully implemented, reconnecting from the client will reconnect to the same connection on the server: the onConnection callback won’t be called for that connection again, and the connection will still have the same connection id.
Hope this helps!
I would want to send a message from the server actively, such as using UDP/TCPIP to a client using an arduino. It is known that this is possible if the user has port forward the specific port to the device on local network. However I wouldn't want to have the user to port forward manually, perhaps using another protocol, will this be possible?
1 Arduino Side
I think the closest you can get to this is opening a connection to the server from the arduino, then use available to wait for the server to stream some data to the arduino. Your code will be polling the open connection, but you are avoiding all the back and forth communications to open and close the connection, passing headers back and forth etc.
2 Server Side
This means the bulk of the work will be on the server side, where you will need to manage open connections so you can instantly write to them when a user triggers some event which requires a message to be pushed to the arduino. How to do this varies a bit depending on what type of server application you are running.
2.1 Node.js "walk-through" of main issues
In Node.js for example, you can res.write() on a connection, without closing it - this should give a similar effect as having an open serial connection to the arduino. That leaves you with the issue of managing the connection - should the server periodically check a database for messages for the arduino? That simply removes one link from the arduino -> server -> database polling link, so we should be able to do better.
We can attach a function triggered by the event of a message being added to the database. Node-orm2 is a database Object Relational Model driver for node.js, and it offers hooks such as afterSave and afterCreate which you can utilize for this type of thing. Depending on your application, you may be better off not using a database at all and simply using javascript objects.
The only remaining issue then, is: once the hook is activated, how do we get the correct connection into scope so we can write to it? Well you can save all the relevant data you have on the request to some global data structure, maybe a dictionary with an arduino ID as index, and in the triggered function you fetch all the data, i.e. the request context and you write to it!
See this blog post for a great example, including node.js code which manages open connections, closing them properly and clearing from memory on timeout etc.
3 Conclusion
I haven't tested this myself - but I plan to since I already have an existing application using arduino and node.js which is currently implemented using normal polling. Hopefully I will get around to it soon and return here with results.
Typically in long-polling (from what I've read) the connection is closed once data is sent back to the client (arduino), although I don't see why this would be necessary. I plan to try keeping the same connection open for multiple messages, only closing after a fixed time interval to re-establish the connection - and I hope to set this interval fairly high, 5-15 minutes maybe.
We use Pubnub to send notifications to a client web browser so a user can know immediately when they have received a "message" and stuff like that. It works great.
This seems to have the same constraints that you are looking at: No static IP, no port forwarding. User can theoretically just plug the thing in...
It looks like Pubnub has an Arduino library:
https://github.com/pubnub/arduino
I'm trying to implement a custom live chat program on the web, but I'm not sure how to handle the real-time (or near real-time) updates for users. Would it make more sense to send Ajax requests from the client side every second or so, polling the database for new comments?
Is there a way to somehow broadcast from the database each time a comment is added? If this is possible how would that work? I'm using Sql Server 2008 with Asp.net (c#).
Thanks!
Use long polling/server side push/comet:
http://en.wikipedia.org/wiki/Comet_(programming))
Also see:
http://en.wikipedia.org/wiki/Push_technology
I think when you use long polling you'll also want your web server to provide some support in the form of non-blocking io for requests, so that you aren't holding a thread per connection.
You could have each client poll the server, and at the server side keep the connection open without responding.
As soon there is a message detected at server side, this data is returned through the already open connection. On receipt, your client immediately issues a new request.
There's some complexity as you need to keep track server side which connections is associated with which session, and which should be responded upon to prevent timeouts.
I never actually did this but this should be the most resource efficient way.
Nope. use queuing systems like RabiitMq or ActiveMQ. Check mongoDB too.
A queuing system will give u a publish - subscribe facilities.
I have a tcpip socket interface to a third party software app. I've implemented this interface for several customer sites with no problem. The latest customer, though... problems. We've turned on logging in the apps on either end, and also installed Wireshark on the PC to log raw tcpip traffic. With that, we've proved that my server app successfully sends the message out, the pc receives the message, but the client app doesn't see it. (This is a totally intermittent problem, which is why it's such a pain to troubleshoot.)
The socket details are as simple as they come: one socket handling two way communications between the server and the pc. The messages are plain ascii text and fairly short (not XML). The server initiates communications by sending the first message, and then the client responds with several messages. The socket is kept open at all times while the apps are running. The client app is designed so that the end user can only process one case at a time, which prevents message collisions from happening. They have some sort of polling set up, their app "hibernates" until it sees the initiating message from the server.
The third party vendor has advised me to add a few second delay before I send them the initiating message. I can't see how that helps. If the client is "sleeping", just polling the socket waiting for a message, how does adding a delay before the first message help? It's not like we send two messages and the second one gets lost. It's losing the first message. So I don't see how it matters if we send that message now or two seconds from now.
I've asked them and they haven't given me details. It could be some proprietary details in their coding that they don't want to disclose to me, and that's fair. So I'm asking here because I'm always learning new things about socket programming. Maybe you guys can shed some light on how polling a tcpip socket can be affected by message timing?
Since its someone else's client and they won't tell you what its doing (other than saying 'insert a delay'), the answer is probably that their client is reading and discarding the message because its not yet in a state to deal with it. The delay will allow the client time to get into a state where it can respond to the message properly.
In other words, the client has a race condition. One easy way this can happen is if they have one thread for reading messages and another for dealing with them.
Short of running strace(1) on the client to see what system calls it is making, its tough to tell what the client is actually doing.
I'd like to know whether it's possible to easily detect (on the server side) when Flex clients disconnect from a BlazeDS destination please? My scenario is simply that I'd like to try and use this to figure out how long each of my clients are connected for each session. I need to be able to differentiate between clients as well (ie so not just counting the number of currently connected clients which I see in ds-console).
Whilst I could program in a "I'm now logging out" process in my clients, I don't know whether this will fire if the client simply navigates away to another web page rather than going though said logout process.
Can anyone suggest if there's an easy way to do this type of monitoring on the server side please.
Many thanks,
Alex
Implement you own adapter extending "extends ServiceAdapter"
Then set the function:
#Override
public boolean handlesSubscriptions() {
return true;
}
So you can handle subscription and unsubscription
Then you can manage those in the manage function:
#Override
public Object manage(CommandMessage commandMessage) {
switch (commandMessage.getOperation()) {
case CommandMessage.SUBSCRIBE_OPERATION:
break;
case CommandMessage.UNSUBSCRIBE_OPERATION:
break;
}
}
You can also catch different commands.
Hope this help
The only way to do it right is to implement the heartbeat mechanism in a way or another. You can use the keep-alive from http coupled with session expire as suggested before but my opinion is to use the messaging mechanism from BlazeDS (send a message at X seconds). You can control the time interval and other aspects (maybe you want to detect if the client is not doing anything for several hours and to invalidate the session even if your client is still connected).
If you want to be notified instantly (chat application) when a client is disconnecting a solution is to have a socket (RTMP) or some emulation (http streaming) which will detect instantly if the client is disconnected, however this disconnection can be temporary (maybe the network was down for one second, and after that is ok, and you should also detect that).
I would assume BlazeDS would provide a callback or event for when a client disconnects, but I haven't worked with Blaze so that would just be a guess. First step would be to check the documentation to see if it does though, as that would be your best bet.
What I've done in cases where there isn't a disconnect event (or it's not reliable) is to add a keepalive message. For instance, the client would be configured to send a keepalive message every 30 seconds, and if the server goes more than, say, 2 minutes without seeing a keepalive then it assumes the client has disconnected. This would let you differentiate between different clients, and you can play around with the rate and check times to get something you're happy with.