Merge branch 'master' of github.com:emqtt/emqttd

This commit is contained in:
huangdan 2015-05-05 12:20:04 +08:00
commit 48e893c016
35 changed files with 362 additions and 699 deletions

View File

@ -2,6 +2,18 @@
emqttd ChangeLog emqttd ChangeLog
================== ==================
0.7.1-alpha (2015-05-04)
-------------------------
Add doc/design/* and merge doc/* to github Wiki
Bugfix: issue #121 - emqttd cluster issuse
Bugfix: issue #123 - emqttd:unload_all_plugins/0 cannot unload any plugin
Bugfix: fix errors found by dialyzer
0.7.0-alpha (2015-05-02) 0.7.0-alpha (2015-05-02)
------------------------- -------------------------

View File

@ -5,15 +5,18 @@ emqttd is a massively scalable and clusterable MQTT V3.1/V3.1.1 broker written i
emqttd requires Erlang R17+ to build. emqttd requires Erlang R17+ to build.
## Goals ## Goals
emqttd aims to provide a solid, enterprise grade open-source MQTT broker that could support ten millions of concurrent MQTT clients. emqttd is aimed to provide a solid, enterprise grade, extensible open-source MQTT broker for IoT(M2M) applications that need to support ten millions of concurrent MQTT clients.
## Architecture * Easy to install
* Massively scalable
* Easy to extend
* Solid stable
![emqttd architecture](http://emqtt.io/static/img/Architecture.png)
## Featues ## Features
* Full MQTT V3.1/V3.1.1 protocol specification support * Full MQTT V3.1/V3.1.1 protocol specification support
* QoS0, QoS1, QoS2 Publish and Subscribe * QoS0, QoS1, QoS2 Publish and Subscribe
@ -25,7 +28,7 @@ emqttd aims to provide a solid, enterprise grade open-source MQTT broker that co
* HTTP Publish API Support * HTTP Publish API Support
* [$SYS/borkers/#](https://github.com/emqtt/emqtt/wiki/$SYS-Topics-of-Broker) Support * [$SYS/borkers/#](https://github.com/emqtt/emqtt/wiki/$SYS-Topics-of-Broker) Support
* Client Authentication with clientId, ipaddress * Client Authentication with clientId, ipaddress
* Client Authentication with username, password. * Client Authentication with username, password.
* Client ACL control with ipaddress, clientid, username. * Client ACL control with ipaddress, clientid, username.
* Cluster brokers on several servers. * Cluster brokers on several servers.
* Bridge brokers locally or remotelly * Bridge brokers locally or remotelly
@ -33,11 +36,19 @@ emqttd aims to provide a solid, enterprise grade open-source MQTT broker that co
* Extensible architecture with plugin support * Extensible architecture with plugin support
* Passed eclipse paho interoperability tests * Passed eclipse paho interoperability tests
## Design
![emqttd architecture](http://emqtt.io/static/img/Architecture.png)
## QuickStart ## QuickStart
Download binary packeges for linux, mac and freebsd from [http://emqtt.io/downloads](http://emqtt.io/downloads). Download binary packeges for linux, mac and freebsd from [http://emqtt.io/downloads](http://emqtt.io/downloads).
``` For example:
```sh
tar xvf emqttd-ubuntu64-0.7.0-alpha.tgz && cd emqttd tar xvf emqttd-ubuntu64-0.7.0-alpha.tgz && cd emqttd
# start console # start console
@ -61,9 +72,11 @@ git clone https://github.com/emqtt/emqttd.git
cd emqttd && make && make dist cd emqttd && make && make dist
``` ```
## GetStarted ## GetStarted
Read [GettingStarted](https://github.com/emqtt/emqttd/wiki/GettingStarted) for more installation and configuration guide. Read [emqtt wiki](https://github.com/emqtt/emqttd/wiki) for detailed installation and configuration guide.
## Benchmark ## Benchmark
@ -71,17 +84,20 @@ Benchmark 0.6.1-alpha on a ubuntu/14.04 server with 8 cores, 32G memory from Qin
200K+ Connections, 200K+ Topics, 20K+ In/Out Messages/sec, 20Mbps+ In/Out with 8G Memory, 50%CPU/core 200K+ Connections, 200K+ Topics, 20K+ In/Out Messages/sec, 20Mbps+ In/Out with 8G Memory, 50%CPU/core
## License ## License
The MIT License (MIT) The MIT License (MIT)
## Contributors ## Contributors
[@hejin1026](https://github.com/hejin1026) [@hejin1026](https://github.com/hejin1026)
[@desoulter](https://github.com/desoulter) [@desoulter](https://github.com/desoulter)
[@turtleDeng](https://github.com/turtleDeng) [@turtleDeng](https://github.com/turtleDeng)
[@Hades32](https://github.com/Hades32)
[@huangdan](https://github.com/huangdan)
## Author ## Author

View File

@ -1,7 +1,7 @@
{application, emqtt, {application, emqtt,
[ [
{description, "Erlang MQTT Common Library"}, {description, "Erlang MQTT Common Library"},
{vsn, "0.7.0"}, {vsn, "0.7.1"},
{modules, []}, {modules, []},
{registered, []}, {registered, []},
{applications, [ {applications, [

View File

@ -1,7 +1,7 @@
{application, emqttd, {application, emqttd,
[ [
{description, "Erlang MQTT Broker"}, {description, "Erlang MQTT Broker"},
{vsn, "0.7.0"}, {vsn, "0.7.1"},
{modules, []}, {modules, []},
{registered, []}, {registered, []},
{applications, [kernel, {applications, [kernel,

View File

@ -162,7 +162,7 @@ loaded_plugins() ->
-spec unload_all_plugins() -> [{App :: atom(), ok | {error, any()}}]. -spec unload_all_plugins() -> [{App :: atom(), ok | {error, any()}}].
unload_all_plugins() -> unload_all_plugins() ->
PluginApps = application:get_env(emqttd, plugins, []), PluginApps = application:get_env(emqttd, plugins, []),
[{App, unload_plugin(App)} || {App, _Env} <- PluginApps]. [{App, unload_plugin(App)} || App <- PluginApps].
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------

View File

@ -31,7 +31,7 @@
-behaviour(application). -behaviour(application).
%% Application callbacks %% Application callbacks
-export([start/2, stop/1]). -export([start/2, prep_stop/1, stop/1]).
-define(PRINT_MSG(Msg), io:format(Msg)). -define(PRINT_MSG(Msg), io:format(Msg)).
@ -47,24 +47,24 @@
State :: term(), State :: term(),
Reason :: term(). Reason :: term().
start(_StartType, _StartArgs) -> start(_StartType, _StartArgs) ->
print_banner(), print_banner(),
emqttd_mnesia:start(), emqttd_mnesia:start(),
{ok, Sup} = emqttd_sup:start_link(), {ok, Sup} = emqttd_sup:start_link(),
start_servers(Sup), start_servers(Sup),
{ok, Listeners} = application:get_env(listeners), {ok, Listeners} = application:get_env(listeners),
emqttd:load_all_plugins(), emqttd:load_all_plugins(),
emqttd:open_listeners(Listeners), emqttd:open_listeners(Listeners),
register(emqttd, self()), register(emqttd, self()),
print_vsn(), print_vsn(),
{ok, Sup}. {ok, Sup}.
print_banner() -> print_banner() ->
?PRINT("starting emqttd on node '~s'~n", [node()]). ?PRINT("starting emqttd on node '~s'~n", [node()]).
print_vsn() -> print_vsn() ->
{ok, Vsn} = application:get_key(vsn), {ok, Vsn} = application:get_key(vsn),
{ok, Desc} = application:get_key(description), {ok, Desc} = application:get_key(description),
?PRINT("~s ~s is running now~n", [Desc, Vsn]). ?PRINT("~s ~s is running now~n", [Desc, Vsn]).
start_servers(Sup) -> start_servers(Sup) ->
Servers = [{"emqttd event", emqttd_event}, Servers = [{"emqttd event", emqttd_event},
@ -128,10 +128,16 @@ worker_spec(Name, Opts) ->
{Name, start_link, [Opts]}, {Name, start_link, [Opts]},
permanent, 10000, worker, [Name]}. permanent, 10000, worker, [Name]}.
%% close all listeners first...
prep_stop(State) ->
%%TODO: esockd app should be running...
{ok, Listeners} = application:get_env(listeners),
emqttd:close_listeners(Listeners),
timer:sleep(2),
State.
-spec stop(State :: term()) -> term(). -spec stop(State :: term()) -> term().
stop(_State) -> stop(_State) ->
{ok, Listeners} = application:get_env(listeners),
emqttd:close_listeners(Listeners),
emqttd:unload_all_plugins(),
ok. ok.

View File

@ -74,7 +74,7 @@ start_bridge(Node, SubTopic, Options) when is_atom(Node) and is_binary(SubTopic)
-spec stop_bridge(atom(), binary()) -> {ok, pid()} | ok. -spec stop_bridge(atom(), binary()) -> {ok, pid()} | ok.
stop_bridge(Node, SubTopic) -> stop_bridge(Node, SubTopic) ->
ChildId = bridge_id(Node, SubTopic), ChildId = bridge_id(Node, SubTopic),
case supervisor:terminate_child(ChildId) of case supervisor:terminate_child(?MODULE, ChildId) of
ok -> ok ->
supervisor:delete_child(?MODULE, ChildId); supervisor:delete_child(?MODULE, ChildId);
{error, Reason} -> {error, Reason} ->

View File

@ -57,10 +57,10 @@ status([]) ->
{InternalStatus, _ProvidedStatus} = init:get_status(), {InternalStatus, _ProvidedStatus} = init:get_status(),
?PRINT("Node ~p is ~p~n", [node(), InternalStatus]), ?PRINT("Node ~p is ~p~n", [node(), InternalStatus]),
case lists:keysearch(emqttd, 1, application:which_applications()) of case lists:keysearch(emqttd, 1, application:which_applications()) of
false -> false ->
?PRINT_MSG("emqttd is not running~n"); ?PRINT_MSG("emqttd is not running~n");
{value,_Version} -> {value,_Version} ->
?PRINT_MSG("emqttd is running~n") ?PRINT_MSG("emqttd is running~n")
end. end.
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
@ -72,32 +72,41 @@ cluster([]) ->
?PRINT("cluster nodes: ~p~n", [Nodes]); ?PRINT("cluster nodes: ~p~n", [Nodes]);
cluster([SNode]) -> cluster([SNode]) ->
Node = node_name(SNode), Node = node_name(SNode),
case net_adm:ping(Node) of case net_adm:ping(Node) of
pong -> pong ->
application:stop(emqttd), case emqttd:is_running(Node) of
application:stop(esockd), true ->
emqttd_mnesia:cluster(Node), %%TODO: should not unload here.
application:start(esockd), emqttd:unload_all_plugins(),
application:start(emqttd), application:stop(emqttd),
?PRINT("cluster with ~p successfully.~n", [Node]); application:stop(esockd),
pang -> application:stop(gproc),
emqttd_mnesia:cluster(Node),
application:start(gproc),
application:start(esockd),
application:start(emqttd),
?PRINT("cluster with ~p successfully.~n", [Node]);
false ->
?PRINT("emqttd is not running on ~p~n", [Node])
end;
pang ->
?PRINT("failed to connect to ~p~n", [Node]) ?PRINT("failed to connect to ~p~n", [Node])
end. end.
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
%% @doc Add usern %% @doc Add usern
%% @end %% @end
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
useradd([Username, Password]) -> useradd([Username, Password]) ->
?PRINT("~p~n", [emqttd_auth_username:add_user(bin(Username), bin(Password))]). ?PRINT("~p~n", [emqttd_auth_username:add_user(bin(Username), bin(Password))]).
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
%% @doc Delete user %% @doc Delete user
%% @end %% @end
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
userdel([Username]) -> userdel([Username]) ->
?PRINT("~p~n", [emqttd_auth_username:remove_user(bin(Username))]). ?PRINT("~p~n", [emqttd_auth_username:remove_user(bin(Username))]).
vm([]) -> vm([]) ->
[vm([Name]) || Name <- ["load", "memory", "process", "io"]]; [vm([Name]) || Name <- ["load", "memory", "process", "io"]];

View File

@ -114,5 +114,5 @@ payload(connected, Params) ->
iolist_to_binary(io_lib:format("from: ~s~nprotocol: ~p~nsession: ~s", [From, Proto, Sess])); iolist_to_binary(io_lib:format("from: ~s~nprotocol: ~p~nsession: ~s", [From, Proto, Sess]));
payload(disconnected, Reason) -> payload(disconnected, Reason) ->
list_to_binary(io_lib:format(["reason: ~p", Reason])). list_to_binary(io_lib:format("reason: ~p", [Reason])).

View File

@ -1,199 +0,0 @@
# eMQTT Get Started
## Overview
eMQTT is a clusterable, massively scalable, fault-tolerant and extensible MQTT V3.1/V3.1.1 broker written in Erlang/OTP.
eMQTT is aimed to provide a solid-stable broker that could be clusterd to support millions of connections and clients.
## Requires
eMQTT is cross-platform, could run on windows, linux, freebsd and mac os x.
eMQTT requires Erlang R17+ to build from source.
## Featues
### Full MQTT V3.1.1 Support
MQTT V3.1.1 and V3.1 protocol support
QoS0, QoS1, QoS2 Publish and Subscribe
Session Management and Offline Messages
Retained Messages
Passed eclipse paho interoperability tests
### Clusterable, Massively Scalable
Massive Connections Clients Support
Cluster brokers on servers or cloud hosts
Bridge brokers locally or remotelly
## Download, Install
### Download
Dowload binary packages from [http://emqtt.io/downloads](http://emqtt.io/downloads].
Please build from source if no packages for your platform, or contact us.
### Install
Extract tgz package to your installed directory. for example:
```
tar xvf emqtt-ubuntu64-0.3.0-beta.tgz && cd emqtt
```
### Startup
Startup console for debug:
```
cd emqtt && ./bin/emqtt console
```
You could see all RECV/SENT MQTT Packages on console.
Start as daemon:
```
cd emqtt && ./bin/emqtt start
```
eMQTT occupies 1883 port for MQTT, 8083 for HTTP API.
### Status
```
cd emqtt && ./bin/emqtt_ctl status
```
### Stop
```
cd emqtt && ./bin/emqtt stop
```
## Configuration
### etc/app.config
```
{emqtt, [
%Authetication. Internal, Anonymous Default.
{auth, {anonymous, []}},
{access, []},
{session, [
{expires, 1}, %hours
{max_queue, 1000},
{store_qos0, false}
]},
{retain, [
{store_limit, 100000}
]},
{listen, [
{mqtt, 1883, [
{acceptors, 4},
{max_conns, 1024}
]},
{http, 8083, [
{acceptors, 1},
{max_conns, 512}
]}
]}
]}
```
### etc/vm.args
```
-name emqtt@127.0.0.1
-setcookie emqtt
```
## Cluster
Suppose we cluster two nodes on 'host1', 'host2', Steps:
### configure and start node on host1
configure 'etc/vm.args':
```
-name emqtt@host1
```
then start:
```
./bin/emqtt start
```
### configure and start node on host2
configure 'etc/vm.args':
```
-name emqtt@host2
```
```
./bin/emqtt start
```
### cluster two nodes
Cluster from 'host2':
```
./bin/emqtt_ctl cluster emqtt@host1
```
or cluster from 'host1':
```
./bin/emqtt_ctl cluster emqtt@host2
```
then check clustered nodes on any host:
```
./bin/emqtt_ctl cluster
```
## HTTP API
eMQTT support HTTP API to publish message from your APP to MQTT client.
Example:
```
curl -v --basic -u user:passwd -d "qos=1&retain=0&topic=/a/b/c&message=hello from http..." -k http://localhost:8083/mqtt/publish
```
### URL
```
HTTP POST http://host:8083/mqtt/publish
```
### Parameters
Name | Description
--------|---------------
qos | QoS(0, 1, 2)
retain | Retain(0, 1)
topic | Topic
message | Message
## Contact
feng@emqtt.io

View File

@ -1,30 +0,0 @@
# ACL
## Protocol
Authentication of users and devices
Authorization of access to Server resources
An implementation may restrict access to Server resources based on information provided by the Client such as User Name, Client Identifier, the hostname/IP address of the Client, or the outcome of authentication mechanisms.
Identify a MQTT User: Peername, ClientId, Username
## Access Rule
allow | deny Who subscribe | publish Topic | all
allow {clientid, {regexp, "abcd"}} subscribe "anna"
deny {clientid, "xxxx"} publish "#"
allow {clientid, "abcd"} publish "#"
allow {peername, "127.0.0.1"} subscribe "$SYS/#"
allow {peername, "127.0.0.1"} subscribe all
allow {clientid, "clientid"} subscribe "#"
allow {clientid, {regexp, "abcd"}} publish "anna"
allow all subscribe all
deny all subscribe all
allow all
deny all

View File

@ -1,34 +0,0 @@
# Broker Topics
## Version
$SYS/broker/version
## Uptime
$SYS/broker/uptime
## Recevied and Sent
$SYS/broker/bytes/received
$SYS/broker/bytes/sent
$SYS/broker/packets/received
$SYS/broker/packets/sent
$SYS/broker/messages/received
$SYS/broker/messages/sent
$SYS/broker/messages/retained
$SYS/broker/messages/stored
$SYS/broker/messages/dropped
## Client Presence
$SYS/broker/clients/connected
$SYS/broker/clients/disconnected
$SYS/broker/clients/${clientId}/presences/online
$SYS/broker/clients/${clientId}presences/offline

View File

@ -1,25 +0,0 @@
zookeeper
|
eMQTT1 eMQTT2 eMQTT3
Bridge
eMQTT1 --> eMQTT2
Cluster
eMQTT1 <--> eMQTT2
Cluster and Bridge
eMQTT1 eMQTT3
---->
eMQTT2 eMQTT4
Mnesia Cluster

View File

@ -1,37 +0,0 @@
# eMQTT Desgin Guide
## KeepAlive
## Retained
## QOS1
## QOS2
## Durable Subscriptions
Durable Sub:
Client->Queue->Router->Queue->Client
Normal Sub:
Client->Router->Client
Router to register queues
## Topic Tree
## Offline Message
## ACL
## Authentication with clientId
## SSL/TLS Socket
## $SYS/topics and Broker statistics...
## Cluster
## Bridge

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.13-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="44.0" x="130.0" y="200.0"/>
<y:Fill color="#3182BD" transparent="false"/>
<y:BorderStyle color="#3182BD" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.6328125" x="16.68359375" y="13.43359375">P<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n1">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="44.0" x="130.0" y="279.0"/>
<y:Fill color="#756BB1" transparent="false"/>
<y:BorderStyle color="#756BB1" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.6328125" x="16.68359375" y="13.43359375">P<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n2">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="44.0" x="458.0" y="202.5"/>
<y:Fill color="#756BB1" transparent="false"/>
<y:BorderStyle color="#756BB1" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.462890625" x="16.7685546875" y="13.43359375">S<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n3">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="44.0" x="458.0" y="277.5"/>
<y:Fill color="#3182BD" transparent="false"/>
<y:BorderStyle color="#3182BD" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.462890625" x="16.7685546875" y="13.43359375">S<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n4">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="124.0" width="125.0" x="250.0" y="193.0"/>
<y:Fill color="#74C476" transparent="false"/>
<y:BorderStyle color="#74C476" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="60.5" y="60.0">
<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n5">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="17.0" width="16.0" x="333.0" y="246.5"/>
<y:Fill color="#FD8D3C" transparent="false"/>
<y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.587890625" x="2.2060546875" y="-0.56640625">#<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n6">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="17.0" width="16.0" x="292.0" y="246.5"/>
<y:Fill color="#FD8D3C" transparent="false"/>
<y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="13.5390625" x="1.23046875" y="-0.56640625">+<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n7">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="17.0" width="16.0" x="273.0" y="277.5"/>
<y:Fill color="#FD8D3C" transparent="false"/>
<y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.359375" x="2.3203125" y="-0.56640625">x<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n8">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="17.0" width="16.0" x="308.0" y="277.5"/>
<y:Fill color="#FD8D3C" transparent="false"/>
<y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.26953125" x="2.865234375" y="-0.56640625">y<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<node id="n9">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="17.0" width="16.0" x="308.0" y="216.5"/>
<y:Fill color="#FD8D3C" transparent="false"/>
<y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="8.48828125" x="3.755859375" y="-0.56640625">t<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="ellipse"/>
</y:ShapeNode>
</data>
</node>
<edge id="e0" source="n0" target="n3">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
<y:Point x="270.0" y="222.5"/>
<y:Point x="360.0" y="300.0"/>
</y:Path>
<y:LineStyle color="#3182BD" type="dashed" width="1.0"/>
<y:Arrows source="none" target="plain"/>
<y:BendStyle smoothed="true"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n1" target="n2">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
<y:Point x="270.0" y="300.0"/>
<y:Point x="360.0" y="225.0"/>
</y:Path>
<y:LineStyle color="#756BB1" type="dashed" width="1.0"/>
<y:Arrows source="none" target="plain"/>
<y:BendStyle smoothed="true"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n6" target="n9">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n7" target="n6">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n8" target="n6">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n9" target="n5">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources/>
</data>
</graphml>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1 +0,0 @@
packet, message handler chain???

BIN
doc/mqtt-v3.1.1-os.pdf Normal file

Binary file not shown.

View File

@ -1,36 +0,0 @@
# MQTT Protocol Guide
## Server or Broker
A program or device that acts as an intermediary between Clients which publish Application Messages and Clients which have made Subscriptions.
A Server Accepts Network Connections from Clients.
Accepts Application Messages published by Clients.
Processes Subscribe and Unsubscribe requests from Clients.
Forwards Application Messages that match Client Subscriptions.
Client ----> Broker(Server) ----> Client
Publisher ----> Broker -----> Subscriber
## Subscription and Session
### Subscription
A Subscription comprises a Topic Filter and a maximum QoS. A Subscription is associated with a single Session. A Session can contain more than one Subscription. Each Subscription within a session has a different Topic Filter.
### Session
A stateful interaction between a Client and a Server. Some Sessions last only as long as the Network
Connection, others can span multiple consecutive Network Connections between a Client and a Server.
## Topic Name and Filter
An expression contained in a Subscription, to indicate an interest in one or more topics. A Topic Filter can include wildcard characters.
## Packet Identifier

View File

@ -1,40 +0,0 @@
# PubSub
## Qos
PubQos | SubQos | In Message | Out Message
-------|--------|------------|-------------
0 | 0 | - | -
0 | 1 | - | -
0 | 2 | - | -
1 | 0 | - | -
1 | 1 | - | -
1 | 2 | - | -
2 | 0 | - | -
2 | 1 | - | -
2 | 2 | - | -
## Publish
## Performance
Mac Air(11):
Function | Time(microseconds)
-------------|--------------------
match | 6.25086
triples | 13.86881
words | 3.41177
binary:split | 3.03776
iMac:
Function | Time(microseconds)
-------------|--------------------
match | 3.2348
triples | 6.93524
words | 1.89616
binary:split | 1.65243

View File

@ -1,133 +0,0 @@
## Quick Start
## Startup in Five Minutes
```
$ git clone git://github.com/emqtt/emqttd.git
$ cd emqttd
$ make && make dist
$ cd rel/emqttd
$ ./bin/emqttd console
```
## Deploy and Start
### start
```
cp -R rel/emqttd $INSTALL_DIR
cd $INSTALL_DIR/emqttd
./bin/emqttd start
```
### stop
```
./bin/emqttd stop
```
## Configuration
### etc/app.config
```
{emqttd, [
{auth, {anonymous, []}}, %internal, anonymous
{listen, [
{mqtt, 1883, [
{acceptors, 4},
{max_clients, 1024}
]},
{mqtts, 8883, [
{acceptors, 4},
{max_clients, 1024},
%{cacertfile, "etc/ssl/cacert.pem"},
{ssl, [{certfile, "etc/ssl.crt"},
{keyfile, "etc/ssl.key"}]}
]},
{http, 8083, [
{acceptors, 1},
{max_clients, 512}
]}
]}
]}
```
### etc/vm.args
```
-name emqttd@127.0.0.1
-setcookie emqtt
```
When nodes clustered, vm.args should be configured as below:
```
-name emqttd@host1
```
## Cluster
Suppose we cluster two nodes on 'host1', 'host2', Steps:
on 'host1':
```
./bin/emqttd start
```
on 'host2':
```
./bin/emqttd start
./bin/emqttd_ctl cluster emqttd@host1
```
Run './bin/emqttd_ctl cluster' on 'host1' or 'host2' to check cluster nodes.
## HTTP API
emqttd support http to publish message.
Example:
```
curl -v --basic -u user:passwd -d "qos=1&retain=0&topic=a/b/c&message=hello from http..." -k http://localhost:8083/mqtt/publish
```
### URL
```
HTTP POST http://host:8083/mqtt/publish
```
### Parameters
Name | Description
--------|---------------
qos | QoS(0, 1, 2)
retain | Retain(0, 1)
topic | Topic
message | Message
## Contributors
@hejin1026 <260495915 at qq.com>
@desoulter <assoulter123 at gmail.com>
@turtleDeng

View File

@ -1,6 +0,0 @@
# Retained Message
## API
store(

View File

@ -1,19 +0,0 @@
ClientA -> SessionA -> Route -> PubSub -> SessionB -> ClientB
ClientA -> Session -> PubSub -> Route -> SessionB -> ClientB
| |
Trie Subscriber
ClientPidA -> ClientPidB
ClientPidA -> SessionPidB -> ClientB
ClientPidA -> SessionPidA -> SessionPidB -> ClientPidB

View File

@ -1,50 +0,0 @@
# Session Design
## session manager
```erlang
%% lookup sesssion
emqtt_sm:lookup_session(ClientId)
%% Start new or resume existing session
emqtt_sm:start_session(ClientId)
%% destroy session, discard all data
emqtt_sm:destory_session(ClientId)
%% close session, save all data
emqtt_sm:close_session(ClientId)
```
## session supervisor
usage?
## session
```
%%system process
process_flag(trap_exit, true),
session:start()
session:subscribe(
session:publish(
session:resume(
session:suspend(
%%destory all data
session:destory(
%%save all data
session:close()
```
## sm and session
sm manage and monitor session
## client and session
client(normal process)<--link to -->session(system process)

View File

@ -1,4 +0,0 @@
client state --> parse_state
--> proto_state --> session_state

View File

@ -1,4 +0,0 @@
# eMQTT $SYS Topics
Wiki: [$SYS Topics of Broker](https://github.com/emqtt/emqtt/wiki/$SYS-Topics-of-Broker)

View File

@ -1,22 +0,0 @@
Topic Types:
static:
/brokers/alerts/
/brokers/clients/connected
/brokers/clients/disconnected
dynamic:
created when subscribe...
bridge:
cretated when bridge...
## Create Topics
emqttd_pubsub:create(Type, Name)
emqttd_pubsub:create(#topic{name = Name, node= node(), type = Type}).

View File

@ -1,14 +0,0 @@
# eMQTT User Guide
## Introduction
## Installation
### Install Requirements
## Configuration
## Cluster
## Bridge

View File

@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------------- %%%-----------------------------------------------------------------------------
%% %%
%% [ACL Design](https://github.com/emqtt/emqttd/wiki/ACL-Design) %% [ACL](https://github.com/emqtt/emqttd/wiki/ACL)
%% %%
%% -type who() :: all | binary() | %% -type who() :: all | binary() |
%% {ipaddr, esockd_access:cidr()} | %% {ipaddr, esockd_access:cidr()} |