使用Vert.x实现一个简单的websocket聊天室

使用Vert.x实现一个简单的websocket聊天室

小菜一枚,公司业务使用了基于netty的websocket,奈何不会netty,索性之前了解到一个基于netty的toolkit,也就是Vert.x。
Vert.x是一个基于事件和异步,依托于全异步Java服务器Netty,并扩展了很多其他特性,以其轻量、高性能、支持多语言开发而备受开发者青睐的工具集(注意,不是说的框架,而是工具集)。点击进入Vert.x官网。目前Vert.x以更新到了3.5.0
它支持的语言:Java、JavaScript、Groovy、Ruby、Ceylon、Kotlin、Scala……未来也许会增加更多的语言支持。
言归正传,这个小东西代码不多,仅作为个人学习Vert.x使用,预期实现目标如下:
- 使用Maven搭建Vert.x程序框架
- 使用Vert.x的WebSocket实现一个简易的局域网聊天室(仅支持文本消息)

Step1 开发环境

Vert.x3.5.0因为使用了大量的Java8的特性,比如lambda表达式,所以要求JDK版本为JDK8+
Maven我使用的3.3.9
IDE使用的Intellij IDEA 2017.2

Step2 项目搭建

新建一个Maven项目,名称什么的随便
pom.xml文件中引入Vert.x 3.5.0版本的依赖

    <dependency>
      <groupId>io.vertxgroupId>
      <artifactId>vertx-webartifactId>
      <version>3.5.0version>
    dependency>

引入了vertx-web自动引入了vertx-core,所以不用手动添加core的依赖

Step3 编写代码

  • 创建WebSocketVerticle.java
import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.ServerWebSocket;
import io.vertx.ext.web.Router;

import java.util.HashMap;
import java.util.Map;

public class WebSocketVerticle extends AbstractVerticle {
    // 保存每一个连接到服务器的通道
    private Map connectionMap = new HashMap<>(16);

    @Override
    public void start() throws Exception {

        HttpServer server = vertx.createHttpServer();

        Router router = Router.router(vertx);

        router.route("/").handler(routingContext -> {
            routingContext.response().sendFile("html/ws.html");
        });
        websocketMethod(server);
        server.requestHandler(router::accept).listen(8080);
    }

    public void websocketMethod(HttpServer server) {
        server.websocketHandler(webSocket -> {
            // 获取每一个链接的ID
            String id = webSocket.binaryHandlerID();
            // 判断当前连接的ID是否存在于map集合中,如果不存在则添加进map集合中
            if (!checkID(id)) {
                connectionMap.put(id, webSocket);
            }

            // WebSocket 连接
            webSocket.frameHandler(handler -> {
                String textData = handler.textData();
                String currID = webSocket.binaryHandlerID();
                //给非当前连接到服务器的每一个WebSocket连接发送消息
                for (Map.Entry entry : connectionMap.entrySet()) {
                    if (currID.equals(entry.getKey())) {
                        continue;
                    }
                    /* 发送文本消息
                    文本信息似乎不支持图片等二进制消息
                    若要发送二进制消息,可用writeBinaryMessage方法
                    */
                    entry.getValue().writeTextMessage(textData);
                }
            });

            // 客户端WebSocket 关闭时,将当前ID从map中移除
            webSocket.closeHandler(handler -> connectionMap.remove(id) );
        });
    }
    // 检查当前ID是否已经存在与map中
    public boolean checkID(String id) {
        return connectionMap.containsKey(id);
    }

整个websocket的服务器端代码就这么点。没有用过其它的框架实现过websocket聊天室,不知道代码量如何。但就Vert.x的实现方式来说,个人觉得还是很方便的。

  • 部署Verticle
    public class Main {
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(WebSocketVerticle.class.getName());
    }
}
  • 最后HTML文件放置在resources/html下
    ws.html
    
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocketTesttitle>
    <script type="text/javascript" src="http://www.w3school.com.cn/jquery/jquery-1.11.1.min.js">script>
head>
<body>
<script>
    var socket;
    if(window.WebSocket){
        socket = new WebSocket("ws://localhost:8080/");
        // websocket收到消息
        socket.onmessage = function(event){
            // 如果服务端是写的二进制数据,则此处的blob也是一个二进制对象,提取数据时需要Blob类和FileReader类配合使用
            var blob = event.data;
            var content = $("#content").html();
            blob += content;
            $("#content").html(blob);
        };

        // websocket连接打开
        socket.onopen = function (event) {
            console.log("websocket 连接打开");
        };

        // websocket连接关闭
        socket.onclose = function (event) {
            console.log("websocket 连接关闭");
        };
    }else{
        alert("你的浏览器不支持websocket");
    }

    function send(message) {
        if(!window.WebSocket){
            return;
        }
        if(socket.readyState == WebSocket.OPEN){
            socket.send(message);
        }else{
            alert("websocket连接未打开,请检查网络设置");
        }
    }
script>
<form onsubmit="return false;">
    <input type="text" name="message">
    <input type="button" value="提交" onclick="send(this.form.message.value)">
    <div id="content">div>
form>
body>
html>

群推荐:如果对Vert.x技术感兴趣,可以加QQ群: 515203212
转载请注明出处:http://blog.csdn.net/zhhactj/article/details/78728899

你可能感兴趣的:(vert-x)