(java)websocket服务的两种实现方式
创始人
2024-11-06 03:07:54

1.基于java注解实现websocket服务器端

1.1需要的类

1.1.1服务终端类

用java注解来监听连接@ServerEndpoint、连接成功@OnOpen、连接失败@OnClose、收到消息等状态@OnMessage

1.1.2配置类

把spring中的ServerEndpointExporter对象注入进来

2.1代码示例

2.1.1 maven配置

      4.0.0      com.heima     ws-demo     1.0-SNAPSHOT               8         8         UTF-8                                org.springframework.boot             spring-boot-starter            2.7.3                               org.projectlombok             lombok             1.16.22                                        org.springframework.boot             spring-boot-starter-websocket             2.7.14                   

2.1.2 WsServerEndpoint类

package com.heima;  import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;  import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap;  /***  * 监听websocket地址  /myWs  */ @ServerEndpoint("/myWs") @Component @Slf4j @EnableScheduling public class WsServerEndpoint {      static Map map = new ConcurrentHashMap();      /***      * 连接建立时执行的操作      * @param session      */     @OnOpen     public void onOpen(Session session)     {         map.put(session.getId(),session);         log.info("websocket is open");     }      /***      * 收到客户端消息执行的操作      * @param text      */     @OnMessage     public String OnMessage(String text)     {         log.info("收到了一条信息"+text);         return "已收到你的信息" ;     }      /***      * 连接关闭时执行的操作      * @param session      */     @OnClose     public void OnClose(Session session)     {         map.remove(session.getId());         log.info("连接关闭时执行的操作");     }      /***      * 向客户端发送信息      */     @Scheduled(fixedRate = 2000)     public void sendMsg() throws IOException {         for (String key : map.keySet())         {             map.get(key).getBasicRemote().sendText("你好,你好");         }     } } 

2.1.3 WebSocketConfig

package com.heima;  import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter;  @Configuration public class WebSocketConfig {       @Bean  public ServerEndpointExporter serverEndpointExporter()  {      return new ServerEndpointExporter();  }    } 

2.1.3 前端测试代码

            wsClient      

2.1.4测试结果

2.1.4.1 当打开浏览器时

2.1.4.2 当关闭浏览器时

2.1.4.3 当刷新浏览器的时候

2.基于spring提供的类和接口刷新websocket服务器端

2.1:HttpSessionHandShakeInter 握手拦截器

package com.spring;  import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;  import java.util.Map;  /***  * 握手拦截器  */ @Component @Slf4j public class MyWsInterceptor extends HttpSessionHandshakeInterceptor {       @Override     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception {         log.info(request.getRemoteAddress().toString()+"开始握手");         return super.beforeHandshake(request, response, wsHandler, attributes);     }      @Override     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {          log.info(request.getRemoteAddress().toString()+"完成握手");         super.afterHandshake(request, response, wsHandler, ex);     } } 

2.2  MyWsHandler 主处理程序

sessionbean封装类
import lombok.AllArgsConstructor; import lombok.Data; import org.springframework.web.socket.WebSocketSession;  @Data @AllArgsConstructor public class SessionBean {     private WebSocketSession webSocketSession;     private Integer clientId; } 
 主处理程序
package com.spring;  import lombok.extern.slf4j.Slf4j; import org.springframework.boot.web.servlet.server.Session; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.AbstractWebSocketHandler;  import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger;  /***  * webSocket 主处理程序  */ @Component @Slf4j @EnableScheduling public class MyWsHandler extends AbstractWebSocketHandler {     //map有并发线程问题  所以用ConcurrentHashMap     private static Map map ;     //id有并发问题 所以用Integer的安全类型     private static AtomicInteger clientIdMaker;     static {          map = new ConcurrentHashMap<>();         clientIdMaker=new AtomicInteger(0);     }     //连接建立     @Override     public void afterConnectionEstablished(WebSocketSession session) throws Exception {         super.afterConnectionEstablished(session);         //将session 进一步封装  id采用的是自增         SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());         map.put(session.getId(),sessionBean);         log.info(map.get(session.getId()).getClientId()+"建立了连接");     }      //收到消息     @Override     protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {         super.handleTextMessage(session, message);         log.info(map.get(session.getId()).getClientId()+":"+message.getPayload());     }      //传输异常     @Override     public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {         super.handleTransportError(session, exception);          if (session.isOpen())         {             session.close();         }         map.remove(session.getId());      }     //连接关闭     @Override     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {         super.afterConnectionClosed(session, status);         log.info(map.get(session.getId()).getClientId()+"关闭连接");     }      /***      * 向客户端发送信息      */     @Scheduled(fixedRate = 2000)     public void sendMsg() throws IOException {         for (String key : map.keySet())         {             map.get(key).getWebSocketSession().sendMessage(new TextMessage("hello," +                     "spring socket"));         }     } } 

2.3 WebSocketConfigurer 注册拦截器和主处理程序以及监听路径

package com.spring;  import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;  import javax.annotation.Resource;  @Configuration @EnableWebSocket public class MyWsConfig implements WebSocketConfigurer {     @Resource     private MyWsHandler wsHandler;     @Resource     private MyWsInterceptor wsInterceptor;     @Override     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {         registry.addHandler(wsHandler,"/myWs1").addInterceptors(wsInterceptor).setAllowedOriginPatterns("*");     } } 

2.4 前端测试

            wsClient      

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...