今天它来了,基于前后端分离项目,springboot + react 架构,实现前后端长链接,实时通讯功能。WebSocket的简单易用,完美实现了小项目中的这种前后端实现实时通讯的功能。
服务端代码
1、首先添加maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、添加websocket的配置类
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3、添加websocket的服务类
@Component
@Slf4j
@Service
@ServerEndpoint("/api/websocket")
public class WebSocketServerSingle {
private static WebSocketServerSingle socketServer;
private Session session;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
socketServer = this;
try {
sendMessage("开始连接。。。。");
log.info("有新客户端开始监听");
} catch (IOException e) {
log.error("websocket IO Exception");
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
// 断开连接情况下,更新主板占用情况为释放
log.info("客户端断开连接");
}
/**
* 收到客户端消息后调用的方法
*
* @Param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到来自客户端的信息:" + message);
try {
sendMessage("客户端发布消息:" + message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发生错误回调
*/
@OnError
public void onError(Session session, Throwable error) {
log.error(session.getBasicRemote() + "客户端发生错误");
error.printStackTrace();
}
/**
* 实现服务器主动推送消息到 指定客户端
*/
public void sendMessage(String message) throws IOException {
log.info("服务端发送消息:{}",message);
this.session.getBasicRemote().sendText(message);
}
/**
* 外部调用 发送信息
*/
public static void sendMessages(String message) throws IOException {
socketServer.sendMessage(message);
}
}
4、再来一个发送数据的业务接口
// 推送数据到websocket客户端 接口
@GetMapping("/socket/push")
public Map pushMessage(String message) {
Map<String, Object> result = new HashMap<>();
try {
WebSocketServerSingle.sendMessages("服务端推送消息:" + message);
result.put("msg", message);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
ok,服务端的websocket就写完了。
下面开始客户端react连接websocket。
客户端代码
直接上代码,test.jsx
代码中的useEffect方法是react的钩子函数,初始化页面的时候执行,所以在页面打开的时候就连接了websocket。
import React from 'react';
import { useEffect, useState } from 'react';
const App = () => {
const [msg, setMsg] = useState('');
useEffect(() => {
// 执行副作用操作
console.log('Component mounted');
const socket = new WebSocket('ws://localhost:8103/control-app/api/websocket');
socket.onopen = () => {
console.log('WebSocket connection opened');
// 在连接建立后,可以发送消息给服务器
socket.send('Hello server!');
};
socket.onmessage = (event) => {
console.log('Received message from server:', event.data);
setMsg(event.data)
// 处理从服务器接收到的消息
};
socket.onclose = () => {
console.log('WebSocket connection closed');
// 处理连接关闭事件
};
// 清理副作用操作
return () => {
console.log('Component unmounted');
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<>
<span>{msg}</span>
</>
)
};
export default App;
看一下运行结果:
页面:
控制台:
服务器端:
接下来我们模拟实时信息同步,我们掉一个方法,让websocket发送消息给前端,看前端是否直接显示新的值还是需要刷新页面才展示。
这里为了方便直接用浏览器测试了,就不用postman了。
这里掉的就是我们普通的业务接口
看一下刚刚的网页:
ok,成功。直接变了,不需要再刷新。
这样一个完整的websocket通讯就完成了, 这可以非常方便的实现我们最常用的一个功能,前端小红点未读提示的功能,或者直接右下角消息提示的功能。