vertx-eventbus实现服务器消息推送

近年来,移动网络、社交网络和电商的兴起,使各大服务提供商的客户端请求数量激增,传统服务器架构已不堪重负,致使基于事件和异步的解决方案备受追捧,如Nginx、NodeJS。Vert.x框架基于事件和异步,依托于全异步Java服务器Netty,并扩展了很多其他特性,以其轻量、高性能、支持多语言开发而备受开发者青睐。

相较于websocket,vertx使用更为简单(具体可参考vertx官网https://vertx.io/)。

Vert.x是事件驱动的,其处理请求的高性能也是基于其事件机制。Vert.x的事件机制中有几个非常重要的概念:Event Loop、Event Loop Vertical、Worker Vertical、Event Bus、Vert.x Module。

Event Loop:即事件循环,是由Vert.x启动的事件处理线程,也是Vert.x项目对外开放的入口,Vert.x由此接收请求事件。一个Vert.x有一个或多个事件循环线程组成,线程最大数量为主机有效的CPU核数。

Event Loop Vertical:事件的业务处理线程,存在于Event Loop中,用于处理非阻塞短任务。

Worker Vertical : 事件的业务处理线程,用于处理长任务阻塞任务。

Event Bus:即事件总线,是Vert.x事件模型中最核心的部分,所有的事件都经由事件总线进行分发,包括Vertical之间的通信事件。

Vert.x Module : Vert.x项目模块,一个应用通常由多个模块组成,每个模块一般包含多个Vertical。(以上来自百度百科)

首先在pom文件中导入相关依赖:

    
			io.vertx
			vertx-core
			3.4.2
		
		
			io.vertx
			vertx-web
			3.4.2
		
		
			io.vertx
			vertx-web-client
			3.4.2
		


作为vertx最核心的部分,我们一般编写一个类继承AbstractVerticle,然后重新它的start方法。

        
        SockJSHandlerOptions sockjsopt=new SockJSHandlerOptions().setHeartbeatInterval(25000);
       //默认25秒,具体查看SockJSHandlerOptions类
        SockJSHandler sockJSHandler = SockJSHandler.create(vertx,sockjsopt);
        //创建路由规则
        Router router=new RouterImpl(vertx);
        BridgeOptions opt=new BridgeOptions();
         opt.setPingTimeout(100000);//默认10秒,具体查看BridgeOptions类
        //设置从客户端发送消息到服务端的地址,根据自己的需要可以创建任意个
        opt.addInboundPermitted(new PermittedOptions().setAddress("chat.to.server"));
        //解决跨域问题
        router.route().handler(CorsHandler.create("*")
                .allowedMethod(HttpMethod.GET).allowedMethod(HttpMethod.OPTIONS)
                .allowedMethod(HttpMethod.POST).allowedHeader("X-PINGARUNER").allowedHeader("Content-Type"));
        router.route().handler(BodyHandler.create().setBodyLimit(-1));
        router.route("/eventbus/*").handler(sockJSHandler.bridge(opt,bridgeEvent->{
            switch (bridgeEvent.type()) {
            case SOCKET_CREATED:
                System.out.println(new Date()+":This event will occur when a new SockJS socket is created.");
                break;
            case SOCKET_IDLE:
                System.out.println(new Date()+":This event will occur when SockJS socket is on idle for longer period of time than initially configured.");
                break;
            case SOCKET_PING:
                System.out.println(new Date()+":This event will occur when the last ping timestamp is updated for the SockJS socket.");
                break;
            case SOCKET_CLOSED:
                System.out.println(new Date()+":This event will occur when a SockJS socket is closed.");
                break;
            case SEND:
                System.out.println(new Date()+":This event will occur when a message is attempted to be sent from the client to the server.");
                break;
            case PUBLISH:
                System.out.println(new Date()+":This event will occur when a message is attempted to be published from the client to the server.");
                break;
            case RECEIVE:
                System.out.println(new Date()+":This event will occur when a message is attempted to be delivered from the server to the client.");
                break;
            case REGISTER:
                System.out.println(new Date()+":This event will occur when a client attempts to register a handler.");
                break;
            case UNREGISTER:
                System.out.println(new Date()+":This event will occur when a client attempts to unregister a handler.");
                break;
            default:
                break;
            }
            //设置为true,可以处理任何在eventbus上的事件
            bridgeEvent.complete(true);
        }));
         JSONObject data = new JSONObject();
        //创建一个eventbus,用来数据通讯
        EventBus eventBus=vertx.eventBus();
        //HttpServerOptions httpopt=new HttpServerOptions().setMaxWebsocketFrameSize(Integer.parseInt(PropertiesUtil.getProperties("common", "maxWebsocketFrameSize")));//设置数据量的大小,在数据量小的时候,这个值可以不用设置
        HttpServerOptions httpopt=new HttpServerOptions();//设置数据量的大小,在数据量小的时候,这个值可以不用设置
        HttpServer server=vertx.createHttpServer(httpopt);
        server.requestHandler(router::accept).listen(8080, res -> {
            if (res.succeeded()) {
                System.out.println("服务开启成功!");
            } else {
                System.out.println("服务开启失败");
            }
        });
        //设置数据推送出去的时间限制
         DeliveryOptions deliveryOptions=new DeliveryOptions(new JsonObject().put("timeout", 10000));
        //注册地址,然后对接收到客户端来的消息进行处理
        eventBus.consumer("chat.to.server", message -> {
            System.out.println(new Date()+":客户端发往服务端的消息内容为:"+message.body().toString());

            eventBus.publish("chat.to.server",data,deliveryOptions);
            System.out.println(new Date()+":数据发布出去的时间");
        });
        //周期性推送数据
        vertx.setPeriodic(10000, timerID -> {
            eventBus.publish("chat.to.server", ata,deliveryOptions);
            System.out.println(new Date()+":推送完毕");
        });
    }

然后我们在主方法或者Listener中便可对其进行调用,具体如下
          Vertx vertx=Vertx.vertx();
         //部署verticle
        vertx.deployVerticle(PushTrailVerticle.class.getName());
        //PushTrailVerticle为你所编写的verticle类

这里写图片描述

当出现上图时,说明你后台框架已搭建好,接下来补全推送数据即可。

接下来便可编写前端订阅代码:
下载 vertx-eventbus.js文件并引入到你的html中




var ebTrail=new EventBus("http://127.0.0.1:8080/eventbus");
        ebTrail.onopen=function(){//监听数据
            ebTrail.registerHandler("chat.to.server",function(err,msg){
                console.log(msg.body);//在这里对接收的数据进行一些操作
            });
            ebTrail.publish("chat.to.server","RequestTrailData");//这行代码可以发送信息给服务端
        };

想要详细了解vertx的朋友可访问vertx官网:https://vertx.io/

你可能感兴趣的:(vertx-eventbus实现服务器消息推送)