I found list of paho MQTT libraries installed in Linux:
libpaho-mqtt3a.so -> libpaho-mqtt3a.so.1
libpaho-mqtt3a.so.1 -> libpaho-mqtt3a.so.1.3
libpaho-mqtt3a.so.1.3
libpaho-mqtt3as.so -> libpaho-mqtt3as.so.1
libpaho-mqtt3as.so.1 -> libpaho-mqtt3as.so.1.3
libpaho-mqtt3as.so.1.3
libpaho-mqtt3c.so -> libpaho-mqtt3c.so.1
libpaho-mqtt3c.so.1 -> libpaho-mqtt3c.so.1.3
libpaho-mqtt3c.so.1.3
libpaho-mqtt3cs.so -> libpaho-mqtt3cs.so.1
libpaho-mqtt3cs.so.1 -> libpaho-mqtt3cs.so.1.3
libpaho-mqtt3cs.so.1.3
I understand that file names with ending with as means asynchronous. But what about a, c, cs?
What they are used for
Quoting from the readme:
paho-mqtt3a - asynchronous (MQTTAsync)
paho-mqtt3as - asynchronous with SSL (MQTTAsync)
paho-mqtt3c - "classic" / synchronous (MQTTClient)
paho-mqtt3cs - "classic" / synchronous with SSL (MQTTClient)
Hopefully this answers the question; if more info is needed there is a link, just below the above, to a document that explains the which to use and why in some detail (but is somewhat outdated!).
Related
Are there any downsides to using the application:get_env / application:set_env to keep global state dynamically?
Example:
I have a module that handles http requests.
I have a collection of http request handlers.
I want to register/get http request handlers via the application env.
start() ->
% Init default handlers
application:set_env(?REQUEST_HANDLER_MODULES, [foo_handler, bar_handler]).
add_http_request_handler(Module) ->
% Register handler at runtime
Modules = application:get_env(?REQUEST_HANDLER_MODULES),
application:set_env(?REQUEST_HANDLER_MODULES, [Module|Modules]).
handle_request(Req) ->
Modules = application:get_env(?REQUEST_HANDLER_MODULES),
handle_request(Req, Modules, {}).
handle_request(Req, [], Agg) ->
Agg;
handle_request(Req, [M|L], Agg) ->
handle_request(Req, L, M:handle(Req, Agg)).
What are the downsides to this?
Does this require a round trip to an application process each time application:get_env is fetched?
Is this a functional anti-pattern?
If you need to have persistent storage i.e. maintain the exact data after Erlang VM restart, I think you should go with Mnesia's disc_copies table. Based on my experience, this beast can handle load and concurrency very well.
I have written some extension modules for eJabberd most of which pass pieces of information to RabbitMQ for various reasons. All has been fine until we brought the server up in staging where we have a Rabbit cluster rather than a single box.
In order to utilize the cluster you need to pass "x-ha-policy" parameter to Rabbit with either the "all" or "nodes" value. This works fine for the Java and Python Producers and Consumers, but the eJabberd (using the Erlang AMQP client of course) has me a bit stumped. The x-ha-policy parameter needs to be passed into the "client_properties" parameter which is just the "catchall" for extra parameters.
In Python with pika I can do:
client_params = {"x-ha-policy": "all"}
queue.declare(host, vhost, username, password, arguments=client_params)
and that works. However the doc for the Erlang client says the arguments should be passed in as a list per:
[{binary(), atom(), binary()}]
If it were just [{binary(), binary()}] I could see the relationship with key/value but not sure what the atom would be there.
Just to be clear, I am a novice Erlang programmer so this may be a common construct that I am not familiar with, so no answer would be too obvious.
I found this in amqp_network_connection.erl, which looks like a wrapper to set some default values:
client_properties(UserProperties) ->
{ok, Vsn} = application:get_key(amqp_client, vsn),
Default = [{<<"product">>, longstr, <<"RabbitMQ">>},
{<<"version">>, longstr, list_to_binary(Vsn)},
{<<"platform">>, longstr, <<"Erlang">>},
{<<"copyright">>, longstr,
<<"Copyright (c) 2007-2012 VMware, Inc.">>},
{<<"information">>, longstr,
<<"Licensed under the MPL. "
"See http://www.rabbitmq.com/">>},
{<<"capabilities">>, table, ?CLIENT_CAPABILITIES}],
lists:foldl(fun({K, _, _} = Tuple, Acc) ->
lists:keystore(K, 1, Acc, Tuple)
end, Default, UserProperties).
Apparently the atom describes the value type. I don't know the available types, but there's a chance that longstr will work in your case.
I have some apps in my cluster, I need to start some of them sometimes on different hosts.
The story is that the Erlang cluster is already running, so even though I have my .app resource file per application stating which applications should be started before mine, this only works to create a startup script, not to start an app in a already running node.
At the moment I have a custom routine that uses application:get_key(Application,applications) to extract the dependencies and start them separately before starting the given application.
I was wondering if there isn't a better way of doing this.
Since Erlang R16B02, there is also application:ensure_all_started.
Frankly, the standard tools for doing this in Erlang are unnecessarily annoying right now. I tend to put the following boiler-plate in my application callback module:
-module(myapp_app).
-export([start/0]).
start() -> a_start(myapp, permanent).
a_start(App, Type) ->
start_ok(App, Type, application:start(App, Type)).
start_ok(_App, _Type, ok) -> ok;
start_ok(_App, _Type, {error, {already_started, _App}}) -> ok;
start_ok(App, Type, {error, {not_started, Dep}}) ->
ok = a_start(Dep, Type),
a_start(App, Type);
start_ok(App, _Type, {error, Reason}) ->
erlang:error({app_start_failed, App, Reason}).
You can then add -s myapp_app to your erlang command line and this will start the app and all its dependencies recursively. Why this function isn't in the application module I don't know :)
There is a working example of this custom erlang app startup code in my Erlang Factory 2012 SFBay example app.
When starting the app outside of the startup script you do need to start the dependencies first. You could build the smarts to do this into the app itself so that when the app starts it will start any required dependencies before it needs them.
One place I've seen this done is in Mochiweb apps. The default app templates include code for loading dependencies on startup:
-module(some_app).
-export([start/0, stop/0]).
ensure_started(App) ->
case application:start(App) of
ok ->
ok;
{error, {already_started, App}} ->
ok
end.
%% #spec start() -> ok
%% #doc Start the some_app server.
start() ->
some_app_deps:ensure(),
ensure_started(crypto),
application:start(some_app).
%% #spec stop() -> ok
%% #doc Stop the some_app server.
stop() ->
application:stop(some_app).
If you write your app under "OTP Design Principles", you will have to make yourappname.app file, which will contains `applications' section. This section defines which other applications you want to be started before yours. Here is stated:
applications
All applications which must be started before this
application is started. systools uses this list to generate correct
boot scripts. Defaults to [], but note that all applications have
dependencies to at least kernel and stdlib.
So if you use releases, this dependency resolution will be solved by systools.
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).
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.