I tried to implement UDP server using Spring Integration like it's described here but when clients operate behind NAT they will never receive responses from server. It's because server should send response datagrams from the same port as UDP adapter port (check UDP via NAT explained here).
How can I achieve proper UDP communication with clients behind NAT using Spring Integration?
As discussed in those threads; there are not currently any gateways for UDP, only channel adapters. Gateways are used for two-way integration.
There has just not been any demand over the years for UDP gateways.
We did make some changes to facilitate users replying to incoming messages (by adding the sending port as as header).
This will allow you do construct a DatagramPacket (perhaps using the SI DatagramPacketMessageMapper) and send it to the originating system using your own code.
If you want us to reconsider providing UDP gateways, make a comment on the JIRA Issue. Even better, consider contributing.
EDIT
For asynchronous sends you don't need a gateway; buy you need to tweak the mapper and message handler which is built into the outbound adapter.
Change the DatagramPacketMessageMapper here to set the socketAddress using message headers; and add an option to the UnicastSendingMessageHandler so that it doesn't unconditionally set the destinationAddress here.
You can do this by subclassing the handler and overriding the send() method.
You can then wire your customized message handler into a <service-activator/> using the ref attribute.
Related
There is a device that works on Android 6. It does not have TCP, there is only a TETRA communication channel.
There works one application that transmits information via the TETRA channel. Since there is no TCP on the device, normal applications (for example, Skype) do not work. Is it possible to create some kind of gateway (for example, programmatically) so that all TCP requests, like sent through TETRA to endPoint?
Or, for example, create an application (proxy) that intercepts all tcp requests and sends a request to the BS using the TETRA protocol and the base station reads this request and there is already running a tcp request for some endPoint (for example, a Skype server), and the response back via TETRA on the device, our proxy application reads the response and interprets it in the TCP response.
I do not quite understand this, maybe I messed up a lot. Tell me, please, is this possible? How?
I've an application that's using Apache mina library for communicating based on TCP. The apache mina library provides a callback with IOBuffer that contains data coming over the network, however often times the data is received out of order or redundantly. I skimmed through the TCP protocol and it says that the protocol always ensures delivery of the data in correct order. The company that provided the APIs for their server claim that they are using TCP/IP for sending the response back however before sending the response back their server doesn't care about confirming if the client (in this case my application/apache mina library) is connected to the server. So the server just fires off the message and moves on.
If I'm not mistaken, that's the UDP protocol's behavior. My question is, if the server is using TCP for sending the response back:
Why do I get out of order data (it's rare but happens one in a while)?
How can a machine that's using TCP protocol just fire and forget about the data without making sure the receiver device is connected to it before sending the data?
Is this really TCP or UDP or some variation of TCP protocol?
Apache Mina does asynchronous messaging over the top of various transports including TCP.
Since Mina is asynchronous, out-of-order delivery should be expected.
Why do I get out of order data (it's rare but happens one in a while)?
One possible explanation is that multiple TCP streams are being used. Data delivered using one TCP stream will be delivered in order, but if multiple streams are used, data in one stream could "overtake" data on another stream, in the TCP stacks on the sending or receiving end, on the network, or in the client side library.
How can a machine that's using TCP protocol just fire and forget about the data without making sure the receiver device is connected to it before sending the data?
Because ... reliable delivery is not a basic attribute of Mina.
If you are using Mina to talk to a service with a particular application protocol, then that protocol will determine will determine whether "sending the data before checking the receiver is connected" is allowed / will work or not. For example, it won't for an HTTP response, because an HTTP response is sent on a connection that was previously established to send the request.
Actually, it seems that there are a variety of ways to use Mina. Some involve an application protocol; e.g. see HttpClientCodec and HttpServerCodec. Others don't.
Is this really TCP or UDP or some variation of TCP protocol?
If they say that TCP is being used as transport, then it is. However, Mina is neither TCP or UDP. It is Mina. It hides the details of the transport.
Bottom line, if you want the reliability / in-order delivery properties of TCP/IP, you should probably use them directly. Mina is providing higher performance than conventional TCP/IP over a synchronous socket by relaxing the normal properties of a (single) stream-based transport.
I want to run a Java based message broker that will route messages to web clients. Web client connections are handled on our server using our custom Java websocket code, which authenticates users against the user database.
I think my server side websocket handler code would connect to ActiveMQ and perform subscription management via AQMP.
I have a specific requirement however:
route messages for a topic specifically to one or more web clients
Note that I don't need to retain messages if a client is not connected. Messages are being used to inform the web client applications of actions they need to take.
I'm considering ActiveMQ but I was hoping people with experience of the product could clarify if it supports this requirement?
If ActiveMQ isn't the best option, could you recommend something else?
Thanks
Yes, ActiveMQ is a great choice for this.
As far as specific approach goes, it depends on your data model and message flow.
You have several options, including:
Produce and consume to a topic-per-client
a. Messages for Client ABC go to topic://CLIENTS.ABC, for Client XYZ go to topic://CLIENTS.XYZ, and the subscribers connect accordingly.
Produce a message with a header and use a consumer-side selector (aka 'filters' in AMQP) to filter messages on a per-client basis. (abc client subscribes to-- ClientId = ABC, xyz client subscribe to-- ClientId = XYZ)
When using WebSockets, you might also look to STOMP which is text-based protocol. (Just depends on your programming language and available libraries that you had in mind)
We are building a new client along with a caching proxy component for an existing online game. The current setup looks like:
Server
| \
TCP TCP
| \
Client1 Client2
The new setup will be:
Server
| |
TCP TCP
\ \
Proxy <-- (New!)
| \
0MQ 0MQ
| \
Client1 Client2 <-- (New!)
The proxy component will sit close to the existing game server and speak the old line based TCP protocol to it, while speaking a new Google Protocol Buffers-based protocol over 0MQ to the new client. In addition to forwarding and translating messages between the server and its clients, the proxy will also cache (protobuf) messages destined for clients.
The server responds to client requests, but may also send unsolicited messages to specific clients, or to all clients. Since the proxy will maintain a cache of messages destined for a certain client, it needs to keep some state associated with each client.
I've been reading quite a bit in the ZeroMQ Guide, but I'm still not sure which of its "patterns" or socket combinations would suit this setup best. I'm hoping there's some ZeroMQ wizard out there who can give some advice on what the best way to go here is.
The question is not language specific, but the proxy component will be written in Java and the client in C#.
Many thanks in advance!
I think the Asynchronous Client Server pattern will get you close. Each of your clients creates a DEALER socket which connects to the ROUTER socket in your proxy. Review the example Java source. You could base your proxy on the ServerTask class, using the frontend/ROUTER socket and omitting the backend/dealer socket.
Your server will be able to respond to client requests and send unsolicited messages back to any client. You will need to cache the socket id of each client after the client has sent at least one message.
Your TCP connection to the game server is conceptually similar to the backend DEALER sockets between the server and workers - however since your connection is classic TCP and and not ZeroMQ you cannot use ZeroMQ sockets and will need to do something custom. And your custom solution requires that you not violate ZeroMQ's concurrency rules, when you integrate with classic TCP sockets.
Here is one way - use a set of PAIR sockets (lets call them A and B) and a BlockingQueue to act as a bridge between ZeroMQ and your TCP sockets. And create 3 threads - TCPRead, TCPWrite and ZeroMQ.
TCPRead reads from the TCP connection to the game server. It converts them to protobuf messages and forwards them through the A socket.
TCPWrite polls the BlockingQueue for messages. When it receives a message it converts it and sends it to the game server via TCP connection.
Finally, most of the work is in the ZeroMQ thread. It uses ZeroMQ polling and is constantly polling it's router socket (for all messages from all clients) and the B socket (for messages from the game server). Sending messages to a client is straightforward and is handled by sending the message to the router socket, prefixing the message with the socket id of the client. Sending messages to the server is done by adding a message to the BlockingQueue. It will be picked up by TCPWrite and forwarded to the game server.
Once you get this basic design working, you can go nuts and add workers etc as described in the various patterns.
Hope this helps.
You can also use 0MQ ROUTER sockets in raw mode, meaning you could write the proxy with two ROUTER sockets. I'd stay away from PAIR sockets except for parent-to-child thread pipes.
It takes a while to plough through the ZeroMQ documentation, excellent as it is. I did and came to the conclusion that Asynchronous Client-Server was close to what I initially wanted.
But it wasn't quite. So I then proceeded to build.
What I actually wanted is based on what I'd learnt from the various examples. A full description of what I ended up with is in here as is the code which may be of some use, for reference or as an actual library.
I have written a socket program in Java. Both server and client can sent/receive data to each other. But I found that if client sends data to server using TCP then internally TCP sends acknowledgement to the client once the data is received by the server. I want to detect or handle that acknowledgement. How can I read or write data in TCP so that I can handle TCP acknowledgement. Thanks.
This is simply not possible, even if you were programming in C directly against the native OS sockets API. One of the points of the sockets API is that it abstracts this away for you.
The sending and receiving of data at the TCP layer doesn't necessarily correlate with your Java calls to send or receive data. The data you send in one Java call may be broken into several pieces which may be buffered, sent and received independently, or even received out of order.
See here for more discussion about this.
Any data sent over a TCP socket is acknowledged in both directions. Data sent from client to server is the same as data sent from server to client as far as TCP wire communications and application signaling. As #Eric mentions, there is no way to get at that signaling.
It may be that you are talking about timing out while waiting for the response from the server. That you'd like to detect if a response is taking too long. Is it possible that the client's message is larger than the server's response so the buffering is getting in the way of the response but not the initial request? Have you tried to use non-blocking sockets?
You might want to take a look at the NIO code if you have not already done so. It has a number of classes that give you more fine grained control over socket communications.
This is not possible in pure Java since Java's network API all handles socket, which hides all the TCP details.
You need a protocol that can handle IP-layer data so you can get TCP headers. DLPI is the most popular API to do this,
http://www.opengroup.org/onlinepubs/9638599/chap1.htm
Unfortunately, there is not Java implementation of such network. You have to use native code through JNI to do this.
I want to detect or handle that acknowledgement.
There is no API for receiving or detecting the ACKs at any level above the protocol stack.
Rethink your requirement. Knowing that the data has got to the server isn't any use to an application. What you want to know is that the peer application has received it, in which case you have to get the peer application to acknowledge at the application protocol level.