2016/11/26

STOMP/MQTT 通訊協定的測試心得(client/server)

STOMP 通訊協定的測試心得(client/server)

STOMP 是啥東西? 
STOMP 是 Simple (or Streaming) Text Oriented Message Protocol 的縮寫
主要提供一個可以操作的通訊界面,可以支援不同平台的的客戶端交換文字訊息。它屬於一個訊息導向的中介軟體。這個服務類似 HTTP ,並且架構於 TCP 上面。
ref: https://segmentfault.com/a/1190000004906137 功能示意圖


用來搭建 IM (即時通訊服務) 是很簡單好用的中介工具
https://segmentfault.com/a/1190000004906137 

這裡有目前常見的訊息中介軟體的比較介紹 amqp mqtt or stomp
http://blogs.vmware.com/vfabric/2013/02/choosing-your-messaging-protocol-amqp-mqtt-or-stomp.html

建議和 html5 websocket 一起看,比較容易理解它到底再做啥? P66 頁開始。
http://www.slideshare.net/peterlubbers/html5-real-time-and-websocket/94-Learn_More_HTML5_User_Groups

這裡有 function 功能規格說明
https://mq.java.net/4.4-content/stomp-funcspec.html

這個大概就是目前的官方網站了
https://github.com/stomp-php/stomp-php/wiki

這個服務主要構過 broker 來提供服務,目前 broker 的軟體有很多種可以提供。

broker -- STOMP Servers
broker -- STOMP Servers 的列表,常用的。
https://stomp.github.io/implementations.html
我裡以 apache apollo 這套 activemq 的子專案,來做說明。

Apollo 1.7.1 版本,下載我是以 Linux 版來說明
http://activemq.apache.org/apollo/download.html

提供有 4 種存取的方式
WS  --  TCP + Websocket
WSS -- TCP + TLS + Websocket
HTTP -- TCP + HTTP
HTTPS -- TCP + TLS + HTTP
ref: http://www.slideshare.net/peterlubbers/html5-real-time-and-websocket/78-ws_and_wss_schemes_78


// 安裝說明文件
http://activemq.apache.org/apollo/documentation/getting-started.html

解開檔案後,我把它放在 /opt 上面 , 並使用這個程式建立一個 broker 名稱為 jangmtbroker 放在 /var/lib/ 上面
# /opt/apache-apollo-1.7.1/bin/apollo create jangmtbroker
Creating apollo instance at: jangmtbroker
Generating ssl keystore...

You can now start the broker by executing:

   "/var/lib/jangmtbroker/bin/apollo-broker" run

Or you can setup the broker as system service and run it in the background:

   sudo ln -s "/var/lib/jangmtbroker/bin/apollo-broker-service" /etc/init.d/
   /etc/init.d/apollo-broker-service start
 
* 設定為啟動的服務
# sudo ln -s "/var/lib/jangmtbroker/bin/apollo-broker-service" /etc/init.d/
* 接下來,就可以透過底下指令啟動它
# /etc/init.d/apollo-broker-service start


* 啟動後會有一個管理界面 Web Administration 預設只開放 127.0.0.1 可以改的
* 如果要修改可以參考 etc 下面的 xml 設定檔。
http://127.0.0.1:61680/ or https://127.0.0.1:61681/
* 預設帳密 admin and password.

# 在系統會看到 appolo 的 port
# netstat -antlp | grep apollo
tcp6       0      0 :::61613                :::*                    LISTEN      11471/apollo      
tcp6       0      0 :::61614                :::*                    LISTEN      11471/apollo      
tcp6       0      0 127.0.0.1:61680         :::*                    LISTEN      11471/apollo      
tcp6       0      0 127.0.0.1:61681         :::*                    LISTEN      11471/apollo      
tcp6       0      0 :::61623                :::*                    LISTEN      11471/apollo      
tcp6       0      0 :::61624                :::*                    LISTEN      11471/apollo      
tcp6       0      0 :::32777                :::*                    LISTEN      11471/apollo      
tcp6       0      0 127.0.0.1:61680         127.0.0.1:53532         ESTABLISHED 11471/apollo      
tcp6       0      0 127.0.0.1:61680         127.0.0.1:53536         ESTABLISHED 11471/apollo

* 防火牆記得要開這幾個 port


* 當然,預設密碼很危險,可以參考下列文件修改預設帳密
https://activemq.apache.org/apollo/documentation/user-manual.html#Using_Custom_Login_Modules

* apollo.xml 為系統主要設定檔, 可以針對 access_rule 設定權限
ex: 允許群組 admins 可以操作所有的動作
access_rule action="*" allow="admins"ex: 允許群組 monotors  可以操作連線及觀看系統狀態的功能
access_rule action="connect monitor" allow="monitors"
ex: 允許群組 appusers 可以操作連線、建立、送出、接收訊息
access_rule action="connect create send receive consume" allow="appusers"
ex: 允許群組 appusers 可以操作連線、建立、接收訊息
access_rule action="connect create  receive consume" allow="users"
透過這樣的區隔,可以仔細的分別設定不同的權限群組。

# 設定個別使用者的密碼,也可以用加密 ENC 方式設定
[root@dev etc]# grep -v '#' users.properties
# 帳號=密碼
mtchang=密碼
demo=密碼
app1=密碼

# 將使用者,分配到不同的群組,一個群組如果需要很多人可以使用 | 符號連接。
[root@dev etc]# grep -v '#' groups.properties
admins=mtchang
monitors=admin
users=demo
appusers=app1


# 以上,這樣 server 端就好了。
// --------------------------------------------------

* 客戶端工具有很多選擇, 我找了一個 STOMP Over WebSocket 的專案,使用 browser 就可以用了。
http://jmesnil.net/stomp-websocket/doc/
這個有說明如何使用 websocket api 來操作


* 主要我想要做一個線上即時聊天的界面,從 github 上找到 jmesnil 的 source code
https://github.com/jmesnil/stomp-websocket/tree/master/example
然後,小小修改一下。

我的個人小小聊天室,就出現了。你只要開兩個 browser 就可以自己和自己聊天了。

http://jangmt.com/stompchat/chat/  (純接收訊息)
http://jangmt.com/stompchat/chat/send.php  (送出訊息測試)


// 發送訊息到指定的 STOMP broker
// ----
$user = "app1";
$password = "密碼";
$host = "主機.jangmt.com";
$port = 61613;
$destination  = '/topic/chat.general.demo';
$message_body1 = '5秒消失_'.date(DATE_RFC2822);
$message_body2 = 'sticky:黏住桌面'.date(DATE_RFC2822);
try {
  $url = 'tcp://'.$host.":".$port;
  $stomp = new Stomp($url, $user, $password);
  $stomp->send($destination, $message_body1);
  $stomp->send($destination, $message_body2);
  //$stomp->send($destination, "SHUTDOWN");
} catch(StompException $e) {
  echo $e->getMessage();
}
?>





這個中介軟體 Apache  Apollo 伺服器端的界面長成這樣,可以看到線上使用者的資源使用狀況。





// --------------------------------------------------
// 如果你的需求是在 php 上面,要撈一些 data 訊息,可以參考下面的資訊
// PHP 官方網站都有說明了
http://php.net/manual/en/book.stomp.php

// 在 PHP 上面執行,可以參考 wiki 上面的說明
http://nrodwiki.rockshore.net/index.php/PHP_Examples

// client 端 , 也可以用 php 記得裝 stomp 套件。
# yum install php71-php-pecl-stomp
// 驗證
# php71 -i | grep stomp
/etc/opt/remi/php71/php.d/40-stomp.ini,
stomp.default_broker => tcp://localhost:61613 => tcp://localhost:61613
stomp.default_connection_timeout_sec => 2 => 2
stomp.default_connection_timeout_usec => 0 => 0
stomp.default_password => no value => no value
stomp.default_read_timeout_sec => 2 => 2
stomp.default_read_timeout_usec => 0 => 0
stomp.default_username => no value => no value

以上經驗分享,打完收工。使用比較有經驗後再來分享使用心得。
該繼續寫程式了。....XDXD

2016/11/24

Enom DNS 服務的動態 dns 更新


Enom DNS 服務的動態 dns 更新

圖跟內文無關


最近因為工作關係,租了一台韓國的 aws 主機來當 vpn 服務,想說 ip 也不想固定,弄個動態 ip 更新好了。我的 dns 主機商是 enom 他在網路上有很多的自動更新的 script。

先提供一個有趣的網站,這網站可以用命令列反查所在的對外 public ip 很適合用來寫程式。
https://ifconfig.co/ 命令列及 API 版本的 myip address

另外有一個網站 https://www.ipip.net/ 可以查詢每個 ip 的所在地,是一個很好用的服務。
另外也提供 api 接入的功能,可以很方便的接程式。

官方網站提供的程式,右方有各種平台用的。
http://www.enom.com/help/faq_dynamicdns.asp 

下面是在 github 找到的,其實重點在 enom api server 提供的服務,每個程式只是包裝了一些個人化的需求。
Enom api server
ENOMURL="http://dynamic.name-services.com"

python version:
https://gist.github.com/stef-levesque/11229362

shell version:
https://gist.github.com/h0tw1r3/11405624

php version:
https://github.com/mrubinsk/phpEnomUpdate/blob/master/phpEnomUpdate.php

php 最簡單版本的 update.
https://gist.github.com/agarzon/2431219

// --------------------------------------------
# php 版本的更新程式
[root@ip-172-31-12-22 enom]# cat /root/enom/ip-update.php
#!/usr/bin/php

/* Run this script every 5 minutes (or 1 hour, is up to you) using a cron task */
// ref: https://gist.github.com/agarzon/2431219
/* Edit this data*/
$domain = "網域名稱 example.com ";  
$pass = "密碼";
$host = "A紀錄名稱"; // Optional, for additional hosts names like: ftp., mail. or any sub-domains.

// 底下三行僅供參考
//file_get_contents("http://dynamic.name-services.com/interface.asp?command=SetDNSHost&Zone=@.$domain&DomainPassword=$pass");
//file_get_contents("http://dynamic.name-services.com/interface.asp?command=SetDNSHost&Zone=www.$domain&DomainPassword=$pass");
//file_get_contents("http://dynamic.name-services.com/interface.asp?command=SetDNSHost&Zone=*.$domain&DomainPassword=$pass");
// 寫入 api service ,執行完後去查查看是否有這個 A 紀錄,或是 ip 更新了
file_get_contents("http://dynamic.name-services.com/interface.asp?command=SetDNSHost&Zone=$host.$domain&DomainPassword=$pass");
?>

寫入排程
[root@ip-172-31-12-22 enom]# crontab -l
*/30 * * * * /root/enom/ip-update.php