PS:带有本身一点个人的明白
1.什么是websocket,为什么要去使用它
首先看一下[维基百科上对Websocket的界说](WebSocket - 维基百科,自由的百科全书 (wikipedia.org)),WebSocket是一种网络传输协议,可在单个TCP毗连上进行全双工通信,位于OSI模子应用层应用层。
通过这个界说,其实就已经能够看出websocket的紧张性了。我们一般对前后端进行交互采用http协议,但http是一种无状态的、无毗连的、单向的应用层协议。因此对于C/S架构,客户端只能向服务端发送请求之后服务端才能向客户端发送数据,服务端属于被动的一方,这使得在一些高实时性要求的业务中,http要反复毗连甚至不关闭,而且速度也有些慢了。
Websocket作为全双工通信的协议,中心的传输信道相称自由,不管是服务端还是客户端都能够自由发送消息,速度上便能够大大提升。
2.简单展示一下我使用Websocket的用例
前端js和后端springboot作为演示对象,这是我本身的监控操纵系统信息的一个小项目,我采用的是Websocket的原生注解。
以下是部门代码演示。
首先要创建一个后端的Websocket服务器端点- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.stereotype.Component;
- import org.springframework.web.socket.server.standard.ServerEndpointExporter;
- @Configuration
- @Component
- public class WebSocketConfig {
- @Bean
- public ServerEndpointExporter serverEndpointExporter() {
- return new ServerEndpointExporter();
- }
- }
复制代码 然后是后端服务器的配置和相干业务的处理- import com.example.cypherserverside.service.collect.SysDataServer;
- import jakarta.websocket.*;
- import jakarta.websocket.server.ServerEndpoint;
- import lombok.NonNull;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
- import org.springframework.stereotype.Component;
- import java.util.concurrent.*;
- @Slf4j
- @ServerEndpoint(value = "/ws/url")
- @Component
- public class WebSocketServer implements ApplicationContextAware {
- //线程安全的数据结构,防止线程冲突,Session就是和前端建立连接后由DI容器自动创建的
- private final static ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
- private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
- //为了获取Bean的字段
- private static ApplicationContext _applicationContext;
- private static SysDataServer sysDataServer;
- @Override
- public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
- _applicationContext = applicationContext;
- //启动定时任务
- startScheduledTask();
- }
- /**
- * 开始连接
- * @param session 客户端传来的session
- */
- @OnOpen
- public void onOpen(Session session) {
- sessions.put(session.getId(), session);
- session.setMaxIdleTimeout(30000);
- System.out.println("连接:" + session.getId());
- }
- /**
- * 收到客户端消息
- * @param message 来自前端的消息
- */
- @OnMessage
- public void onMessage(String message) {
- log.info("onMessage: " + message);
- }
- /**
- * 断开连接
- */
- @OnClose
- public void onClose(Session session) {
- for (String key : sessions.keySet()) {
- if (key.equals(session.getId())) {
- sessions.remove(key);
- System.out.println("关闭" + session.getId());
- }
- }
- }
- /**
- * 连接失败出现异常
- * @param t 异常
- */
- @OnError
- public void onError(Throwable t) {
- log.error(t.getMessage(), t);
- }
- /**
- * 定时任务启动,两秒一发送
- */
- private static void startScheduledTask(){
- scheduler.scheduleAtFixedRate(()->{
- sysDataServer = _applicationContext.getBean(SysDataServer.class);
-
- //我自己的业务逻辑,获取JsonString数据然后发给前端
- String systemMessage = sysDataServer.toJSONString(sysDataServer.collectData());
- broadcast(systemMessage);
-
- }, 0, 2, TimeUnit.SECONDS);
- }
-
- //发送数据
- private static void broadcast(String message){
- for (Session session : sessions.values()) {
- session.getAsyncRemote().sendText(message);
- System.out.println("已发送:" + session.getId());
- }
- }
- }
复制代码 js部门代码展示- import { ref } from 'vue';
- const processes = ref([]);
- const ws = new WebSocket('ws://localhost:8080/ws/url');
- ws.onopen = () => {
- console.log('WebSocket 连接成功');
- socket.send("Hello, Server!");
- };
- ws.onmessage = (event) => {
- const data = JSON.parse(event.data);
- // 处理后端数据
- processes.value = data.map(process => ({
- pid: process.pid,
- pname: process.pName,
- cpuUsage: process.processCpuUsage,
- memoryUsage: process.processMemoryUsage
- }));
- };
- ws.onclose = () => {
- console.log('WebSocket 连接关闭');
- };
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |