Java中使用websocket实现在线聊天功能

下面我将为您详细讲解如何使用WebSocket实现Java Web应用中的在线聊天功能。

简介

WebSocket是一种协议,它允许客户端与服务端之间建立一个持久性的套接字连接,以实现双方之间的实时通信。

相对于HTTP请求/响应模式,WebSocket的优势在于:
- 更少的网络流量。与每次发送HTTP请求并接收响应的通信形式不同,WebSocket允许建立一次连接,之后双方可一直进行实时通信,节省了许多数据传输的开销。
- 更快的响应速度。WebSocket支持全双工通信,服务器可以主动向客户端发送消息,双方交互更为顺畅和高效。
- 更多的数据类型和格式。WebSocket不仅支持文本数据,也可以传输二进制数据,且支持多种数据格式,如JSON、XML等。

实现步骤

下面给出Java实现WebSocket的步骤:

  1. 添加依赖

在pom.xml文件中添加以下依赖:

<dependency>
  <groupId>javax.websocket</groupId>
  <artifactId>javax.websocket-api</artifactId>
  <version>1.1</version>
</dependency>
<dependency>
  <groupId>org.glassfish.tyrus</groupId>
  <artifactId>tyrus-server</artifactId>
  <version>1.13</version>
</dependency>
  1. WebSocket服务端实现

创建一个WebSocketServer类继承javax.websocket.server.Endpoint,实现以下方法:

@ServerEndpoint(value = "/chat")
public class WebSocketServer {
    private Session session;

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        // 处理收到的消息
    }

    @OnClose
    public void onClose(Session session) {
        // 关闭连接
    }
}

通过注解@ServerEndpoint(value = "/chat")指定WebSocket服务的URI。

@OnOpen注解表示该方法在建立连接时被调用,通过参数Session session可以获取WebSocket连接的会话。

@OnMessage注解表示该方法在接收到客户端发送的消息时被调用,参数String message表示收到的消息。

@OnClose注解表示该方法在断开连接时被调用,同样通过Session session参数获取连接会话。

  1. 客户端实现

创建一个WebSocket对象,连接到WebSocket服务端:

var socket = new WebSocket("ws://localhost:8080/chat");

通过socket.send(message)方法发送消息,通过socket.onmessage监听服务端的消息推送。

  1. 部署和测试

将项目打包成war包并部署到Tomcat服务器上,启动Tomcat服务器。在浏览器中打开多个窗口,加载应用程序页面,输入消息并发送,窗口之间可以实时收发消息。

示例说明

以下是两个示例说明,用于更加具体地了解WebSocket的应用。

示例1:汇率实时更新

需求:在Web页面上显示汇率情况,每隔1秒实时更新一次。

实现思路:前端页面通过WebSocket连接到汇率服务器,服务器每隔1秒向所有客户端推送汇率信息。

  1. 后端实现

创建一个ExchangeRateServer类,实现以下方法:

@ServerEndpoint(value = "/exchangerate")
public class ExchangeRateServer {
    private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());

    @OnOpen
    public void onOpen(Session session) {
        sessions.add(session);
    }

    @OnClose
    public void onClose(Session session) {
        sessions.remove(session);
    }

    @Scheduled(fixedDelay = 1000)
    public void pushExchangeRate() {
        sessions.forEach(session -> {
            try {
                session.getBasicRemote().sendText(getExchangeRate());
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    private String getExchangeRate() {
        // 获取实时汇率信息
    }
}

@ServerEndpoint(value = "/exchangerate")定义WebSocket服务URI。

@OnOpen@OnClose方法分别在连接/断开时被调用,并将连接保存在一个集合中。

@Scheduled(fixedDelay = 1000)用于定期向客户端发送汇率信息。其中sessions保存了所有连接,session.getBasicRemote().sendText()可以将消息推送到客户端。

  1. 前端实现

在Web页面中添加如下JS代码:

var socket = new WebSocket("ws://localhost:8080/exchangerate");
socket.onmessage = function(event) {
  var data = JSON.parse(event.data);
  // 更新汇率信息
};

每次接收到服务端推送的消息,即更新一次汇率信息。

示例2:博客评论实时更新

需求:在博客页面上同步显示最新的评论,实现与已有评论的实时互动。

实现思路:前端页面通过WebSocket连接到服务器,服务器将收到的新评论实时推送给所有与该博客关联的客户端。

  1. 后端实现

创建一个BlogCommentsServer类,实现以下方法:

@ServerEndpoint(value = "/blog/comments/{blogId}")
public class BlogCommentsServer {
    private static final Map<String, Set<Session>> clients = new HashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("blogId") String blogId) {
        clients.computeIfAbsent(blogId, k -> Collections.synchronizedSet(new HashSet<>()));
        clients.get(blogId).add(session);
    }

    @OnClose
    public void onClose(Session session, @PathParam("blogId") String blogId) {
        clients.get(blogId).remove(session);
    }

    public static void pushNewComment(String blogId, Comment newComment) {
        clients.computeIfPresent(blogId, (k, sessions) -> {
            sessions.parallelStream().forEach(session -> {
                try {
                    session.getBasicRemote().sendText(newComment.toJSON());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            return sessions;
        });
    }
}

@ServerEndpoint(value = "/blog/comments/{blogId}")定义WebSocket服务URI。URI中的blogId表示与该博客关联的所有客户端。

@OnOpen@OnClose方法记录每个客户端与哪些博客绑定在一起,以便于后面的推送。

BlogCommentsServer.pushNewComment()方法在收到新评论时,将该评论推送给与博客关联的所有客户端。

  1. 前端实现

在博客页面的JS代码中,添加如下代码:

var socket = new WebSocket("ws://localhost:8080/blog/comments/" + blogId);
socket.onmessage = function(event) {
  var data = JSON.parse(event.data);
  // 实时更新新评论
};

每次接收到服务端推送的消息,即添加一条新评论。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中使用websocket实现在线聊天功能 - Python技术站

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

相关文章

  • Js类的静态方法与实例方法区分及jQuery拓展的两种方法

    Js类的静态方法与实例方法区分及jQuery拓展的两种方法是面向对象编程中的基础知识,这里我们来详细讲解一下。 静态方法和实例方法的区别 在JavaScript中,类的静态方法和实例方法的区别在于调用的方式和使用的场景。 静态方法是类的方法,需要通过类名直接调用,不依赖于类的实例。静态方法通常用于实现类级别的工具方法或者计算某些和类本身相关的数据。 示例代码…

    jquery 2023年5月28日
    00
  • jQuery实现表单提交时判断的方法

    当使用jQuery进行表单提交时,我们可以使用以下方法来进行表单提交时的判断,以确保提交的数据格式正确: 提交前进行表单校验 在表单提交之前,我们可以编写一段jQuery代码来进行表单校验,确保用户输入的数据格式正确。具体实现步骤如下: (1)取得表单元素和相应的值 var name = $("#name").val(); var age…

    jquery 2023年5月28日
    00
  • 详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)

    Ajax请求中的async参数指的是异步请求的开关,该参数的值可以为true或false,默认值为true。该参数与请求的同步或异步方式有关。 当async为true时,表示异步请求,即发送请求后,不会等待服务器返回数据,而是立即执行后续的代码。当服务器返回数据后再回调函数中进行处理。这种方式可以提高网页的响应速度和用户体验。示例代码如下: $.ajax({…

    jquery 2023年5月27日
    00
  • jQuery UI菜单select事件

    下面是关于“jQuery UI菜单select事件”的详细讲解。 什么是jQuery UI菜单select事件? jQuery UI菜单select事件是指在jQuery UI菜单组件中,当用户选择一个菜单项时,触发的事件。这个事件常用于响应用户的选择,例如在菜单被选择后执行相关的JavaScript操作或者切换内容区域。 如何使用jQuery UI菜单se…

    jquery 2023年5月12日
    00
  • jQWidgets jqxTextArea popupZIndex属性

    让我们来详细讲解一下“jQWidgets jqxTextArea popupZIndex属性”。 什么是 jqxTextArea? jqxTextArea 是 jQWidgets 中的一个组件,用于创建一个多行文本输入框。 什么是 popupZIndex 属性? popupZIndex 属性用于设置弹出窗口的层级。当 jqxTextArea 内部弹出窗口被打…

    jquery 2023年5月12日
    00
  • slideDown()函数如何在jQuery事件处理程序中工作

    在jQuery中,我们可以使用.slideDown()函数来显示元素。.slideDown()函数将元素设置为可见,并将其高度逐渐增加,直到达到其原始高度。以下是两个示例演示如何在jQuery事件处理程序中使用.slideDown()函数: 示例1:单击按钮显示元素 以下是一个示例,演示如何在单击按钮时使用.slideDown()函数显示元素: <!D…

    jquery 2023年5月9日
    00
  • jQWidgets jqxDataTable组属性

    以下是关于“jQWidgets jqxDataTable组属性”的完整攻略,包含两个示例说明: 简介 jqxDataTable 控件的组属性用将数据按照指的列分组显示。组属性用于创建数据汇总报表或者按照某字段进行数据分析。 完整攻略 以下是 jqxDataTable 控件组属性的完整攻略。 定义组属性 在 jqxDataTable 控中,可以使用 group…

    jquery 2023年5月11日
    00
  • 在ASP.NET 2.0中操作数据之十九:给编辑和新增界面增加验证控件

    在ASP.NET网站中,为了让用户输入的数据更加规范和准确,我们需要给编辑和新增界面增加验证控件。ASP.NET 2.0提供了一些内置的验证控件供我们使用,例如RequiredFieldValidator、RegularExpressionValidator、CompareValidator等。下面是给编辑和新增界面增加验证控件的完整攻略: 1. 在ASP.…

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