一、WebSocket是什么?

WebSocket是在单个TCP连接上进行全双工通信的协议,可以在服务器和客户端之间建立双向通信通道。

WebSocket 首先与服务器建立常规 HTTP 连接,然后通过发送Upgrade标头将其升级为双向 WebSocket 连接。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

二、WebSocket的优点

1.较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于控制协议的数据包头部较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。

2.更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。

3.保持连接状态。与HTTP不同的是,WebSocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息,而HTTP请求可能需要在每个请求都携带状态信息,比如身份认证等。

4.更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。

5.可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。

6.更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

三、项目实战

1.引入依赖

org.springframework.boot

spring-boot-starter-websocket

完整的pom文件如下所示:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.7.14

com.example

WebSocketChatDemo

0.0.1-SNAPSHOT

WebSocketChatDemo

WebSocketChatDemo

1.8

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-websocket

org.projectlombok

lombok

org.springframework.boot

spring-boot-starter-thymeleaf

org.springframework.boot

spring-boot-starter-test

test

org.springframework.boot

spring-boot-maven-plugin

2.创建SystemWebSocketHandler类

package com.example.websocketchatdemo.websocket;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

import org.springframework.web.socket.*;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

/**

* @author qx

* @date 2023/8/22

* @des WebSocket处理类

*/

@Slf4j

@Component

public class SystemWebSocketHandler implements WebSocketHandler {

// 存储所有客户端会话

private static final List sessionList = new ArrayList<>();

/**

* 与服务器连接成功

*/

@Override

public void afterConnectionEstablished(WebSocketSession session) throws Exception {

log.info("客户端成功建立连接:{}", session.getId());

sessionList.add(session);

}

/**

* 接受客户端的消息

*/

@Override

public void handleMessage(WebSocketSession session, WebSocketMessage message) throws Exception {

// 获取客户端的消息

String msg = message.getPayload().toString();

log.info("接收到客户端的消息:{}", msg);

sendMsg(msg);

}

/**

* 给所有客户端发送消息

*

* @param msg 消息内容

* @throws IOException

*/

private void sendMsg(String msg) throws IOException {

for (WebSocketSession session : sessionList) {

if (session.isOpen()) {

session.sendMessage(new TextMessage(msg));

}

}

}

/**

* 通讯异常

*/

@Override

public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

log.error("通讯出现异常");

}

/**

* 连接关闭

*/

@Override

public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {

log.info("连接关闭");

}

/**

* 是否允许分段发送

*/

@Override

public boolean supportsPartialMessages() {

// 一次性发送消息

return false;

}

}

3.创建WebSocket配置类

这个配置类主要进行跨域的配置。

package com.example.websocketchatdemo.websocket;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import org.springframework.web.socket.config.annotation.EnableWebSocket;

import org.springframework.web.socket.config.annotation.WebSocketConfigurer;

import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

/**

* @author qx

* @date 2023/8/22

* @des WebSocket配置类

*/

@Configuration

@EnableWebSocket

public class WebSocketConfig implements WebMvcConfigurer, WebSocketConfigurer {

@Autowired

private SystemWebSocketHandler handler;

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

// 设置WebSocket服务器地址 ws://localhost:8080/SpringBootWebSocket

registry.addHandler(handler, "/SpringBootWebSocket").setAllowedOrigins("*");

}

}

4.前台页面编写

聊天室

聊天消息内容:



输入框:





5.控制器编写

主要编写一个跳转到聊天室的请求

package com.example.websocketchatdemo.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

/**

* @author qx

* @date 2023/8/22

* @des 测试

*/

@Controller

@RequestMapping("/chat")

public class IndexController {

/**

* 跳转到聊天室

*/

@GetMapping("/index")

public String toChat() {

return "index";

}

}

6.测试

我们启动项目,打开两个聊天页面。

方便设置两个用户加入聊天室

 

 

然后在一个用户中发送消息,我们可以看到两个聊天窗口的消息同步了。

 

 

当一个用户退出聊天室时,会提示用户退出聊天室。

 这个时候另一个用户发送消息只能自己看到了。

 

 如果想测试多个用户,再从新打开一个页面,进入聊天室就可以了。

相关文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。