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日

相关文章

  • 如何用jQuery选择一个元素的所有同级元素

    要使用jQuery选择一个元素的所有同级元素,可以使用siblings()方法。下面是一个完整攻略,包括两个示例说明。 步骤1:创建HTML和CSS 首先,我们需要一个HTML和CSS以便在页面中显示一个元素。下面是示例HTML和CSS: <!DOCTYPE html> <html> <head> <title&gt…

    jquery 2023年5月9日
    00
  • jQWidgets jqxNavigationBar getContentAt()方法

    以下是关于 jQWidgets jqxNavigationBar 组件中 getContentAt() 方法的详细攻略。 jQWidgets jqxNavigationBar getContentAt() 方法 jQWidgets jqxNavigationBar 的 getContentAt() 方法用于获取指定索引位置的导航栏项的内容。 语法 // 获取…

    jquery 2023年5月12日
    00
  • Angular5中调用第三方js插件的方法

    当我们使用Angular5进行开发时,难免会用到一些第三方的JavaScript插件来满足特定的需求。但有时调用这些插件可能会比较困难,因为它们可能不是针对Angular5开发的,因此我们需要使用特殊的方法来有效地使用它们。 下面是一个完整的攻略,以Angular5使用jQuery插件为例。 1. 安装jQuery插件 我们首先需要在Angular5项目中安…

    jquery 2023年5月27日
    00
  • jQWidgets jqxPivotGrid pivotitemclick事件

    以下是关于 jQWidgets jqxPivotGrid pivotitemclick 事件的详细攻略。 jQWidgets jqxPivotGrid pivotitemclick 事件 jQWidgets jqxPivotGrid 是一个功能强大的数据透视表控件,它提供了多种事件,您可以在特定的情况下执行自定义操作。其中一个事件是 pivotitemcli…

    jquery 2023年5月12日
    00
  • jQWidgets jqxTree dragEnd事件

    当用户拖动 jQWidgets jqxTree 组件中的节点并释放鼠标按钮时,dragEnd 事件将被触发。以下是 jQWidgets jqxTree dragEnd 事件的完整攻略: jQWidgets jqxTree dragEnd 事件 dragEnd 事件在用户拖动 jQWidgets jqxTree 组件中的节点并释放鼠标按钮时触发。 语法 $(‘…

    jquery 2023年5月11日
    00
  • 用jQuery简化Ajax开发实现方法

    关于使用jQuery简化Ajax开发实现方法的攻略,我这里提供一份完整的教程。 什么是Ajax? Ajax (Asynchronous JavaScript and XML)是一种基于web页面的异步通信技术,可以用于在不跳转页面的情况下向服务器发送请求并获取响应,实现页面的异步更新,从而大幅提升页面的用户体验。 用jQuery构建Ajax示例 下面是一个简…

    jquery 2023年5月27日
    00
  • jQuery delegate()方法

    jQuery中的delegate()方法用于在DOM元素中添加事件处理程序。与传统的事件绑定方式不同,delegate()方法可以在父元素上监听子元素上的事件,因此可以动态地添加元素并绑定事件处理程序。 语法 delegate()方法的语法如下: $(selector).delegate(childSelector,event,data,function) …

    jquery 2023年5月12日
    00
  • 用jquery写的一个万年历(自写)

    下面是“用jquery写的一个万年历(自写)”的完整攻略: 1. 需求分析 首先需要明确一下我们的需求: 展示一个日历界面,包括年份、月份、日期等信息 支持查看上个月和下个月的日历 支持点击日期,获取该日期的详细信息 2. 技术选型 考虑到我们需要进行DOM操作和事件绑定,以及便捷的选择器,所以使用jQuery是比较合适的选择。同时,为了方便样式的管理和布局…

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