MQTTで遊ぶ(Java)
すっかりブログ書くのを放置してしまいましたが、前回MQTTサーバを導入しましたので、実際にコード書いてみます。
お仕事でプログラム書かなくなって久しいですが一番書ける言語はやっぱりJavaなので、Javaで。
・・・といっても、ここに書いてあることを試すだけですが^^; eclipse.org
設定
pom.xmlファイルを用意し次のように記入し、Java用MQTTクライアントを入手します。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> (中略) <repositories> <repository> <id>Eclipse Paho Repo</id> <url>https://repo.eclipse.org/content/repositories/paho-releases/</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.eclipse.paho</groupId> <artifactId>org.eclipse.paho.client.mqttv3</artifactId> <version>1.1.0</version> </dependency> </dependencies> </project>
これで、org.eclipse.paho.client.mqttv3-1.1.0.jarファイルが落ちてきました。
コード
次にコードを書きます。 コードの内容は、MQTTサーバに接続し、"test"のトピックに"Message from MqttPublishSample"というメッセージを投げるというものです。
※package文は省略 import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; public class Sample { public static void main(String[] args) { String topic = "test"; String content = "Message from MqttPublishSample"; int qos = 0; String broker = "tcp://***.***.***.***:1883"; String clientId = "JavaSample"; MemoryPersistence persistence = new MemoryPersistence(); try { MqttClient sampleClient = new MqttClient(broker, clientId, persistence); MqttConnectOptions connOpts = new MqttConnectOptions(); connOpts.setCleanSession(true); System.out.println("Connecting to broker: " + broker); sampleClient.connect(connOpts); System.out.println("Connected"); System.out.println("Publishing message: " + content); MqttMessage message = new MqttMessage(content.getBytes()); message.setQos(qos); sampleClient.publish(topic, message); System.out.println("Message published"); sampleClient.disconnect(); System.out.println("Disconnected"); System.exit(0); } catch (MqttException me) { me.printStackTrace(); } } }
確認
MQTTサーバを立ち上げます。
sudo vernemq start
前回も使用したPaho Clientでサーバにつなぎ、"test"トピックをSubscribeしておきます。
そして、先ほど書いたJavaプログラムを実行。
プログラムのコンソール
Paho Clientの画面
最下行のReceivedにある通り、testトピックのJavaプログラムから発行したメッセージをPaho Clientで受信することが出来ました。
MQTTで遊ぶ(導入編)
MQTTとは
次のURL参照で(他力本願)
ざっくり雑にまとめると、メッセージ配信に使用する軽量なプロトコルって感じでしょうか。
導入
MQTTを扱うサーバ(MQTTブローカーというらしい)は色々あるようですが、今回はVerneMQを使用します。 vernemq.com
パッケージをダウンロードしてインストール。
今回はさくらのVPS上に導入しますのでRedHat用のパッケージを。
・・・なんですが、0.15.2のダウンロードリンクがなぜかsrc.rpmになっているのでURLを一部書き換える必要があります。(12/25現在)
設定
VerneMQの設定ファイルは次のところにあります。
- /etc/vernemq/vernemq.conf
とりあえず動かすところを目標にしているので匿名ユーザーの接続をOKにします。
※実際にはVPN経由でしか繋がらない様にファイアウォールでポートふさいでいます。
allow_anonymous = on
次に使用するポートの設定
listener.tcp.default = 0.0.0.0:1883 listener.ws.default = 0.0.0.0:8888
後は初期値のまま。
起動
sudo vernemq start
起動すると、ulimit -n の値が小さいと警告が出るので、値を変更して再起動。
- /etc/security/limits.conf
vernemq soft nofile 65536 verne hard nofile 65536
※一時的に変更する場合は次のコマンドを実行
/sbin/sysctl -w fs.file-max = 65536
設定確認
次のコマンドを実行します。
sudo vmq-admin listener show
+------+-------+-------+-----+----------+---------+ | type |status | ip |port |mountpoint|max_conns| +------+-------+-------+-----+----------+---------+ | vmq |running|0.0.0.0|44053| | 10000 | |mqttws|running|0.0.0.0|8888 | | 10000 | | mqtt |running|0.0.0.0|1883 | | 10000 | +------+-------+-------+-----+----------+---------+
1883番と8888番ポートが開いて使えるようになりました。
動作確認
さくっと既製のクライアントを使用して動作を確認します。
Paho - Open Source messaging for M2M
ダウンロードしたファイルを解凍して起動します。
Connectionの設定
Server URIの欄は、tcp://IPアドレス:1883 と入力し、「Connect」ボタンをクリックして接続
StatusがConnectedになればOKです。
Subscriptionの設定
「+」ボタンをクリックすると図の様にTopicとQoSを入力できるようになります。
Topicは任意の値を入力(今回はtestにしました)、QoSは0 - At Most Onceを選択し、「Subscribe」ボタンをクリックします。
左側のHistoryタブにSubscribedと出ればOKです。
メッセージの発行
では実際にメッセージを発行します。
TopicはSubscriptionで設定した値(test)を入力し、Messageに任意の文言を入力したら、「Publish」をクリックします。
History欄にPublishedとReceivedのメッセージが出ています。
(今回発行と購読が一緒のマシンなので両方出ます)
Last Message欄をみると、メッセージがちゃんと受信できています。
無事動作できているようです。
次回は実際にコード書いて同様の動きを試してみます。
VPSサーバ立て直してやった事 (ユーザー追加, SSH公開鍵認証, VPN)
ブログをはてブロに移し終わったので、これまでブログおいていたさくらのVPSをリセットしました。
サーバの構築手順はググれば沢山出てくるし、いたってふつーの事しかやっていませんが、この後Ansible使って初期構築を自動化を企んでいるってのもあるので、それ用に作業内容を残しておきます。
※さくらのVPSで動かすことを前提としています
※systemctlコマンドも省いています、必要に応じてenable/disableするって感じで
OSアップデート
※標準OSインストールでCentOS入れたらupdate済みのようですが、念のため。。。
# yum update
ユーザー追加
# useradd -G wheel ユーザー名 # passwd ユーザー名 Changing password for user ******. New password: #パスワード入力 Retype new password: #もう1度パスワード入力 passwd: all authentication tokens updated successfully.
SSH公開鍵認証
変更前: #PermitRootLogin yes 変更後: PermitRootLogin no 変更前: PasswordAuthentication yes 変更後: PasswordAuthentication no
その後、公開鍵を作成してアップロード(id_rsa.pub)してコマンド実行
# mkdir /home/ユーザー名/.ssh # chown ユーザー名:グループ名 /home/ユーザー名/.ssh # chmod 700 /home/ユーザー名/.ssh # mv /アップロード先/id_rsa.pub /home/ユーザー名/.ssh/authorized_keys # chown ユーザー名:グループ名 /home/ユーザー名/.ssh/authorized_keys # chmod 600 /home/ユーザー名/.ssh/authorized_keys
VPNサーバ(SoftEther)設定
DLしてインストール
# cd /tmp/ # wget http://jp.softether-download.com/files/softether/v4.22-9634-beta-2016.11.27-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.22-9634-beta-2016.11.27-linux-x64-64bit.tar.gz # tar xvzf softether-vpnserver-v4.22-9634-beta-2016.11.27-linux-x64-64bit.tar.gz # cd vpnserver/ # make -------------------------------------------------------------------- SoftEther VPN Server (Ver 4.22, Build 9634, Intel x64 / AMD64) for Linux Install Utility Copyright (c) SoftEther Project at University of Tsukuba, Japan. All Rights Reserved. -------------------------------------------------------------------- Do you want to read the License Agreement for this software ? 1. Yes 2. No Please choose one of above number: # 1を入力 (中略) Did you read and understand the License Agreement ? (If you couldn't read above text, Please read 'ReadMeFirst_License.txt' file with any text editor.) 1. Yes 2. No Please choose one of above number: # 1を入力 Did you agree the License Agreement ? 1. Agree 2. Do Not Agree Please choose one of above number: # 1を入力 (中略) -------------------------------------------------------------------- make[1]: Leaving directory `/tmp/vpnserver' # cd ../ # mv vpnserver /usr/local
設定ファイルの作成
- /usr/local/vpnserver/setup_vpnserver.sh ※新規作成
#!/bin/sh sleep 3 tap_count=`nmcli d | grep tap_vpn | wc -l` if [ $tap_count -eq 1 ] then result=`ip addr add IPアドレス/サブネットマスク dev tap_vpn` exit $result fi
- /usr/lib/systemd/system/vpnserver.service ※新規作成
[Unit] Description=SoftEther VPN Server After=network.target local-fs.target [Service] Type=forking ExecStart=/usr/local/vpnserver/vpnserver start ExecStartPost=/usr/local/vpnserver/setup_vpnserver.sh ExecStop=/usr/local/vpnserver/vpnserver stop [Install] WantedBy=multi-user.target
そのあと、次のコマンドを実行
# cd /usr/local/vpnserver/ # chmod 600 * # chmod 700 vpncmd # chmod 700 vpnserver # chmod 700 setup_vpnserver.sh # firewall-cmd --add-port=500/udp --permanent # firewall-cmd --add-port=4500/udp --permanent # firewall-cmd --add-port=5555/tcp --permanent # firewall-cmd --zone=public --add-masquerade --permanent # firewall-cmd --reload
※SoftEtherのコンフィグ(vpn_server.config)はあらかじめ作っておいて、/usr/local/vpnserver/vpn_server.configにアップロード
Raspberry Piのiptablesを設定
(注)この記事は2015年5月9日に旧ブログに投稿したものです。今でも有効な内容かは不明・・・
iptablesの設定内容を永続化(起動時に自動的に読み込む)ためのパッケージをインストールします。
sudo aptitude install iptables-persistent
iptablesのコマンドをポチポチ叩いて設定します。
コマンドの詳細は以下のURLを参照
Linuxコマンド集 – 【iptables】パケットフィルタリングを設定する:ITpro
iptablesの設定方法|さくらインターネット公式サポートサイト
なお、今回
インターネット — ホテル有線LAN — Raspberry Pi — 無線LAN — スマホ
という通信をさせたかったので、iptablesにNAPT(IPマスカレード)の設定を入れます。
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
注)この設定で正しくホテルで使えるかは試していないので不明です…
iptablesの設定内容を保存します。
sudo iptables-save /etc/iptables/rules.v4
ちなみにこんな感じのファイルが出来上がりました。
(一部編集しています)
# Generated by iptables-save v1.4.14 on Tue May 5 07:57:35 2015
*filter
:INPUT DROP [11:3724]
:FORWARD ACCEPT [4480:2695254]
:OUTPUT ACCEPT [228:27001]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
# Completed on Tue May 5 07:57:35 2015
# Generated by iptables-save v1.4.14 on Tue May 5 07:57:35 2015
*nat
:PREROUTING ACCEPT [145:12075]
:INPUT ACCEPT [1:52]
:OUTPUT ACCEPT [15:1234]
:POSTROUTING ACCEPT [2:288]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Tue May 5 07:57:35 2015
ラズパイのGUIを遠隔で操作(VNCサーバ構築)
(注)この記事は2015年5月4日に旧ブログに投稿したものです。今でも有効な内容かは不明・・・
色々なソフトの組み合わせを試してみましたが、自分の使い方ではこれが一番しっくりしたのでその方法をまとめます。
tightvncserverの導入
インストールします。
sudo aptitude install tightvncserver
まずは手動で起動してみます。
初回の起動時に初期パスワードを聞いてきますので、適当に入力。
vncserver
You will require a password to access your desktops. Password:********
Verify:********
Would you like to enter a view-only password (y/n)?n
New 'X' desktop is raspberrypi:1 Creating default startup script /home/pi/.vnc/xstartup Starting applications specified in /home/pi/.vnc/xstartup Log file is /home/pi/.vnc/raspberrypi:1.log
これでVNCサーバが立ち上がりました。
PCから繋いでみます。
ポート番号は5900 + vncserver起動時に表示されたディスプレイ番号
無事接続できているようです。
ここでVNCサーバのメニューからログアウトを選択すると、VNCサーバを再起動するまで使えなくなりますので、ログアウトせずビューアを終了します。
VNCサーバを終了します。
vncserver -kill :1
Killing Xtightvnc process ID 2326
当然ですが、VNCサーバ終了後はビューアで接続を試みても接続できません。
xinetdの導入
上記の方法では使っていないときでもVNCサーバが常駐します。まぁサーバってそういうもんなんですが。
頻繁に使用する場合であれば起動しっぱなしでもいいですが、そうでない場合はリソースの無駄遣いです。
ということで、スーパーサーバ(xinetd)を使用して必要なときだけVNCサーバを起動することにします。
まずはxinetdをインストール
sudo aptitude install xinetd
VNCで使用するポート番号をxinetdの設定で使用できるように、/etc/servicesファイルに以下を追記します。
追記場所はどこでもOK
vnc 5901/tcp
続いて、xinetdからVNCサーバを起動するための設定ファイルを作成します。
/etc/xinetd.d/vnc (新規作成)
service vnc
{
socket_type = stream
wait = no
user = nobody
server = /usr/bin/Xvnc
server_args = -inetd -query localhost -once -geometry 1024x768 -depth 16 -rfbauth /etc/vnc_passwd
disable = no
}
server_argsの設定(Xvnc起動パラメータ)はここを参考
http://www.tightvnc.com/Xvnc.1.php
-rfbauth で指定した個所にパスワードファイルを作成します。
sudo vncpasswd /etc/vnc_passwd
作成後、パーミッションを変更してOtherのRead権限を付加します。
(本当はやりたくないんですが、これやらないとログインに失敗します。)
sudo chmod o+r vnc_passwd
LightDMの設定
xinetd経由で起動するようにした場合、LightDM(ディスプレイマネージャ)の設定も必要です。
Raspbianであれば既にインストールはされているので、設定ファイルを変更します。
/etc/lightdm/lightdm.conf (変更箇所のみ)
[LightDM]
(中略)
xserver-allow-tcp=true ←追加
[SeatDefaults]
(中略)
#autologin-user=pi ←コメントアウト
[XDMCPServer]
enabled=true ←アンコメント
ちなみにこれ、raspi-configの『3 Enable Boot to Desktop/Scratch』で設定を変更すると、
/etc/lightdm/lightdm.confの一部が書き換わるみたいです。
最後に、LightDMを自動起動するように変更します。
sudo update-rc.d lightdm enable