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日常练习题,每天进步一点点(17)

    我来为你讲解“Java日常练习题,每天进步一点点(17)”的攻略。 首先,这个练习题共有两个小问题,我们分开来看。 问题一 要求 给定一个仅包含小写字母的字符串,去除字符串中重复的字符,使得每个字符都只出现一次。保证结果字符串中的字符在原字符串中出现顺序不变。例如,给定 “abadbc” ,返回 “abdc” 。 思路 首先我们需要字符串中每个字符只出现一次…

    Java 2023年5月20日
    00
  • SpringBoot2零基础到精通之数据与页面响应

    SpringBoot2 零基础到精通之数据与页面响应 SpringBoot是一款快速开发框架,它的特点在于能够自动配置和约定大于配置。通过本文,你将学会: 在SpringBoot项目中,利用控制器将数据响应到页面上; 配置模板引擎,在页面上渲染动态数据; 将数据响应成Json,供前端异步获取。 1. 添加依赖 在你的SpringBoot项目的pom.xml文…

    Java 2023年5月19日
    00
  • 如何使用​win10内置的linux系统启动spring-boot项目

    下面是如何使用Win10内置的Linux系统启动spring-boot项目的完整攻略。 安装WSL WSL(Windows Subsystem for Linux)是Win10内置的Linux子系统,可在其上运行各种Linux发行版。要使用WSL启动spring-boot项目,首先需要安装WSL: 打开”控制面板”,进入”程序与功能”,选择左侧的”启用或关闭…

    Java 2023年5月19日
    00
  • 详解如何实现SpringBoot的底层注解

    详解如何实现Spring Boot的底层注解 Spring Boot是一个非常流行的Java框架,它提供了许多便利的功能,其中包括底层注解。在本文中,我们将详细讲解如何实现Spring Boot的底层注解,包括如何创建自定义注解、如何使用元注解和如何使用注解处理器。 创建自定义注解 在Java中,我们可以使用@interface关键字来创建自定义注解。以下是…

    Java 2023年5月15日
    00
  • 用JSP创建可重用的图形背景

    下面我会详细讲解如何用JSP创建可重用的图形背景。 1. 确定背景图形 首先,我们需要确定要使用的背景图形。可以在互联网上下载一些免费的背景图像,或者自己设计制作。确保图像大致符合网站设计风格,比如配色、大小等。 2. 创建JSP页面 接下来,我们需要创建一个JSP页面来展示背景图形。可以把背景图形作为JSP页面的背景图片,在页面的CSS中设置背景图像,并将…

    Java 2023年6月15日
    00
  • Java 如何实现照片转化为回忆中的照片

    要实现将现有照片转化为回忆中的照片,可以考虑使用 Java 中的图像处理库,例如 Java Advanced Imaging (JAI)。下面是实现该过程的具体攻略: 准备工作 首先需要在项目中引入 Java Advanced Imaging API。JAI 支持的文件格式包括 JPEG、BMP、PNG、TIFF 等常见的图片格式。如果需要支持其他格式,可以…

    Java 2023年5月26日
    00
  • JavaScript BASE64算法实现(完美解决中文乱码)

    下面详细讲解一下JavaScript BASE64算法实现的攻略。 什么是BASE64算法 BASE64是一种将二进制数据编码成 ASCII 字符串的算法。它主要用于在字符集不兼容的情况下,将文本数据通过电子邮件传输,或者在需要保留文本格式的情况下,将二进制数据嵌入到文本文件中。 JavaScript实现BASE64算法 下面是一个JavaScript BA…

    Java 2023年5月20日
    00
  • spring实现动态切换、添加数据源及源码分析

    下面是关于“spring实现动态切换、添加数据源及源码分析”的完整攻略。 1. 动态添加数据源 1.1 添加数据源配置 在Spring Boot的配置文件中,以 spring.datasource. 开头的配置项表示数据源相关的配置,可以在程序启动时从配置文件中读取。 接下来,我们来实现动态向配置中添加用户自定义的数据源。 首先,在 application.…

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