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
非常感謝!