Mqtt Websocket

Intro

前篇提到如何簡單建置mqtt server and client
但若是網頁前端想屆接mqtt server
光開放tcp port是不夠的
必須再開放websocket port
若web使用http,mosquitto只需設置帳號密碼
若web使用https,mosquitto則要建置tls認證機制
此篇先已http為主題實作

Dependencies

sudo apt-get update
sudo apt-get install build-essential python quilt python-setuptools python3
sudo apt-get install openssl
sudo apt-get install libssl-dev
sudo apt-get install cmake
sudo apt-get install g++
sudo apt-get install libc-ares-dev
sudo apt-get install uuid-dev
sudo apt-get install daemon
sudo apt-get install libwebsockets-dev

Broker

與前篇不同,為了開啟websocket開關必須自行下載mosquitto原始碼進行編譯執行

install:

wget http://mosquitto.org/files/source/mosquitto-1.6.1.tar.gz
tar -zxvf mosquitto-1.6.1.tar.gz
cd mosquitto-1.6.1/

edit config:

sudo vim config.mk

開啟webwocket開關

WITH_WEBSOCKETS:=yes

build:

make
sudo make install

Set Up User/Password:

  1. 建立一個帳號名為 User
    sudo mosquitto_passwd -c /etc/mosquitto/passwd User
    
  2. 執行指令後輸入密碼
    Password: xxxx
    Reenter password: xxxx
    

edit mosquitto.conf:

port 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
listener 9001
protocol websockets

start service with config:

mosquitto -c /etc/mosquitto/mosquitto.conf
// -d background

Mqtt broker and client

Intro

Environment: Ubuntu
Client lanaguage: Python
Server: Mosquitto

Broker

install:

sudo apt-get install mosquitto

start service:

mosquitto

Set Up User/Password:

  1. 建立一個帳號名為 User
    sudo mosquitto_passwd -c /etc/mosquitto/passwd User
    
  2. 執行指令後輸入密碼
    Password: xxxx
    Reenter password: xxxx
    
  3. 在 /etc/mosquitto/mosquitto.conf 檔案最後加上
    allow_anonymous false
    password_file /etc/mosquitto/passwd
    

start service with config:

mosquitto -c /etc/mosquitto/mosquitto.conf

Client (command test)

install:

sudo apt-get install mosquitto-clients

subscribe:

 mosquitto_sub -t "topicName"

subscribe with password:

 mosquitto_sub -h "localhost" -p "port" -v -d -t "topicName" -u "username" -P "password"

publish:

 mosquitto_pub -m "message from mosquitto_pub client" -t "topicName"

publish with password:

mosquitto_pub -h "localhost" -p "port"  -t "topicName" -m "test message" -u "username" -P "password"

Client (python)

install:

pip install paho-mqtt

SubscribeTest.py :

import paho.mqtt.client as mqtt


def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("test")

def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set(username="px2",password="px2")
client.connect("localhost", 1883, 60)
client.loop_forever()

PublisherTest.py :

# Publisher.py
import paho.mqtt.client as mqtt

_g_cst_ToMQTTTopicServerIP = "localhost"
_g_cst_ToMQTTTopicServerPort = 1883 #port
_g_cst_MQTTTopicName = "test" #TOPIC name

mqttc = mqtt.Client("python_pub")
mqttc.username_pw_set(username="px2",password="px2")
mqttc.connect(_g_cst_ToMQTTTopicServerIP, _g_cst_ToMQTTTopicServerPort)
mqttc.publish(_g_cst_MQTTTopicName, "Hello")

實作漸層 TextView

設置顏色漸層的 TextView

import android.content.Context;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;

public class GradientTextView extends android.support.v7.widget.AppCompatTextView {
    public GradientTextView(Context context) {
        super(context);
    }

    public GradientTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public GradientTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        //Setting the gradient if layout is changed
        if (changed) {
            getPaint().setShader(new LinearGradient(getWidth()/2, 0, getWidth()/2, getHeight(),
                    ContextCompat.getColor(getContext(), R.color.textColor),
                    ContextCompat.getColor(getContext(), R.color.textColorEnd),
                    Shader.TileMode.CLAMP));
        }
    }
}

LinearGradient參數

LinearGradient(漸層 X值, 漸層Y值, 漸層X值, 漸層Y值, 起始顏色, 結束顏色, shader type)

Android App bundle實作

使用情境

  • 手機圖片過多且支援每個解析度的圖,APK時會載到不必要的解析度的圖,因此導致apk檔案過大
  • 不同硬體的手機使用不同程式碼時有可以利用此方式減少apk大小
  • 有時候手機只需安裝某種特定語言的語言包

使用App bundle build aab

使用3.2.1最新的Android studio版本 並選擇Android App Bundle

結果

會產生附檔名為aab的檔案

修改輸出檔案名稱

在gradle的 defaultConfig中加入

setArchivesBaseName("apk name")

遺憾的是目前並不支援flavors輸出不同名稱

將aab運行安裝在手機上

  1. 至 https://github.com/google/bundletool 下載最新版本的tool

  2. 與aab放在同個路徑下(或是修改下方指令路徑)

  3. 執行下方指令,會產生apks

     java -jar bundletool-all-0.6.2.jar build-apks --bundle=app.aab --output=my_app.apks --ks=../../../../chtSmartGreenParkKey.jks --ks-pass=pass:iocapp --ks-key-alias=ioc --key-pass=pass:iocapp
    
  4. 接上手機後執行下方指令安裝至手機

     java -jar bundletool-all-0.6.2.jar install-apks --apks=my_app.apks --adb=C:\Users\aslanyan\AppData\Local\Android\sdk\platform-tools\adb.exe
    

gradle選擇那些需要被分離

android {
    // Instead, use the bundle block to control which types of configuration APKs
    // you want your app bundle to support.
    bundle {
        language {
            enableSplit = false
        }
        density {
            // This property is set to true by default.
            enableSplit = true
        }
        abi {
            // This property is set to true by default.
            enableSplit = false
        }
    }
}

優缺點

  • 優點:減少APP大小
  • 缺點:難以直接測試

可能遇到的問題

如果Android studio目前有連到裝置,可能會造成指令無法成功安裝的問題,可以先拔掉裝置,執行

adb kill-sever

再重新連上裝置執行

adb start-server

來連上

建立自己的函式庫-Maven Server

From Hackmd : https://hackmd.io/oHrZ-IOTTl6E6cALrk4VhQ


What’s Maven Server

在區網內架設一個Maven Server來提供開發人員能簡易使用libraries


安裝注意事項

  • 使用內網請 關閉防火牆 或是 開啟8081 port
  • Maven預設帳號 = ‘admin’
  • Maven預設密碼 = ‘admin123’

upload your .aar to Server

三步驟簡易上手

  1. put the maven.gradle in the folder outside the project

    https://github.com/B013040034/ohmyblog/blob/master/data/maven.gradle

  2. in sdk’s build.gradle bottom add

    dependencies {
    
    }
    apply from: '/../../maven.gradle'
    
  3. click uploadArchives command PS:可以到以下網址確認是否成功上傳 http://192.168.X.XX:8081/nexus/content/repositories/your_library_server_name/


注意事項

  1. maven.gradle會調整輸出的aar名稱 (gradle不吃dash) 由 XXXX-release.aar -> XXXX.aar
  2. 發布版號來源是sdk的gradle中的 versionName

import your .aar from Server

兩步驟導入aar

  1. 在要使用的專案的 build.gradle中加入

     allprojects {
         repositories {
             maven{ url 'http://192.168.X.XX:8081/nexus/content/repositories/your_library_server_name/'}
         }
     }
    
  2. 在app層級的 build.gradle ->

     dependencies {
         implementation 'com.your_library_server_name:sdkName:versionName'
     }
    

    For Example

     dependencies {
     implementation 'com.kingwaytek:networkInfoCollectionSdk:1.0.0'
     }