`

Vertx3 Java版 在线聊天实时推送 官网Demo

阅读更多

Java代码:

 

package io.vertx.example.web.chat;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.eventbus.EventBus;
import io.vertx.example.util.Runner;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.StaticHandler;
import io.vertx.ext.web.handler.sockjs.BridgeOptions;
import io.vertx.ext.web.handler.sockjs.PermittedOptions;
import io.vertx.ext.web.handler.sockjs.SockJSHandler;

import java.text.DateFormat;
import java.time.Instant;
import java.util.Date;

/**
 * A {@link io.vertx.core.Verticle} which implements a simple, realtime,
 * multiuser chat. Anyone can connect to the chat application on port
 * 8000 and type messages. The messages will be rebroadcast to all
 * connected users via the @{link EventBus} Websocket bridge.
 *
 * @author <a href="https://github.com/InfoSec812">Deven Phillips</a>
 */
public class Server extends AbstractVerticle {

  // Convenience method so you can run it in your IDE
  public static void main(String[] args) {
    Runner.runExample(Server.class);
  }

  @Override
  public void start() throws Exception {

    Router router = Router.router(vertx);

    // Allow events for the designated addresses in/out of the event bus bridge
    BridgeOptions opts = new BridgeOptions()
      .addInboundPermitted(new PermittedOptions().setAddress("chat.to.server"))
      .addOutboundPermitted(new PermittedOptions().setAddress("chat.to.client"));

    // Create the event bus bridge and add it to the router.
    SockJSHandler ebHandler = SockJSHandler.create(vertx).bridge(opts);
    router.route("/eventbus/*").handler(ebHandler);

    // Create a router endpoint for the static content.
    router.route().handler(StaticHandler.create());

    // Start the web server and tell it to use the router to handle requests.
    vertx.createHttpServer().requestHandler(router::accept).listen(8080);

    EventBus eb = vertx.eventBus();

    // Register to listen for messages coming IN to the server
    eb.consumer("chat.to.server").handler(message -> {
      // Create a timestamp string
      String timestamp = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM).format(Date.from(Instant.now()));
      // Send the message back out to all clients with the timestamp prepended.
      eb.publish("chat.to.client", timestamp + ": " + message.body());
    });

  }
}
 

 页面代码:

 

<!--
  #%L
  distributed-chat-service
  %%
  Copyright (C) 2015 Zanclus Consulting
  %%
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  
       http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  #L%
  -->
<html>
<head>
  <title>Distributed Chat Service</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
  <script src="//cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js"></script>
  <script src="vertxbus.js"></script>
  <style>
    .inset {
      box-shadow: inset 0 0 4px #000000;
      -moz-box-shadow: inset 0 0 4px #000000;
      -webkit-box-shadow: inset 0 0 4px #000000;
      width: 400px;
      border-width: 4px;
      padding: 5px;
    }

    input.inset {
      height: 40px;
    }

    div.inset {
      height: 500px;
      white-space: pre-wrap
    }
  </style>
</head>
<body>
<script>
  var eb = new vertx.EventBus("/eventbus/");
  eb.onopen = function () {
    eb.registerHandler("chat.to.client", function (msg) {
      $('#chat').append(msg + "\n");
    });
  };

  function send(event) {
    if (event.keyCode == 13 || event.which == 13) {
      var message = $('#input').val();
      if (message.length > 0) {
        console.log($('#input'));
        eb.publish("chat.to.server", message);
        $('#input').val("");
      }
    }
  }
</script>
<div id="chat" class="inset"></div>
<input id="input" type="text" onkeydown="send(event)" class="inset">
</body>
</html>

Js引用资源:

 

/*
 * Copyright 2014 Red Hat, Inc.
 *
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  and Apache License v2.0 which accompanies this distribution.
 *
 *  The Eclipse Public License is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  The Apache License v2.0 is available at
 *  http://www.opensource.org/licenses/apache2.0.php
 *
 *  You may elect to redistribute this code under either of these licenses.
 */

/*
 *   Copyright (c) 2011-2013 The original author or authors
 *   ------------------------------------------------------
 *   All rights reserved. This program and the accompanying materials
 *   are made available under the terms of the Eclipse Public License v1.0
 *   and Apache License v2.0 which accompanies this distribution.
 *
 *       The Eclipse Public License is available at
 *       http://www.eclipse.org/legal/epl-v10.html
 *
 *       The Apache License v2.0 is available at
 *       http://www.opensource.org/licenses/apache2.0.php
 *
 *   You may elect to redistribute this code under either of these licenses.
 */

var vertx = vertx || {};

!function(factory) {
  if (typeof define === "function" && define.amd) {
    // Expose as an AMD module with SockJS dependency.
    // "vertxbus" and "sockjs" names are used because
    // AMD module names are derived from file names.
    define("vertxbus", ["sockjs"], factory);
  } else {
    // No AMD-compliant loader
    factory(SockJS);
  }
}(function(SockJS) {

  vertx.EventBus = function(url, options) {
  
    var that = this;
    var sockJSConn = new SockJS(url, undefined, options);
    var handlerMap = {};
    var replyHandlers = {};
    var state = vertx.EventBus.CONNECTING;
    var pingTimerID = null;
    var pingInterval = null;
    if (options) {
      pingInterval = options['vertxbus_ping_interval'];
    }
    if (!pingInterval) {
      pingInterval = 5000;
    }
  
    that.onopen = null;
    that.onclose = null;

    that.send = function(address, message, replyHandler) {
      sendOrPub("send", address, message, replyHandler)
    }
  
    that.publish = function(address, message) {
      sendOrPub("publish", address, message, null)
    }
  
    that.registerHandler = function(address, handler) {
      checkSpecified("address", 'string', address);
      checkSpecified("handler", 'function', handler);
      checkOpen();
      var handlers = handlerMap[address];
      if (!handlers) {
        handlers = [handler];
        handlerMap[address] = handlers;
        // First handler for this address so we should register the connection
        var msg = { type : "register",
                    address: address };
        sockJSConn.send(JSON.stringify(msg));
      } else {
        handlers[handlers.length] = handler;
      }
    }
  
    that.unregisterHandler = function(address, handler) {
      checkSpecified("address", 'string', address);
      checkSpecified("handler", 'function', handler);
      checkOpen();
      var handlers = handlerMap[address];
      if (handlers) {
        var idx = handlers.indexOf(handler);
        if (idx != -1) handlers.splice(idx, 1);
        if (handlers.length == 0) {
          // No more local handlers so we should unregister the connection
  
          var msg = { type : "unregister",
                      address: address};
          sockJSConn.send(JSON.stringify(msg));
          delete handlerMap[address];
        }
      }
    }
  
    that.close = function() {
      checkOpen();
      state = vertx.EventBus.CLOSING;
      sockJSConn.close();
    }
  
    that.readyState = function() {
      return state;
    }
  
    sockJSConn.onopen = function() {
      // Send the first ping then send a ping every pingInterval milliseconds
      sendPing();
      pingTimerID = setInterval(sendPing, pingInterval);
      state = vertx.EventBus.OPEN;
      if (that.onopen) {
        that.onopen();
      }
    };
  
    sockJSConn.onclose = function() {
      state = vertx.EventBus.CLOSED;
      if (pingTimerID) clearInterval(pingTimerID);
      if (that.onclose) {
        that.onclose();
      }
    };
  
    sockJSConn.onmessage = function(e) {
      var msg = e.data;
      var json = JSON.parse(msg);
      var type = json.type;
      if (type === 'err') {
        console.error("Error received on connection: " + json.body);
        return;
      }
      var body = json.body;
      var replyAddress = json.replyAddress;
      var address = json.address;
      var replyHandler;
      if (replyAddress) {
        replyHandler = function(reply, replyHandler) {
          // Send back reply
          that.send(replyAddress, reply, replyHandler);
        };
      }
      var handlers = handlerMap[address];
      if (handlers) {
        // We make a copy since the handler might get unregistered from within the
        // handler itself, which would screw up our iteration
        var copy = handlers.slice(0);
        for (var i  = 0; i < copy.length; i++) {
          copy[i](body, replyHandler);
        }
      } else {
        // Might be a reply message
        var handler = replyHandlers[address];
        if (handler) {
          delete replyHandlers[address];
          handler(body, replyHandler);
        }
      }
    }

    function sendPing() {
      var msg = {
        type: "ping"
      }
      sockJSConn.send(JSON.stringify(msg));
    }
  
    function sendOrPub(sendOrPub, address, message, replyHandler) {
      checkSpecified("address", 'string', address);
      checkSpecified("replyHandler", 'function', replyHandler, true);
      checkOpen();
      var envelope = { type : sendOrPub,
                       address: address,
                       body: message };
      if (replyHandler) {
        var replyAddress = makeUUID();
        envelope.replyAddress = replyAddress;
        replyHandlers[replyAddress] = replyHandler;
      }
      var str = JSON.stringify(envelope);
      sockJSConn.send(str);
    }
  
    function checkOpen() {
      if (state != vertx.EventBus.OPEN) {
        throw new Error('INVALID_STATE_ERR');
      }
    }
  
    function checkSpecified(paramName, paramType, param, optional) {
      if (!optional && !param) {
        throw new Error("Parameter " + paramName + " must be specified");
      }
      if (param && typeof param != paramType) {
        throw new Error("Parameter " + paramName + " must be of type " + paramType);
      }
    }
  
    function isFunction(obj) {
      return !!(obj && obj.constructor && obj.call && obj.apply);
    }
  
    function makeUUID(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
        .replace(/[xy]/g,function(a,b){return b=Math.random()*16,(a=="y"?b&3|8:b|0).toString(16)})}
  
  }
  
  vertx.EventBus.CONNECTING = 0;
  vertx.EventBus.OPEN = 1;
  vertx.EventBus.CLOSING = 2;
  vertx.EventBus.CLOSED = 3;

  return vertx.EventBus;

});

 

分享到:
评论

相关推荐

    分布式游戏服务端 Vertx3

    分布式游戏服务端基于Vertx3的构建是一种高效、可扩展且灵活的方法,它允许开发者创建高性能的游戏后端系统。Vert.x是一个用Java语言编写的轻量级、反应式框架,适用于构建现代的、异步的、非阻塞的Web应用程序。在...

    vertx-core-3.9.0-API文档-中文版.zip

    标签:vertx、core、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。

    vertx-web-3.9.0-API文档-中文版.zip

    标签:vertx、web、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。

    Java vertx

    Java API 版本的Vert.x Core 手册, Java API 版本的Vert.x Core 手册, Java API 版本的Vert.x Core 手册, Java API 版本的Vert.x Core 手册, Java API 版本的Vert.x Core 手册

    vertx-h2-httpclient-demo.zip

    解压后的`vertx-demo`目录应该包含了这些组成部分,展示了如何组织和构建一个Vert.x项目。 6. **依赖管理**: 使用Gradle或Maven等构建工具,我们可以管理项目所依赖的库,包括Vert.x核心、Web模块和H2数据库驱动。...

    vertx-web-3.9.0-API文档-中英对照版.zip

    标签:vertx、web、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。...

    vertx-core-3.9.0-API文档-中英对照版.zip

    标签:vertx、core、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用...

    vertx-bridge-common-3.9.0-API文档-中文版.zip

    标签:vertx、bridge、common、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...

    vertx-auth-common-3.9.0-API文档-中文版.zip

    标签:vertx、auth、common、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心...

    vertx3-java8-benchmark

    Vertx 3.x 基准测试 这是比较各种 Web 开发平台的的 vertx 3.x 部分。 明文测试 JSON 序列化测试 数据库单查询测试 数据库多查询测试 数据库数据更新测试 财富测试 版本 顶点 3.0.0 测试网址 明文测试 ...

    javascript Vertx开发教程

    JavaScript Vertx开发教程 在现代Web开发中,Vert.x是一个重要的工具,它是一个轻量级、反应式的事件驱动框架,专为构建分布式系统而设计。本教程将深入探讨如何使用JavaScript来利用Vert.x的强大功能,以创建高效...

    vertx-mod-jersey-2.4.0-final.zip

    【标题】"vertx-mod-jersey-2.4.0-final.zip" 是一个基于 Vert.x 框架的 Jersey 模块的发布版本。Vert.x 是一个轻量级、高性能且反应式的 Java 开发平台,它允许开发人员构建分布式系统,而Jersey 则是 Java 世界中...

    面向Java开发人员的Vertx 3指南.zip

    【标题】"面向Java开发人员的Vertx 3指南" 提供了一个深入的教程,旨在帮助Java开发者理解和应用Vert.x 3这一强大的反应式框架。Vert.x是一个轻量级、高性能且多语言的工具包,它允许开发人员构建高度并发、非阻塞的...

    基于websocket实时聊天记录Demo

    这个Demo提供了一个基础的实时聊天应用实例,通过学习它可以理解WebSocket的基本用法和Java实现。你可以在此基础上扩展功能,如添加用户认证、群聊、文件传输等功能,以满足更复杂的应用场景需求。

    vertx-service-demo

    vertx-service-demo

    vertx-bridge-common-3.9.0-API文档-中英对照版.zip

    标签:vertx、bridge、common、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,...

    基于Java与HTML的分布式游戏服务端Vertx3设计源码

    该项目是一个基于Java和HTML的分布式游戏服务端,采用Vertx3框架设计,源码共计174个文件,包括110个Java源文件、23个SQL脚本、15个XML配置文件、14个Git忽略文件、6个属性文件、4个Markdown文件和1个HTML文件。

    vertx集成mybatis架构

    【标题】:“vertx集成mybatis架构” 在Java开发领域,Vert.x是一个高度可扩展的、非阻塞的事件驱动框架,它适用于构建现代的、响应式的后端应用。MyBatis则是流行的持久层框架,提供了灵活的SQL映射机制和对象关系...

    vertx学习示例

    vertx是一个开源的、基于Java虚拟机(JVM)的轻量级框架,它以其强大的异步事件驱动模型而闻名。vert.x提供了多种编程语言的API,包括Java、JavaScript(Node.js风格)、Groovy、Rust、Kotlin等,使得开发者可以根据...

Global site tag (gtag.js) - Google Analytics