移动端与服务器跨平台通信:sockJS,cordova与Vert.x

移动端与服务器跨平台通信:sockJS,cordova与Vert.x

  1. 问题引入

    有个朋友想开发一款APP,想要同时兼容各个APP平台,但是初期投入又不想太大,于是开发人员就选择给他做成H5的,
    但是这款APP与服务器的通信方式却又是双向的(比如说手机端棋牌类游戏),HTTP的方式满足不了要求。

    以上内容纯属虚构,
    以下概念纯属拼凑。

  2. 会用到的几个概念

    • webSocket
      就是把HTTP协议从无状态升级为有状态的持久协议的东西。
      对于以上问题首先想到的肯定就是webSocket,但是webSocket是H5中新增的,浏览器支持情况如下:这里有浏览器支持概述,
      需要注意的是webview的老版本是不支持的,为了更好的兼容性,可以使用cordova的webSocket插件,这里采用sockJS。
      (可以使用socketIO,但是需要配套的nodejs后端且不是本文内容)。

    • sockJS
      sockJS并不是webSocket的库,但是他提供类似于webSocket的功能及接口,并且在浏览器不支持websocket的时候仍然能运转良好。SockJS需要配套的后端。
      个人瞎猜其可以这样实现:
      可用webSocket则用,否则 -> 可用长连接则用长连接,否则 -> ajax/http

    • cordova
      是一个用H5来开发跨平台APP的平台。有兴趣的话请看这篇文章

    • Vert.x
      使用sockJS需要指定的后台,而vert.x有对应的sockJS实现。
      我也是刚接触,如有错误还请批评指教。 我了解到的是一个高效的,异步的,基于NETTY的服务器框架。

      • vert.x 基于事件与异步
        tomcat作为web服务器使用的时候(默认)是同步的,也就是阻塞的,为每一个连接请求分配一个线程,
        当每个线程连接的时间很短时,尚且可以处理,但是当大量长连接存在的时候这种架构就难以为继了。
        使用异步的方式,没有了阻塞线程,可以更大化CPU的利用率。
      • 基于netty实现
        特点基本同上。
      • 更丰富的接口与使用方式
        事实上以上提到的nio实现方式听起来与Jetty类似, 但是jetty是实现了大部分的J2EE规范的,而vert.x
        压根就是另起炉灶的意思,jsp/servlet这些均没有考虑实现,所以提供了更丰富的API与高精度的可控制度。
  3. 搬出代码

    • Vert.x

      1. 依赖
        // gradle
        dependencies {
            compile 'io.vertx:vertx-core:3.4.1'
            compile 'io.vertx:vertx-sockjs-service-proxy:3.4.1'
            testCompile group: 'junit', name: 'junit', version: '4.11'
        }

      其中vertx-core是vert.x的实实现,新版本的vert.x的sockJSServer调出来放到vertx-sockjs-service-proxy里面了。

      1. vert.x的启动方式:以下实现了一个helloWorld页面

        public class MySockJS extends AbstractVerticle {
        
            public void start() {
                vertx.createHttpServer().requestHandler(req -> {
                    req.response()
                            .putHeader("content-type", "text/plain")
                            .end("Hello World!");
                }).listen(80);
            }
        
            public static void main(String[] args) {
                Vertx vertx = Vertx.vertx();
                vertx.deployVerticle(MySockJS.class.getName());
            }
        }
      2. 使用vert.x实现一个静态资源服务器

            public class MySockJS extends AbstractVerticle {
        
                public void start() {
                    Router router = Router.router(vertx);
                    router.route("/page/*").handler(StaticHandler.create("/html"));
                    vertx.createHttpServer().requestHandler(router::accept).listen(80);
                }
        
                public static void main(String[] args) {
                    Vertx vertx = Vertx.vertx();
                    vertx.deployVerticle(MySockJS.class.getName());
                }
            }

        route(“/page/“).handler(StaticHandler.create(“/html”))的意思是类似于URL/page/的路由都转到html文件夹下面。

      3. 使用vert.x实现webSocket服务器

            public class MySockJS extends AbstractVerticle {
        
                public void start() {
        
                    Router router = Router.router(vertx);
                    BridgeOptions opts = new BridgeOptions()
                            .addInboundPermitted(new PermittedOptions().setAddress("toServer"))
                            .addOutboundPermitted(new PermittedOptions().setAddress("toClient"));
        
                    SockJSHandler ebHandler = SockJSHandler.create(vertx).bridge(opts);
                    router.route("/webSocket/*").handler(ebHandler);
                    vertx.createHttpServer().requestHandler(router::accept).listen(80);
        
                    EventBus eb = vertx.eventBus();
                    eb.consumer("toServer").handler(message -> {
                        //这里是具体的消息处理方式
                        System.out.println(message.body());
                    });
                }
        
                public static void main(String[] args) {
                    Vertx vertx = Vertx.vertx();
                    vertx.deployVerticle(MySockJS.class.getName());
                }
            }

      BridgeOptions类似于topic,client和server端统一才可以发送消息。

    • sockJS
      使用sockJS连接后台

      var eb = new vertx.EventBus("http://127.0.0.1:8080/webSocket/");
          eb.onopen = function () {
              eb.registerHandler("toClient", function (msg) {
                  $('#chat').append(msg + "\n");
              });
          };
      
          function send(message) {
              eb.publish("toServer", message);
          }

      registerHandler是接收消息的处理程序,eb.publish是发送消息。
      toClient跟toServer分别与java代码中的new PermittedOptions().setAddress对应。

      下面附上一个聊天代码的链接,亲测可用。Vertx3 Java版 在线聊天实时推送 官网Demo

你可能感兴趣的:(android)