Java后端Tomcat实现WebSocket实例教程

Java后端Tomcat实现WebSocket实例教程

WebSocket简介

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket允许服务器端和客户端之间的数据实时交换。它被设计成一种通用的解决方案,可以执行不需要长时间等待的双向数据传输。

实现步骤

步骤1:创建WebSocket处理类

创建一个实现javax.websocket.Endpoint接口的WebSocket处理类。Endpoint是WebSocket API的核心接口,它只有两个方法:

public interface Endpoint {
    public void onOpen(Session session, EndpointConfig endpointConfig);
    public void onClose(Session session, CloseReason closeReason);
}

onOpen方法在WebSocket连接建立成功时调用,onClose方法在WebSocket连接关闭时调用。

实现WebSocket处理类的代码如下:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;

public class MyEndpoint extends Endpoint {
    private Session session;
    private Map<String, MessageHandler.Whole<String>> handlers = new HashMap<>();

    @Override
    public void onOpen(Session session, EndpointConfig config) {
        this.session = session;
        session.addMessageHandler(new MessageHandler.Whole<String>() {
            @Override
            public void onMessage(String message) {
                System.out.println("Received message: " + message);
                MessageHandler.Whole<String> handler = handlers.get(message);
                if (handler != null) {
                    handler.onMessage(message);
                }
            }
        });
    }

    @Override
    public void onClose(Session session, CloseReason reason) {
        System.out.println("Closing WebSocket connection...");
    }

    public void sendMessage(String message) throws IOException {
        session.getBasicRemote().sendText(message);
    }

    public void addMessageHandler(String type, MessageHandler.Whole<String> handler) {
        handlers.put(type, handler);
    }

    public void removeMessageHandler(String type) {
        handlers.remove(type);
    }
}

步骤2:配置WebSocket容器

创建一个WebSocket容器,用于处理来自客户端的连接请求。目前支持WebSocket的容器有很多,比如Tomcat、Jetty、Undertow等。以下是在Tomcat中配置WebSocket容器的示例代码:

import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.websocket.server.WsContextListener;
import org.apache.tomcat.websocket.server.WsSci;

public class MyWebSocketContainer {
    public static void main(String[] args) throws Exception {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);

        Context context = tomcat.addContext("/", null);
        context.addApplicationListener(WsContextListener.class.getName());
        context.addServletContainerInitializer(new WsSci(), null);
        tomcat.start();
        tomcat.getServer().await();
    }
}

这个示例代码中,我们创建了一个Tomcat实例,设置端口号为8080,并创建一个根路径为/的上下文。我们通过addApplicationListener和addServletContainerInitializer方法来启用Tomcat的WebSocket支持。

步骤3:创建WebSocket连接

在客户端创建WebSocket连接时,需要使用WebSocket的API来执行连接。以下是在JavaScript中创建WebSocket连接的示例代码:

var webSocket = new WebSocket("ws://localhost:8080/mywebsocket");

webSocket.onopen = function(event) {
    console.log("WebSocket connected");
    webSocket.send("hello server");
};

webSocket.onmessage = function(event) {
    console.log("Received message: " + event.data);
};

webSocket.onclose = function(event) {
    console.log("WebSocket disconnected");
};

在这个示例代码中,我们创建了一个WebSocket实例,并指定请求连接的URL为ws://localhost:8080/mywebsocket,该路径/mywebsocket指的是我们在后面程序代码中要创建的WebSocket处理类的路径。当WebSocket连接成功建立时,我们会收到一个onopen事件,当WebSocket接收到消息时,我们会收到一个onmessage事件。当WebSocket连接关闭时,我们会收到一个onclose事件。

步骤4:接收WebSocket消息

现在我们已经在客户端成功创建了WebSocket连接,接下来我们在服务端来接收WebSocket发送的消息。在MyEndpoint类中,我们已经实现了一个MessageHandler,它可以处理来自客户端的消息。

session.addMessageHandler(new MessageHandler.Whole<String>() {
    @Override
    public void onMessage(String message) {
        System.out.println("Received message: " + message);
        MessageHandler.Whole<String> handler = handlers.get(message);
        if (handler != null) {
            handler.onMessage(message);
        }
    }
});

在接收到消息后,我们通过handlers取出相应的MessageHandler对象,并调用它的onMessage方法来处理消息。

步骤5:发送WebSocket消息

在MyEndpoint类中,我们定义了一个sendMessage方法,用于向客户端发送消息:

public void sendMessage(String message) throws IOException {
    session.getBasicRemote().sendText(message);
}

在客户端中,我们可以通过WebSocket的send方法来发送消息:

webSocket.send("hello server");

这个示例代码中,我们向服务器发送了一条消息“hello server”。

实例演示

下面是一个简单的实例演示,客户端向服务端发送一条消息,服务端返回一条消息。请按照以下步骤操作:

步骤1:创建MyEndpoint类

import java.io.IOException;

import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;

public class MyEndpoint extends Endpoint {

    private Session session;

    @Override
    public void onOpen(Session session, EndpointConfig config) {
        System.out.println("WebSocket connection opened");
        this.session = session;
        session.addMessageHandler(new MessageHandler.Whole<String>() {
            @Override
            public void onMessage(String message) {
                System.out.println("Received message: " + message);
                try {
                    session.getBasicRemote().sendText("Hello client! You said: " + message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void onClose(Session session, javax.websocket.CloseReason reason) {
        System.out.println("WebSocket connection closed");
    }
}

步骤2:创建WebSocket容器

import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.websocket.server.WsContextListener;
import org.apache.tomcat.websocket.server.WsSci;

public class MyWebSocketContainer {

    public static void main(String[] args) throws Exception {

        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);

        Context context = tomcat.addContext("/", null);

        context.addApplicationListener(WsContextListener.class.getName());
        context.addServletContainerInitializer(new WsSci(), null);

        Tomcat.addServlet(context, "MyEndpointServlet", new MyEndpointServlet());
        context.addServletMappingDecoded("/myendpoint", "MyEndpointServlet");

        tomcat.start();
        tomcat.getServer().await();
    }
}

步骤3:创建WebServlet类

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

import org.apache.tomcat.websocket.server.Constants;
import org.apache.tomcat.websocket.server.WsServerContainer;

@WebServlet(urlPatterns = "/myendpoint")
public class MyEndpointServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    public void init() {
        WsServerContainer container = (WsServerContainer) getServletContext().getAttribute(Constants.SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE);
        try {
            container.addEndpoint(MyEndpoint.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

步骤4:创建index.html页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket Test</title>
<script type="text/javascript">
    var webSocket;
    function connect() {
        var username = document.getElementById("username").value;
        webSocket = new WebSocket("ws://localhost:8080/myendpoint");
        webSocket.onopen = function(event) {
            console.log("WebSocket connected");
            webSocket.send(username);
        };
        webSocket.onmessage = function(event) {
            console.log("Received message: " + event.data);
            document.getElementById("output").innerHTML = event.data;
        };
        webSocket.onclose = function(event) {
            console.log("WebSocket disconnected");
        };
    }
    function disconnect() {
        if (webSocket !== undefined) {
            console.log("WebSocket disconnecting...");
            webSocket.close();
        }
    }
</script>
</head>
<body>
    <h1>WebSocket Test</h1>
    <form>
        <label for="username">Username:</label>
        <input type="text" id="username" name="username">
        <button type="button" onclick="connect()">Connect</button>
        <button type="button" onclick="disconnect()">Disconnect</button>
    </form>
    <div id="output"></div>
</body>
</html>

在这个示例代码中,我们定义了两个JavaScript函数connect和disconnect。当用户填写自己的用户名后,点击Connect按钮,connect函数会创建一个WebSocket连接,并向服务器发送用户名。当WebSocket接收到消息时,客户端会显示服务器返回的消息在页面上。

结论

本文详细讲解了如何在Java后端Tomcat中实现WebSocket,步骤包括创建WebSocket处理类、配置WebSocket容器、创建WebSocket连接、接收WebSocket消息和发送WebSocket消息。同时,我们还演示了一个简单的实例,客户端向服务端发送一条消息,服务端返回一条消息。至此,我们已经完成了Java后端Tomcat实现WebSocket的一个实例教程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java后端Tomcat实现WebSocket实例教程 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • java文件操作之Path,Paths,Files

    Java文件操作之Path、Paths、Files Java中的Path、Paths和Files是比较常用的文件操作类,提供了丰富的API用于文件的读写、复制、移动、删除等操作。 Path Path是java.nio包中的一个接口,代表一个文件系统中的路径。在创建一个Path对象时,可以向它传递一个字符串表示路径,这个字符串中可以使用反斜杠也可以使用正斜杠作…

    Java 2023年5月19日
    00
  • 详解如何在Java中实现堆排序算法

    下面是详解如何在Java中实现堆排序算法的完整攻略: 堆排序算法 堆排序(Heap sort)是一种基于比较的排序算法,它的思想是将待排序的序列构建成一个二叉树堆,然后依次删除根节点(或者称为堆顶),并重新调整堆,直到所有的元素都被删除。在堆调整的过程中,需要保证堆的性质,即每个节点的值都不大于其父亲节点的值(max堆),或者每个节点的值都不小于其父亲节点的…

    Java 2023年5月19日
    00
  • springMVC几种页面跳转方式小结

    SpringMVC几种页面跳转方式小结 在SpringMVC中,有多种方式可以实现页面跳转。本文将介绍其中的几种方式,并提供示例说明。 方式一:使用redirect 使用redirect可以实现页面的重定向。在控制器方法中,我们可以使用”redirect:”前缀来指定重定向的URL。下面是一个示例的控制器方法: @GetMapping("/redi…

    Java 2023年5月17日
    00
  • vue + element-ui的分页问题实现

    下面是“vue + element-ui的分页问题实现”的完整攻略,包含以下几个部分: 安装element-ui和配置Vue组件 Element-ui分页组件的使用 分页数据处理及传参方式说明 1. 安装element-ui和配置Vue组件 1.1 安装element-ui 首先需要在你的项目中安装 element-ui,使用如下命令进行安装: npm in…

    Java 2023年6月16日
    00
  • Java读写文件创建文件夹多种方法示例详解

    请您先到我的网站上查看该文章的具体内容,以便更好地理解我的回答,并方便您对我的回答进行参考对照:Java读写文件创建文件夹多种方法示例详解 首先,本文中提到了多种文件读写方法,包括字节流,字符流及NIO方式。在进行文件读写操作前,需首先声明文件路径,一般会使用java.io.File类来表示文件或者目录。文件读写时,需要指定文件的输入流或输出流。在Java中…

    Java 2023年5月20日
    00
  • Java使用BigDecimal进行高精度计算的示例代码

    下面是Java使用BigDecimal进行高精度计算的完整攻略。 概述 在进行浮点运算或需要精确计算金额等数据时,常常会遇到精度损失的问题。这时候可以使用Java的BigDecimal类来进行高精度计算。BigDecimal类可以精确表示任意精度的小数,并支持基本的算术运算、比较运算和舍入操作。 BigDecimal类的使用 创建BigDecimal对象 创…

    Java 2023年5月30日
    00
  • Java面向对象编程的三大特征

    Java面向对象编程的三大特征分别是封装、继承和多态。下面分别来详细讲解: 封装 封装是面向对象编程的一个非常重要的特征,它是指将数据和方法结合起来,形成一个独立的整体,对外部隐藏对象内部的实现细节。在Java中,通过访问修饰符(public、private、protected)来实现封装。 示例1:下面的代码展示了一个简单的Java类,它使用封装来隐藏内部…

    Java 2023年5月26日
    00
  • JSP基于JDBC的数据库连接类实例

    下面我将给出关于“JSP基于JDBC的数据库连接类实例”的完整攻略,希望可以对您有所帮助。 JSP基于JDBC的数据库连接类实例 JDBC(Java Database Connectivity)是Java语言中访问数据库的标准规范,通过JDBC可以实现与多种数据库的连接。在JSP中使用JDBC连接数据库是非常常见的一种操作。接下来将为您提供一些相关的实例: …

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部