浅谈WebSocket

打印 上一主题 下一主题

主题 837|帖子 837|积分 2511

PS:带有本身一点个人的明白
1.什么是websocket,为什么要去使用它

首先看一下[维基百科上对Websocket的界说](WebSocket - 维基百科,自由的百科全书 (wikipedia.org)),WebSocket是一种网络传输协议,可在单个TCP毗连上进行全双工通信,位于OSI模子应用层应用层。
通过这个界说,其实就已经能够看出websocket的紧张性了。我们一般对前后端进行交互采用http协议,但http是一种无状态的、无毗连的、单向的应用层协议。因此对于C/S架构,客户端只能向服务端发送请求之后服务端才能向客户端发送数据,服务端属于被动的一方,这使得在一些高实时性要求的业务中,http要反复毗连甚至不关闭,而且速度也有些慢了。
Websocket作为全双工通信的协议,中心的传输信道相称自由,不管是服务端还是客户端都能够自由发送消息,速度上便能够大大提升。
2.简单展示一下我使用Websocket的用例

前端js和后端springboot作为演示对象,这是我本身的监控操纵系统信息的一个小项目,我采用的是Websocket的原生注解。
以下是部门代码演示。
首先要创建一个后端的Websocket服务器端点
  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.stereotype.Component;
  4. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  5. @Configuration
  6. @Component
  7. public class WebSocketConfig {
  8.     @Bean
  9.     public ServerEndpointExporter serverEndpointExporter() {
  10.         return new ServerEndpointExporter();
  11.     }
  12. }
复制代码
然后是后端服务器的配置和相干业务的处理
  1. import com.example.cypherserverside.service.collect.SysDataServer;
  2. import jakarta.websocket.*;
  3. import jakarta.websocket.server.ServerEndpoint;
  4. import lombok.NonNull;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.beans.BeansException;
  7. import org.springframework.context.ApplicationContext;
  8. import org.springframework.context.ApplicationContextAware;
  9. import org.springframework.stereotype.Component;
  10. import java.util.concurrent.*;
  11. @Slf4j
  12. @ServerEndpoint(value = "/ws/url")
  13. @Component
  14. public class WebSocketServer implements ApplicationContextAware {
  15.     //线程安全的数据结构,防止线程冲突,Session就是和前端建立连接后由DI容器自动创建的
  16.     private final static ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
  17.     private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
  18.     //为了获取Bean的字段
  19.     private static ApplicationContext _applicationContext;
  20.     private static SysDataServer sysDataServer;
  21.     @Override
  22.     public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException         {
  23.         _applicationContext = applicationContext;
  24.         //启动定时任务
  25.         startScheduledTask();
  26.     }
  27.     /**
  28.      * 开始连接
  29.      * @param session 客户端传来的session
  30.      */
  31.     @OnOpen
  32.     public void onOpen(Session session) {
  33.         sessions.put(session.getId(), session);
  34.         session.setMaxIdleTimeout(30000);
  35.         System.out.println("连接:" + session.getId());
  36.     }
  37.     /**
  38.      * 收到客户端消息
  39.      * @param message 来自前端的消息
  40.      */
  41.     @OnMessage
  42.     public void onMessage(String message) {
  43.         log.info("onMessage: " + message);
  44.     }
  45.     /**
  46.      * 断开连接
  47.      */
  48.     @OnClose
  49.     public void onClose(Session session) {
  50.         for (String key : sessions.keySet()) {
  51.             if (key.equals(session.getId())) {
  52.                 sessions.remove(key);
  53.                 System.out.println("关闭" + session.getId());
  54.             }
  55.         }
  56.     }
  57.     /**
  58.      * 连接失败出现异常
  59.      * @param t 异常
  60.      */
  61.     @OnError
  62.     public void onError(Throwable t) {
  63.         log.error(t.getMessage(), t);
  64.     }
  65.     /**
  66.      * 定时任务启动,两秒一发送
  67.      */
  68.     private static void startScheduledTask(){
  69.         scheduler.scheduleAtFixedRate(()->{
  70.             sysDataServer = _applicationContext.getBean(SysDataServer.class);
  71.             
  72.             //我自己的业务逻辑,获取JsonString数据然后发给前端
  73.             String systemMessage = sysDataServer.toJSONString(sysDataServer.collectData());
  74.             broadcast(systemMessage);
  75.             
  76.         }, 0, 2, TimeUnit.SECONDS);
  77.     }
  78.    
  79.         //发送数据
  80.     private static void broadcast(String message){
  81.         for (Session session : sessions.values()) {
  82.             session.getAsyncRemote().sendText(message);
  83.             System.out.println("已发送:" + session.getId());
  84.         }
  85.     }
  86. }
复制代码
js部门代码展示
  1. import { ref } from 'vue';
  2. const processes = ref([]);
  3. const ws = new WebSocket('ws://localhost:8080/ws/url');
  4. ws.onopen = () => {
  5.   console.log('WebSocket 连接成功');
  6.   socket.send("Hello, Server!");
  7. };
  8. ws.onmessage = (event) => {
  9.   const data = JSON.parse(event.data);
  10.   // 处理后端数据
  11.   processes.value = data.map(process => ({
  12.     pid: process.pid,
  13.     pname: process.pName,
  14.     cpuUsage: process.processCpuUsage,
  15.     memoryUsage: process.processMemoryUsage
  16.   }));
  17. };
  18. ws.onclose = () => {
  19.   console.log('WebSocket 连接关闭');
  20. };
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

祗疼妳一个

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表