How to send a message from Java to Erlang? - erlang

I'm making a application in Erlang, with a GUI in Java.
I've managed to establish a connection between the to languages, but now i need to (i guess) send a message from Java to Erlang, every time I e.g press a button.
Is that the right way to go?
How would such a message look?
I've found a few good sites about this form of integration, but I feel like im not getting everything.
http://www.trapexit.org/How_to_communicate_java_and_erlang

Besides classic Java-Erlang communication via OTP jinterface you can research such methods like:
- thrift
- ice from zeroC (no official erlang binding)
- maybe two http servers on both sides (I like this approach)
- protocol buffers (rather not, it is better for larger data transfers)
You need to learn the shape of your traffic and choose the best solution.
Jinterface is not so bad, tho.. (here is official doc: http://www.erlang.org/doc/apps/jinterface/jinterface_users_guide.html)

If jinterface is too complicated you might just use the packet option on open_port and use
byte[] in_buf = new byte[256];
byte[] out_buf = new byte[256];
int in_count = System.in.read ();
int offset = 0;
do
{
int c = System.in.read (in_buf, offset, in_count-offset);
offset += c;
}
while (offset < in_count);
To read packets from erlang and to write use:
System.out.write(out_count);
System.out.write(out_buf, 0, out_count);
On the erlang side this would match with
open_port({spawn, "<path-to-java> -cp <classpath> your-java-prog",
[{packet, 1}]).
If you need larger packets use {packet, 2} or {packet, 4} and adapt the java.
Inside the packets you can run whatever protocol you like on both sides.

I am working on an application similar to yours: C++ GUI and Erlang server. I use TCP sockets to exchange messages between the GUI and server, and Erlang server patterns for handling requests (I may have more than one GUI hooked up to the server at the same time).

Related

ROS - How do I publish a message and get the subscribed callback immediately

I have a ROS node that allows you to "publish" a data structure to it, to which it responds by publishing an output. The timestamp of what I published and what it publishes is matched.
Is there a mechanism for a blocking function where I send/publish and output, and it waits until I receive an output?
I think you need the ROS_Services (client/server) pattern instead of the publisher/subscriber.
Here is a simple example to do that in Python:
Client code snippet:
import rospy
from test_service.srv import MySrvFile
rospy.wait_for_service('a_topic')
try:
send_hi = rospy.ServiceProxy('a_topic', MySrvFile)
print('Client: Hi, do you hear me?')
resp = send_hi('Hi, do you hear me?')
print("Server: {}".format(resp.response))
except rospy.ServiceException, e:
print("Service call failed: %s"%e)
Server code snippet:
import rospy
from test_service.srv import MySrvFile, MySrvFileResponse
def callback_function(req):
print(req)
return MySrvFileResponse('Hello client, your message received.')
rospy.init_node('server')
rospy.Service('a_topic', MySrvFile, callback_function)
rospy.spin()
MySrvFile.srv
string request
---
string response
Server out:
request: "Hi, do you hear me?"
Client out:
Client: Hi, do you hear me?
Server: Hello client, your message received.
Learn more in ros-wiki
Project repo on GitHub.
[UPDATE]
If you are looking for fast communication, TCP-ROS communication is not your purpose because it is slower than a broker-less communicator like ZeroMQ (it has low latency and high throughput):
ROS-Service pattern equivalent in ZeroMQ is REQ/REP (client/server)
ROS publisher/subscriber pattern equivalent in ZeroMQ is PUB/SUB
ROS publisher/subscriber with waitformessage equivalent in ZeroMQ is PUSH/PULL
ZeroMQ is available in both Python and C++
Also, to transfer huge amounts of data (e.g. pointcloud), there is a mechanism in ROS called nodelet which is supported only in C++. This communication is based on shared memory on a machine instead of TCP-ROS socket.
What exactly is a nodelet?
Since you want to stick with publish/ subscribers, assuming from your comment, that services are to slow I would have a look at waitForMessage (Documentation).
And for an example on how to use it you can have a look at this ros answers question.
All you need to do is to publish your data and immediately call waitForMessage on the output topic and manually pass the received message to your "callback".
I hope this is what you were looking for.
To get this request/reply behaviour ROS has a mechanism called ROS service.
You can specify the input and output of your service in a service file similar to a ROS message definition. You can then call the service of a node with your input and the call will receive an output when the service is finished.
Here is a tutorial how to use this mechanism in python. If you prefer C++ there is also one, you should find it.

zlib inflate giving data error in erlang

I have a java client which is sending some message to an erlang server process listening on TCP.The java client sends the data using outputstream.On the server side i am using following call to uncompress the data after initialising zlib
zlib:inflate(ZStream, Data),
where Data is binary.I am getting data_error on this call.
Under what conditions do I get data_error with zlib.
Try setting a 0 or -15 WindowBits, would help if you paste more code like the zlib:inflateInit call, the binary dump of Data variable, and the Java side zlib init.
If you are streaming the data in relatively small chunks, you can use my ezlib on Github.
Performance wise it's around 69 % faster than erlang driver and also works better when you have concurrent sessions.
To integrate, use rebar as you would do for any other erlang app. To run a small example:
StringBin = <<"this is a string compressed with zlib nif library">>,
{ok, DeflateRef} = ezlib:new(?Z_DEFLATE),
{ok, InflateRef} = ezlib:new(?Z_INFLATE),
CompressedBin = ezlib:process(DeflateRef, StringBin),
DecompressedBin = ezlib:process(InflateRef, CompressedBin).
Do not use it to compress large blocks, because you can block the erlang scheduler. I will change this in the subsequent versions.

Any lib or formal method handling TLV in Erlang?

I'm working on a protocol handling data exchange that somehow a little complex, then I found TLV is the one I need. Is there a formal way to read and write TLV in erlang? or some lib / code example handling this? thanks.
The "default" in Erlang is LTV rather than TLV, but it is rather easy to handle:
case gen_tcp:recv(Socket, 8) of
<<Type:32/integer, Len:32/integer>> ->
Payload = gen_tcp:recv(Socket, Len),
{type_of(Type), Payload};
...
end,
You will need passive sockets to get this to work, but it is rather easy to do. If you have the freedom to pick your format, the LTV encoding is better because you can then put the socket in {active, once} mode which means the underlying layer decodes stuff for you.
I haven't actually used it, but how about this one: https://github.com/essiene/smpp34pdu/blob/master/src/tlv.erl

Measuring data traffic flow over server/client socket in delphi?

i am making a program that sends data between a server program and its clients. They all use the server and client socket components found in Delphi! I have looked on the Internet and cannot find a way on how to measure how much data has been transferred through a socket!
Any help, especially some code (pascal/Delphi), would be very much appreciated!
here you have a full example http://delphi.about.com/od/fullcodeprojects/l/aa112903a.htm
If you use win/*nix API sockets (not a special libraries) you have to count returns from recv and send functions.
total_data = 0;
...
...
get_data = recv(...)
total_data = total_data + get_data
...
send_data = send(...)
total_data = total_data + send_data
Magenta Systems has a free set of components that can monitor network traffic using either raw sockets or WinPcap.
Update:
From your comment to RBA's response: The Magenta components let you identify and differentiate between different IP addresses and services (ports).
I keep stats on all my TCP traffic to the byte. Every time I send data I update the stats and every time I receieve data I update the stats. This is accurate to one byte and requires only a few lines of code. And it does not rely on any particular TCP components. Why is doing it this way so hard?

How to filter messages in Ejabberd

I have Ejabberd up and running with test users, and its working fine. I want to write a module that can intercept messages and modify them, as follows :
intercept "messages"
send them to a php file
get the result from the same php file (immediate)
Modify the message stanza and send it down the wire to the recipient
The ejabberd documentation is weak and tutorials are non-existent. Can you give me some sample code that does this. I can then figure how to configure it for my needs.
Thanks a bundle!
Adil
Here's the basic example of such module:
-module(packet_interceptor).
-behaviour(gen_mod).
-export([start/2,
stop/1]).
-export([on_filter_packet/1]).
start(Host, _Opts) ->
ejabberd_hooks:add(filter_packet, global, ?MODULE, on_filter_packet, 0).
on_filter_packet({From, To, XML} = Packet) ->
%% does something with a packet
%% should return modified Packet or atom `drop` to drop the packet
Packet.
And make sure to add this module into ejabberd's configuration into module section:
{modules,
[...
...
...
{packet_interceptor, []}
]}.
Just extend on_filter_packet/1 the way you want and return appropriately modified packet.
gleber's example is excellent. I also wrote a more complex example of packet manipulation that I built for Chesspark called
mod_sunshine.
How can send this XML data to php (via ?xml=) and retrieve the resulting XML and then pass it to the recipient?
If you have a recent version of ejabberd that uses exmpp, you can use exmpp_xml:node_to_binary/1 or exmpp_xml:node_to_list/1 to turn the internal representation of the XML to a binary or a string respectively.
There were similarly named functions in the older ejabberd, but within the xml module.
It seems that what you want to do there is to create an XMPP server component. Lots of things has already been said on that post Which XMPP server to experiment developing a server component.
I can link you some useful links:
Jabber Component Protocol
An Echo-Bot in Python from metajack.im, a very nice blog from an XMPP guru. This bot listen for any message stanzas and reply to some of them.
Gleber's solution is really "ejabberd" oriented (certainly the easiest one in your case), whereas this one can scale with other XMPP servers.
There is the interface:
ejabberd_router:register_route(MyHost)
which I have used in the past and works well. Once the MyHost is registered with ejabberd, the module will receive the communications intended to MyHost through info messages (assuming gen_server).
As noted by #gleber, don't forget to add your module to the configuration file.

Resources