I need to interact with a server over TCP/IP with a basic message/response protocol (so for each request I shall receive a defined response).
In the JVM ecosystem, I think Java Socket was the tool to use 15 years ago, but I'm wondering if there is anything more suitable nowadays in the JDK? For example, with Java Sockets one still needs to manually timeout a request if no answer is received, which feels really old fashioned.
So is there anything new in the JDK or JVM universe?
No, there are much better option nowadays which allow you to implement your client/server asynchronously without additional threading.
Look at SocketChannel from nio or even better AsynchronousSocketChannel from nio2. Check this tutorial
Especially the latter option will allow you to just start the connection listener and register callback which will be called whenever new connection is requested, data arrived, data was written etc.
Also consider looking at some high level solutions like Netty. It will take care of the network core, distribute load evenly to executors. Additionally it provides clears separation of the network layer and processing layer. For the processing layer it will provide you with lot of reusable codecs for common protocols.
You can try RMI which works on top of TCP/IP but hides all the hardwork with a convenient set of APIs.
Follow this tutorial post
Well, there are really a lot of other technologies to use, for example JMS has various implementations which work out of the box.
Sockets are low-level building blocks of network communications, like wires in the electricity network of your house. Yes, they're old fashioned, yes, we likely don't want to see them, but they're there and they will stay there for a good reason.
On top of Sockets, you can e.g. pick the HTTPUrlConnection, which implements most of the HTTP protocol. Still, setting timeout policies are in your hands, which I find quite useful, and extremelly painful at the same time.
http://www.mkyong.com/java/how-to-send-http-request-getpost-in-java/
You are free to move one abstraction level above, and use a ready-made REST library, such as this: http://unirest.io/java.html
The example above connects to a server, configures a HTTP query string, perform the request (timeout, encodings, all the mess under the hood), and finally get the response in Json format in a few lines:
Unirest.post("http://httpbin.org/post")
.queryString("name", "Mark")
.field("last", "Polo")
.asJson();
Nowadays a vast amount of web services are available using REST protocol, which is a simple command-response over HTTP. If you have a chance, I'd suggest using REST, as you can easily find available client and server side implementations, and you don't need to reinvent the wheel on the command-protocol layer either.
On client side, unirest is quite convenient. On the server side, we have had really great experience in the 1.2.xx series of Play! framework. But there are thousands of these things out there, just search for "REST".
Take a look to Netty Project, "Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server."
This framework give us a lot of capabilities that simplify the programming process, allowing a big scalability.
Is used by Twitter and a lot of big companies in the tecnology industry.
This is a nice presentation from Norman Maurer.
Related
I have the following situation:
I have 2 JVM processes (really 2 java processes running separately, not 2 threads) running on a local machine. Let's call them ProcessA an ProcessB.
I want them to communicate (exchange data) with one another (e.g. ProcessA sends a message to ProcessB to do something).
Now, I work around this issue by writing a temporary file and these process periodically scan this file to get message. I think this solution is not so good.
What would be a better alternative to achieve what I want?
Multiple options for IPC:
Socket-Based (Bare-Bones) Networking
not necessarily hard, but:
might be verbose for not much,
might offer more surface for bugs, as you write more code.
you could rely on existing frameworks, like Netty
RMI
Technically, that's also network communication, but that's transparent for you.
Fully-fledged Message Passing Architectures
usually built on either RMI or network communications as well, but with support for complicated conversations and workflows
might be too heavy-weight for something simple
frameworks like ActiveMQ or JBoss Messaging
Java Management Extensions (JMX)
more meant for JVM management and monitoring, but could help to implement what you want if you mostly want to have one process query another for data, or send it some request for an action, if they aren't too complex
also works over RMI (amongst other possible protocols)
not so simple to wrap your head around at first, but actually rather simple to use
File-sharing / File-locking
that's what you're doing right now
it's doable, but comes with a lot of problems to handle
Signals
You can simply send signals to your other project
However, it's fairly limited and requires you to implement a translation layer (it is doable, though, but a rather crazy idea to toy with than anything serious.
Without more details, a bare-bone network-based IPC approach seems the best, as it's the:
most extensible (in terms of adding new features and workflows to your
most lightweight (in terms of memory footprint for your app)
most simple (in terms of design)
most educative (in terms of learning how to implement IPC). (as you mentioned "socket is hard" in a comment, and it really is not and should be something you work on)
That being said, based on your example (simply requesting the other process to do an action), JMX could also be good enough for you.
I've added a library on github called Mappedbus (http://github.com/caplogic/mappedbus) which enable two (or many more) Java processes/JVMs to communicate by exchanging messages. The library uses a memory mapped file and makes use of fetch-and-add and volatile read/writes to synchronize the different readers and writers. I've measured the throughput between two processes using this library to 40 million messages/s with an average latency of 25 ns for reading/writing a single message.
What you are looking for is inter-process communication. Java provides a simple IPC framework in the form of Java RMI API. There are several other mechanisms for inter-process communication such as pipes, sockets, message queues (these are all concepts, obviously, so there are frameworks that implement these).
I think in your case Java RMI or a simple custom socket implementation should suffice.
Sockets with DataInput(Output)Stream, to send java objects back and forth. This is easier than using disk file, and much easier than Netty.
I tend to use jGroup to form local clusters between processes. It works for nodes (aka processes) on the same machine, within the same JVM or even across different servers.
Once you understand the basics it is easy working with it and having the options to actually run two or more processes in the same JVM makes it easy to test those processes easily.
The overhead and latency is minimal if both are on the same machine (usually only a TCP rountrip of about >100ns per action).
socket may be a better choice, I think.
Back in 2004 I implement code which do the job with sockets. Until then, many times I search for a better solution, because socket approach triggers firewall and my clients worry. There is no better solution until now. Client must serialize your data, send and server must receive and unserialize.
It is easy.
I am currently decide what kind of communication method/network protocol I am going to use for a new project.
What I can tell you about this project is that:
- It is Android/java based, using X amount of Android devices
- These devices should be able to send strings to each other over a local network. We are talking about small strings here. Small as in less than 100 characters.
- The amount of packages/transmissions being sent can vary "A LOT". I can't say how much unfortunately, but the network protocol needs to be as scalable as possible.
I have researched different kinds of possible solutions and is now deciding wether to use "Sockets" or "RMI"
As I have understood about RMI:
It is easier than Java sockets to implement and maintain (smaller amount of code)
It is "a bit slower" than sockets, as it is a new "layer" build on top of Sockets
There may be some scalability issues (if this is true, how "serious" is it?) as it creates a lot of new sockets, resulting in Exceptions.
Obviously the system needs to run as smooth as possible, but the main objective is to make it scalable so it can handle more Android devices.
EDIT: The system the system is not "peer-to-peer". All of the android devices should be able to be configured as the server.
None of your concerns are the real issue, in my view.
RMI has a pre-defined protocol, raw sockets do not.
If you use raw sockets, you have to do all the work to define what messages and protocols are exchanged by client and server.
There are so many good existing protocols (RMI, HTTP, etc.) that I'd wonder why you feel the need to invent your own again.
Android devices communicating over HTTP - tell me why it won't be fast or scalable enough. HTTP is good enough for the Internet - why not you and your solution?
I would suggest you to expose some kind of webservice (SOAP or REST) in your application server. For example, people frequently expose their data to mobile devices as a REST webservice API returning some kind of JSON format in order to make it easier to marshal it again in the client device.
This way you take profit of the underlying implementation of HTTP communication in every application server; any other way, you would have to write your own worker thread pool using nio primitive operations in order to achieve performance... Not a thing to be done in a real production environment - maybe in an academic one?
When you work with Bluetooth or WiFi Direct in Android, at the end of all of the handshaking and such, you wind up with sockets.
With TCP/IP, we have a zillion-plus-one libraries that layer on top of sockets, for high-level protocols: HTTP, XMPP, IMAP, etc. Courtesy of these libraries, we can deal with more domain-specific abstractions of an operation (e.g., "download this file"), with low-level socket plumbing handled by the library.
Question: Are there equivalents, for any high-level protocol, that are known to work (or are likely to work) with the sockets produced via Android's Bluetooth and/or WiFi Direct layers?
Right now, I'm not fussy about the specific protocol -- I'm just looking for examples of this sort of protocol layer, to make using these sorts of connectivity options easier for developers.
For example, it looks like I could create a fork or add-on for OkHTTP that uses an alternative source for sockets, and I could probably create a Java HTTP server that does the same. Given those, app developers would write HTTP apps that talked over Bluetooth or WiFi Direct (and, on the client side at least, the coding should be fairly "natural" in feel, once the connectivity-specific pairing and handshaking has gone on).
IOW, going back to dealing with raw sockets feels so two decades ago... :-)
Thanks!
UPDATE
Based on Kristopher Micinski's comment on the ZeroMQ answer, I figured some clarification might be in order.
It's easier to say what I don't want: I don't want to touch sockets, after creating them. Something else at a higher level should handle those for me, plus handle what I'd consider a "protocol" to be (e.g., determining when some communications operation has ended, beyond a socket closing).
Mostly, this is for my book. Most book examples for low-level socket stuff are unrealistic, such as "we open a socket to the server and immediately start blasting the bytes representing some image to be uploaded, then close the socket when we're done". While the examples work, you'd never write something like that in real life:
If you're really working at the socket level, you'd be implementing some protocol that has the hopes of addressing authentication, error handling, etc., even if you're rolling the protocol yourself
Few developers work directly with sockets today for Internet operations
Now, it'd be cool if the protocol offered by the layer were something developers were used to (e.g., HTTP) or had heard of even if they haven't used it (e.g., XMPP). And I'll settle for simple scenarios (e.g., N-way support is cool but not necessary). In this respect, based on preliminary research (conducted by a sleep-deprived brain), ZeroMQ isn't a bad option. It lacks a bit of "brand recognition" compared to, say, an XMPP stack that could work with arbitrary sockets. But off the cuff it seems to meet what else I'm looking for.
I recognize that these stacks will have limitations imposed by the underlying transport (e.g., Bluetooth works well for N-way only for small values of N). And I certainly don't want to portray -- here or in my book -- that whatever solution I portray is the be-all and end-all of socket based communication.
I just want something that has a prayer of being more realistic for actual use. Bonus points if it is something that I can grok, as I have always used higher-level protocols for TCP/IP communications, and so I'm short on experience with direct socket manipulation.
I found ZeroMQ to be useful for managing socket connection. They have a support in multiple languages which includes JAVA. You may use this to manage the sockets once you establish the connection over wifi-direct or BT.
I know it's a somewhat old question and already answered but I would like to contribute.
I did this app: https://play.google.com/store/apps/details?id=com.budius.WiFiShoot and although the WiFi Direct connection n handshake is somewhat broken and it's what causes most of my unhappy users, I'm handling all the communication using the excellent https://github.com/EsotericSoftware/kryonet
and my code is pretty much what you see on their examples, create kryo, register classes, open server, connect client to server IP and shoot objects across with the file information and later I shoot the actual files using this code https://code.google.com/p/kryonet/source/browse/trunk/kryonet/test/com/esotericsoftware/kryonet/InputStreamSenderTest.java
hope it helps.
I want to be able to exchange data between my app and the server where each side has to be able to initiate sending of data. I want it to happen quickly and polling from the client side for new messages is not fast enough in my case. How do push technologies work?
I was thinking to keep an opened socket connection from the device to the server and send receive raw bytes in some custom format.
Is it a good approach and what problems might I run into? What would you suggest as an alternative?
When it comes to message passing, the time needed to initialize a new connection between the server and the client usually exceeds by far the time needed to sent the data itself - at least for simple status-like messages. This adds significantly to the communication latency, which seems to be your main concern.
There are two main ways to deal with this issue:
Keep a connection open between both ends at all times: This is the standard way of dealing with this issue - it has the advantage of programming simplicity but you may need to use stay-alive packets regularly to keep the connection open. This may reduce the battery life of a mobile device and increase the networking cost slightly. It may also interact unfavorably with the power-management features of a mobile device.
In addition, no matter what you do, you cannot completely eliminate the possibility of a new connection needing to be established at an inconvenient time - connections that are mostly idle do not fare very well in today's networking infrastructure, I'm afraid...
Use a connection-less protocol, such as UDP: This solution has the potential to minimize the communication and power cost, but it requires that your server and client are designed to handle the inherent unreliability of such protocols.
That said, I would not consider the actual format of the data a major concern, until some profiling demonstrates that a custom format will indeed result in significant savings. I would consider the ability to use off-the-shelf network monitoring and analysis software far more important during the development phase...
Push technology is loosely called Comet. The basic logic is to open an persistent HTTP connection with the server (often called HTTP Streaming). As this connection will not last forever (due to the limitations on the server by default), you should be able to reopen the connection. I am not sure how to do it in android specifically but this should be possible.
The basic concept behind this is explained in this blogpost
As this is a concept, it can be implemented in any server side programming language of your choice. This tutorial gives a fair introduction about how to implement COMET in php. socket.io is another such library if you are comfortable with javascript. This SOF thread provides some useful links.
Coming to advantages and disadvantages,
If you want almost instant updates, COMET is the best.
If you have a limit on the number of connections to the server at a time, then COMET probably has to be thought upon based on the tradeoff.
I have 2 processes that need to communicate over the same PC and different PCs. In the local case the process communication is among different processes e.g Process A and Process B.
In the remote case it will be among 2 instances of Process A running in different PCs.
I will create them from scratch and I am wondering what is the best approach. I am aware of RMI and sockets but I was wondering for my case as described, and taking also into account that the messages exchanged are small and the number of APIs really small, if there is a standard approach/library for this.
Any suggesstions are highly welcome
Update after #EJP comments:
My interest is 1)to implement the requirement for communication in a light manner since the API exposed will be really small and the messages as well 2)use and learn a new popular framework if possible (I already know RMI and sockets)
If you are just looking for messaging frameworks, there's a bunch available out such as
RabbitMQ - http://www.rabbitmq.com/
ZeroC Ice - http://www.zeroc.com/ice.html
AMQP - http://www.amqp.org
OpenSplice DDS - http://www.prismtech.com/opensplice
But when you use a 3rd party framework, you are then adding an additional dependency to your application. If it is something very simple like your case, perhaps writing a TCP client/server would be sufficient for a client/server paradigm or if you are looking for publisher/subscriber paradigm then you can look into using UDP multicast. You just need your data class to extends Serializable if you want to be able to marshal and unmarshal your data to buffer and send it over to network using typical JAVA socket API.
I strongly suggest having a look at Thrift. From all the technologies I've used (web services, RMI, XML-RPC, Corba comes to mind) it is currently my favourite. Essentially the steps involved are:
Download the Thrift compiler.
Add the Maven dependency (make sure it is the same version as the compiler!) I currently use 0.8.0.
Write your Thrift IDL (incredibly easy, google for it as there are plenty of examples).
Compile it for Java.
Writer your server/client.
In general, you can whip together a server and a client in about 30 lines of code. In terms of speed and reliability it has never failed me before.
You might have a look at Versile Java (full disclosure: I am one of the developers), it satisfies at least your criteria #1. From the API documentation, here are some examples of writing remote-enabled objects, running a service, and connecting to a service.
If you want to learn something new then I'd look at OpenSplice. The reason is pretty simple, among the technologies suggested above is the only one that provides you with Data-Centric abstractions.
The cool thing about OpenSplice is that gives you the abstraction of a Global Data Space, yet the implementation of this global data space is fully distributed and very high performance.
Take a look at some of the slides available at http://www.slideshare.net/angelo.corsaro and I am sure you'll get in love with the technology.
Finally OpenSplice is Open Source.
Happy Hacking.
A+
JMX is a good alternative .
Example :
http://www.javalobby.org/java/forums/t49130.html
IMB JMX Example
http://alvinalexander.com/blog/post/java/source-code-java-jmx-hello-world-application