1. 程式人生 > >【5】JMicro免費線上訊息服務

【5】JMicro免費線上訊息服務

JMicro是一個用Java語言實現的開源微服務全家桶,

原始碼地址:https://github.com/mynewworldyyl/jmicro,

Demo地址:http://jmicro.cn/。

 

JMicro訊息服務特性說明

今天向大家介紹基於JMicro實現的非同步線上訊息服務,其特點是免費,非同步,多客戶端支援,高效能,高可用。

現在網上很多宣稱免費訊息服務,其實到一定量後都是要收費的,但JMicro“不限量”免費,但是由於系統算力限制,不可能無限量大,所以JMicro系統預設為每秒最高50條訊息,每條訊息最大為8K二進位制Byte。如果有需要更大的流量場景,可以在問題反饋裡提單說明需求場景,我們評估通過後可適當增大流量(免費)。

客戶端支援方面,目前支援Java客戶端及JS WEB客戶端,後面將陸續增加其他語言平臺客戶端。每種客戶端都支援釋出訊息和訂閱訊息。比如可以用Java客戶端傳送訊息,然後在Web客戶端接收訊息;或者在兩個Web客戶端之間相互發送或訂閱訊息,並且站在使用者的角度看就好像無後端伺服器支援的訊息通訊,非常方便。

下面做個Demo,首先開啟http://jmicro.cn頁面並註冊個賬號,分別在兩個頁面登陸並開啟訊息測試頁面,如下圖:

 

在Chrome瀏覽器開啟兩個頁面,登陸同一個賬號或不同賬號都可以,用賬號登陸成功就行,如上兩個頁面都使用test01賬號登陸。

左邊框“傳送主題”等於右邊框“接收主題”,表示左邊框傳送訊息給右邊框,左邊框的“訂閱主題”等於右邊框的“傳送主題”,表示左邊框接收右邊框傳送過來的訊息。

在左右兩個框分別點選“訂閱”按鈕後,按鈕標題將變為“取消訂閱”;

分別輸入傳送內容,並點擊發送,將看到訊息顯示在對方的“接收訊息”輸出框中。

非同步和高效能其實是一個整體,只有非同步,才能做到快速的網路通訊,而高效能的終極解決方案,基本上只有非同步才能實現,瞭解一個單執行緒的Redis就會知道。值得一提的是JMicro是多執行緒的非同步,是不是想想都激動!

JMIcro原生支援多主備份例項,所以支援高可用,這方面可以檢視前面分享關於JMicro的文章。

 

JS API客戶端Demo

純JS樣例:

http://jmicro.cn/testpubsub.html

原始碼地址:

https://github.com/mynewworldyyl/jmicro/blob/master/mng.web/public/testpubsub.html

 

Vue樣例

按如下網址開啟頁面即可

 

 Vue樣例原始碼地址:

https://github.com/mynewworldyyl/jmicro/blob/master/mng.web/src/components/pubsub/JTestingPubsub.vue

 

JS API客戶端使用

1. 首先註冊JMicro賬號

開啟頁面 http://jmicro.cn/ 右上角註冊即可。註冊時郵箱必須有效可用,後面要通過郵箱啟用賬號。手機號目前雖然沒做實際驗證,但後面不排除需要實名,所以建議填寫真實有效手機號。

2. 引用JS檔案

HTML檔案頭部引入JS,建議將此檔案下載到本地引用,速度會快點

<script type="text/javascript" src="http://jmicro.cn/js/rpc.js"></script>

3. 初始化配置

$(function(){
    jm.rpc.init("jmicro.cn",80);
})

4.賬號登陸

//actName賬號,pwd密碼
jm.rpc.login(actName,pwd,(rst,err)=>{ if(err) { alert(err); }else {       //登陸成功 } });

5. 訂閱訊息

let topic = "/jmicro/test/topic01";
jm.ps.subscribe(topic,{},msgCallback) .then((rst)=>{ if(rst >= 0) { self.subState=true; $("#subscribe").text("Unsubscribe"); }else { console.log(rst); } });
msgCallback是接收訊息函式,定義如下:
function msgCallback(msg) {
        if(!msg || msg.length == 0) {
            $("#msg").text("Pubsub topic is disconnected by server");
       //出錯,取消訂閱 this.doSubscribe(); }else { let txt = $("#Result").text(); $("#Result").text(txt + "\n" + msg.data); } }

如果想取消訂閱訊息,則

let topic = "/jmicro/test/topic01"
jm.ps.unsubscribe(topic,msgCallback)
                .then((succ)=>{
                    if(succ==true) {
                        self.subState=false;
                        $("#subscribe").text("Subscribe");
                    } else {
                        console.log(succ);
                    }
                });

6. 傳送訊息

let topic = "/jmicro/test/topic01"
let content = "Hello jmicro pubsub servcie";
jm.ps.publishString(topic,content,false,false,null,null)
            .then(rst=>{
                console.log(rst);
            }).catch(err=>{
            console.log(err)
        });

以上傳送一個字串訊息。

 

7. 對JS訊息API簡單說明

開啟rpc.js檔案,大概從1200行開始,有如下程式碼

     //byteArray: 傳送byte陣列
    //persist: 指示訊息伺服器是否持久化訊息,如果為true,則持久化到資料庫儲存24小時,在24小時內可以通過訊息歷史記錄頁面查詢到已經發送的訊息。
    //queue: 目前未使用
    //callback: 接收訊息傳送結果主題,需要單獨訂閱此主題接收結果通知
    //itemContext:每個訊息都有一個上下文,有於儲存訊息相關的附加資訊
    publishBytes: function(topic, byteArray,persist,queue,callback,itemContext){
        return this._publishItem(topic, byteArray,persist,queue,callback,itemContext);
    },
    //傳送字串訊息
    publishString: function(topic,content,persist,queue,callback,itemContext){
        return this._publishItem(topic, content,persist,queue,callback,itemContext);
    },

    //通過訊息伺服器呼叫別外一個RPC方法,args為RPC方法的引數
    callService: function (topic,args,persist,queue,callback,itemContext){
        return this._publishItem(topic,args,persist,queue,callback,itemContext);
    },

    //同時傳送多個訊息,psItems為訊息陣列
    publishMultiItems: function (psItems){
        return jm.rpc.callRpcWithParams(this.sn,this.ns,this.v,'publishMutilItems',[psItems]);
    },

    //傳送單個訊息
    publishOneItem: function (psItem){
        return jm.rpc.callRpcWithParams(this.sn,this.ns,this.v,'publishOneItem',[psItem]);
    },

 

Java API使用用說明

樣例原始碼地址:

https://github.com/mynewworldyyl/jmicro/tree/master/example/gatewayclientapp

1. POM中引用客戶端Jar包

<dependency>
          <groupId>cn.jmicro</groupId>
          <artifactId>gateway.client</artifactId>
          <version>0.0.2-SNAPSHOT</version>
        </dependency>

 如果報gateway.client Jar包下載失敗,則需要配置一下Maven Settings檔案,讓其可以使用snapshot創庫

  <profiles>
  
 
    <profile>
      <id>dev</id>
      
      <repositories>
        <repository>
          <id>snapshots</id>
          <url>https://oss.sonatype.org/content/repositories/snapshots/</url>  
          <releases>
            <enabled>false</enabled>
          </releases>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
        </repository>
         <repository>
          <id>public</id>
          <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>  
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
     
       
    </profile>
   

 

2 初始化客戶端連線

    //主題
    private String TOPIC = "/jmicro/test/topic01";
    
    //private ApiGatewayClient socketClient = new ApiGatewayClient(new ApiGatewayConfig(Constants.TYPE_HTTP,"jmicro.cn",80));
    private ApiGatewayClient socketClient = new ApiGatewayClient(new ApiGatewayConfig(Constants.TYPE_SOCKET,"jmicro.cn",9092));
    
    //賬號名
    private static final String ACT = "test01";
    //密碼
    private static final String PWD = "1";

Java客戶端支援SOCKET及HTTP連線型別,SOCKET支援長連線,可以支援訊息訂閱,而HTTP只支援傳送,不支援訂閱。

 

3.傳送字串訊息

@Test
    public void testPublishString() {
        socketClient.loginJMAsync(ACT, PWD)
        .success((resp,cxt)->{
            System.out.println("Success login: "+resp.getData().getActName());
             
            .success((id,cxt0)->{
                System.out.println("Publish result: "+id);
            })
            .fail((code,msg,cxt1)->{
                System.out.println("Fail pubilish content: code: "+ code + ", msg: " + msg);
            });
        })
        .fail((code,msg,cxt)->{
            System.out.println("Fail login: code"+ code + ", msg: " + msg);
        });
        
        Utils.getIns().waitForShutdown();
    }

因為JMicro是基於非同步的RPC,而訊息服務是其中的一個應用,所以以上非同步程式碼看起來不是很直觀。

最外層的socketClient.loginJMAsync(ACT, PWD)表示登陸訊息服務系統,其返回一個IPromise例項,通過其success接收登陸成功通知,fail接收登陸失敗通知。

在success方法裡面再呼叫
socketClient.getPubsubClient()
.publishStringJMAsync(TOPIC, "Message from java client!",PSData.FLAG_DEFALUT,null)
傳送一個字串訊息,同樣,publishStringJMAsync返回IPromise例項,同樣有success和fail接收發送訊息成功或失敗通知。

最後一行Utils.getIns().waitForShutdown();表示讓JVM等待,否則JVM直接退出,自然看不到訊息傳送結果。

4. 訂閱訊息

定義訊息接收器

訂閱訊息必須有一個訊息接收器,用於接收非同步下發的訊息,程式碼如下

PSDataListener lis = new PSDataListener() {
            int id = 0;
            
            @Override
            public void onMsg(PSData item) {
                System.out.println("Got message: " + item.getData().toString());
            }

            @Override
            public int getSubId() {
                return id;
            }

            @Override
            public void setSubId(int id) {
                this.id = id;
            }
            
        };

主要在onMsg方法裡接收訊息,別的暫時不用理會。

 

 開始訂閱

socketClient.loginJMAsync(ACT, PWD)
        .success((resp,cxt)->{
            
            System.out.println("Success login: "+resp.getData().getActName());
            
            socketClient.getPubsubClient()
            .subscribeJMAsync(TOPIC, null, lis)
            .success((id,cxt0)->{
                System.out.println("Subscribe success: "+id);
            })
            .fail((code,msg,cxt1)->{
                System.out.println("Fail to subscribe code: "+ code + ", msg: " + msg);
            });
             
        })
        .fail((code,msg,cxt)->{
            System.out.println("Fail login: code"+ code + ", msg: " + msg);
        });
        
        Utils.getIns().waitForShutdown();

和訊息傳送一樣,最外層表示登陸,並在success方法呼叫訂閱,返回的ID大於0表示訂閱成功,小於或等於0表示訂閱失敗。

最後一行Utils.getIns().waitForShutdown()作用和傳送訊息相同。
你可以通過以上方式在Java與Web頁面間反覆測試兩者之間訊息傳送與接收功能。

 

總結果:

JS及Java訊息傳送與接收是非同步的,並且可以訂閱訊息傳送結果通知,確保訊息傳送成功,以達到同步訊息同樣的效果;

JS及Java API程式設計風格基本上相同,都返回Promise介面例項,並在相應的Success及Fail方法接收結果;

實際上,你可以將Java客戶端Jar放到支援Java的移動終端裡面使用,實現兩個無伺服器支援的App之間傳送接收訊息;

基於JMicro訊息服務,可以在任何系統之間做訊息通訊,即使一個沒有任何伺服器支援的兩個HTML頁面,也可以做網路通訊,並且你不需要為此花費一分錢。

如果你在使用過程中有任何問題,可以在jmicro.cn問題反饋頁面提單,我們技術人員有空就會及時回覆,還希望你能在裡面分享你的使用經驗。

最後,如果JMicro專案確實幫助到你,希望你在到Gitgub上給個星

https://github.com/mynewworldyyl/jmicro

非常感謝!

&n