Просмотр исходного кода

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

huangdan 10 лет назад
Родитель
Сommit
48e893c016

+ 12 - 0
CHANGELOG.md

@@ -2,6 +2,18 @@
 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)
 -------------------------
 

+ 25 - 9
README.md

@@ -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.
 
+
 ## 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
 * 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
 * [$SYS/borkers/#](https://github.com/emqtt/emqtt/wiki/$SYS-Topics-of-Broker) Support
 * Client Authentication with clientId, ipaddress
-* Client Authentication with  username, password.
+* Client Authentication with username, password.
 * Client ACL control with ipaddress, clientid, username.
 * Cluster brokers on several servers.
 * 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
 * Passed eclipse paho interoperability tests
 
+
+## Design
+
+![emqttd architecture](http://emqtt.io/static/img/Architecture.png)
+
+
 ## QuickStart
 
 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
 
 # start console
@@ -61,9 +72,11 @@ git clone https://github.com/emqtt/emqttd.git
 cd emqttd && make && make dist
 ```
 
+
 ## 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
 
@@ -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
 
+
 ## License
 
 The MIT License (MIT)
 
+
 ## Contributors
 
 [@hejin1026](https://github.com/hejin1026)
-
 [@desoulter](https://github.com/desoulter)
-
 [@turtleDeng](https://github.com/turtleDeng)
+[@Hades32](https://github.com/Hades32)
+[@huangdan](https://github.com/huangdan)
+
 
 ## Author
 

+ 1 - 1
apps/emqtt/src/emqtt.app.src

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

+ 1 - 1
apps/emqttd/src/emqttd.app.src

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

+ 1 - 1
apps/emqttd/src/emqttd.erl

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

+ 19 - 13
apps/emqttd/src/emqttd_app.erl

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

+ 1 - 1
apps/emqttd/src/emqttd_bridge_sup.erl

@@ -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.
 stop_bridge(Node, SubTopic) ->
     ChildId = bridge_id(Node, SubTopic),
-    case supervisor:terminate_child(ChildId) of
+    case supervisor:terminate_child(?MODULE, ChildId) of
         ok -> 
             supervisor:delete_child(?MODULE, ChildId);
         {error, Reason} ->

+ 26 - 17
apps/emqttd/src/emqttd_ctl.erl

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

+ 1 - 1
apps/emqttd/src/emqttd_event.erl

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

+ 0 - 199
doc/GetStarted.md

@@ -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
-

+ 0 - 30
doc/acl.md

@@ -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
-

+ 0 - 34
doc/broker.md

@@ -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
-
-
-

+ 0 - 25
doc/cluster.md

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

+ 0 - 37
doc/design.md

@@ -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

doc/Architecture.png → doc/design/Architecture.png


doc/Architecture.graphml → doc/design/Design_Cluster.graphml


BIN
doc/design/Design_Cluster.png


+ 274 - 0
doc/design/Design_Standalone.graphml

@@ -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>

BIN
doc/design/Design_Standalone.png


BIN
doc/design/PubSub_CleanSess_0.png


BIN
doc/design/PubSub_CleanSess_1.png


+ 0 - 1
doc/hooks_chain.md

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

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


+ 0 - 36
doc/protocol.md

@@ -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
-
-

+ 0 - 40
doc/pubsub.md

@@ -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
-

+ 0 - 133
doc/quickstart.md

@@ -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

+ 0 - 6
doc/retain.md

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

+ 0 - 19
doc/route.md

@@ -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
-
-

+ 0 - 50
doc/session.md

@@ -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)
-
-

+ 0 - 4
doc/state_design.md

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

+ 0 - 4
doc/systopics.md

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

+ 0 - 22
doc/topic.md

@@ -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}).
-

+ 0 - 14
doc/user-guide.md

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

+ 0 - 0
plugins/emqttd_auth_mysql/.placehodler


+ 1 - 1
rel/files/acl.config

@@ -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() |
 %%               {ipaddr, esockd_access:cidr()} |