zoukankan      html  css  js  c++  java
  • 【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 + " " + 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

    非常感谢!

    如非授权,禁止用于商业用途,转载请注明出处
    作者:mynewworldyyl
    邮箱:mynewworldyyl@gmail.com
  • 相关阅读:
    MapReduce in MongoDB
    MongoDB的一些基本操作
    谈谈NOSQL
    Java中的反射(1)
    Mybatisの常见面试题
    关于Lombok和自动生成get set方法
    订Pizza(Java)
    美化Div的边框
    爱,死亡和机器人(Love,Death&Robots)
    session与cookie的介绍和两者的区别之其相互的关系
  • 原文地址:https://www.cnblogs.com/jmicro/p/13700307.html
Copyright © 2011-2022 走看看