当前位置:   article > 正文

(java)websocket服务的两种实现方式_java websocket 服务端

java websocket 服务端

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

1.1需要的类

1.1.1服务终端类

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

1.1.2配置类

把spring中的ServerEndpointExporter对象注入进来

2.1代码示例

2.1.1 maven配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.heima</groupId>
  7. <artifactId>ws-demo</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <properties>
  10. <maven.compiler.source>8</maven.compiler.source>
  11. <maven.compiler.target>8</maven.compiler.target>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. </properties>
  14. <dependencies>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-starter</artifactId>
  18. <version>2.7.3</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.projectlombok</groupId>
  22. <artifactId>lombok</artifactId>
  23. <version>1.16.22</version>
  24. </dependency>
  25. <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket -->
  26. <dependency>
  27. <groupId>org.springframework.boot</groupId>
  28. <artifactId>spring-boot-starter-websocket</artifactId>
  29. <version>2.7.14</version>
  30. </dependency>
  31. </dependencies>
  32. </project>

2.1.2 WsServerEndpoint类

  1. package com.heima;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.scheduling.annotation.EnableScheduling;
  4. import org.springframework.scheduling.annotation.Scheduled;
  5. import org.springframework.stereotype.Component;
  6. import javax.websocket.OnClose;
  7. import javax.websocket.OnMessage;
  8. import javax.websocket.OnOpen;
  9. import javax.websocket.Session;
  10. import javax.websocket.server.ServerEndpoint;
  11. import java.io.IOException;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. import java.util.concurrent.ConcurrentHashMap;
  15. /***
  16. * 监听websocket地址 /myWs
  17. */
  18. @ServerEndpoint("/myWs")
  19. @Component
  20. @Slf4j
  21. @EnableScheduling
  22. public class WsServerEndpoint {
  23. static Map<String,Session> map = new ConcurrentHashMap<String,Session>();
  24. /***
  25. * 连接建立时执行的操作
  26. * @param session
  27. */
  28. @OnOpen
  29. public void onOpen(Session session)
  30. {
  31. map.put(session.getId(),session);
  32. log.info("websocket is open");
  33. }
  34. /***
  35. * 收到客户端消息执行的操作
  36. * @param text
  37. */
  38. @OnMessage
  39. public String OnMessage(String text)
  40. {
  41. log.info("收到了一条信息"+text);
  42. return "已收到你的信息" ;
  43. }
  44. /***
  45. * 连接关闭时执行的操作
  46. * @param session
  47. */
  48. @OnClose
  49. public void OnClose(Session session)
  50. {
  51. map.remove(session.getId());
  52. log.info("连接关闭时执行的操作");
  53. }
  54. /***
  55. * 向客户端发送信息
  56. */
  57. @Scheduled(fixedRate = 2000)
  58. public void sendMsg() throws IOException {
  59. for (String key : map.keySet())
  60. {
  61. map.get(key).getBasicRemote().sendText("你好,你好");
  62. }
  63. }
  64. }

2.1.3 WebSocketConfig

  1. package com.heima;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  5. @Configuration
  6. public class WebSocketConfig {
  7. @Bean
  8. public ServerEndpointExporter serverEndpointExporter()
  9. {
  10. return new ServerEndpointExporter();
  11. }
  12. }

2.1.3 前端测试代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>wsClient</title>
  6. </head>
  7. <body>
  8. <script>
  9. // 创建websocket
  10. let ws = new WebSocket("ws://localhost:8080/myWs")
  11. //向服务器发送hello
  12. ws.onopen=function (){
  13. ws.send("hello")
  14. }
  15. //监听数据ws://localhost:8080/myWs
  16. ws.onmessage=function (message){
  17. console.log(message.data)
  18. }
  19. </script>
  20. </body>
  21. </html>

2.1.4测试结果

2.1.4.1 当打开浏览器时

2.1.4.2 当关闭浏览器时

2.1.4.3 当刷新浏览器的时候

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

2.1:HttpSessionHandShakeInter 握手拦截器

  1. package com.spring;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.http.server.ServerHttpRequest;
  5. import org.springframework.http.server.ServerHttpResponse;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.web.socket.WebSocketHandler;
  8. import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
  9. import java.util.Map;
  10. /***
  11. * 握手拦截器
  12. */
  13. @Component
  14. @Slf4j
  15. public class MyWsInterceptor extends HttpSessionHandshakeInterceptor {
  16. @Override
  17. public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
  18. log.info(request.getRemoteAddress().toString()+"开始握手");
  19. return super.beforeHandshake(request, response, wsHandler, attributes);
  20. }
  21. @Override
  22. public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
  23. log.info(request.getRemoteAddress().toString()+"完成握手");
  24. super.afterHandshake(request, response, wsHandler, ex);
  25. }
  26. }

2.2  MyWsHandler 主处理程序

sessionbean封装类
  1. import lombok.AllArgsConstructor;
  2. import lombok.Data;
  3. import org.springframework.web.socket.WebSocketSession;
  4. @Data
  5. @AllArgsConstructor
  6. public class SessionBean {
  7. private WebSocketSession webSocketSession;
  8. private Integer clientId;
  9. }
 主处理程序
  1. package com.spring;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.boot.web.servlet.server.Session;
  4. import org.springframework.scheduling.annotation.EnableScheduling;
  5. import org.springframework.scheduling.annotation.Scheduled;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.web.socket.CloseStatus;
  8. import org.springframework.web.socket.TextMessage;
  9. import org.springframework.web.socket.WebSocketSession;
  10. import org.springframework.web.socket.handler.AbstractWebSocketHandler;
  11. import java.io.IOException;
  12. import java.util.Map;
  13. import java.util.concurrent.ConcurrentHashMap;
  14. import java.util.concurrent.atomic.AtomicInteger;
  15. /***
  16. * webSocket 主处理程序
  17. */
  18. @Component
  19. @Slf4j
  20. @EnableScheduling
  21. public class MyWsHandler extends AbstractWebSocketHandler {
  22. //map有并发线程问题 所以用ConcurrentHashMap
  23. private static Map<String, SessionBean> map ;
  24. //id有并发问题 所以用Integer的安全类型
  25. private static AtomicInteger clientIdMaker;
  26. static {
  27. map = new ConcurrentHashMap<>();
  28. clientIdMaker=new AtomicInteger(0);
  29. }
  30. //连接建立
  31. @Override
  32. public void afterConnectionEstablished(WebSocketSession session) throws Exception {
  33. super.afterConnectionEstablished(session);
  34. //将session 进一步封装 id采用的是自增
  35. SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());
  36. map.put(session.getId(),sessionBean);
  37. log.info(map.get(session.getId()).getClientId()+"建立了连接");
  38. }
  39. //收到消息
  40. @Override
  41. protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
  42. super.handleTextMessage(session, message);
  43. log.info(map.get(session.getId()).getClientId()+":"+message.getPayload());
  44. }
  45. //传输异常
  46. @Override
  47. public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
  48. super.handleTransportError(session, exception);
  49. if (session.isOpen())
  50. {
  51. session.close();
  52. }
  53. map.remove(session.getId());
  54. }
  55. //连接关闭
  56. @Override
  57. public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
  58. super.afterConnectionClosed(session, status);
  59. log.info(map.get(session.getId()).getClientId()+"关闭连接");
  60. }
  61. /***
  62. * 向客户端发送信息
  63. */
  64. @Scheduled(fixedRate = 2000)
  65. public void sendMsg() throws IOException {
  66. for (String key : map.keySet())
  67. {
  68. map.get(key).getWebSocketSession().sendMessage(new TextMessage("hello," +
  69. "spring socket"));
  70. }
  71. }
  72. }

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

  1. package com.spring;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.socket.config.annotation.EnableWebSocket;
  4. import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
  5. import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
  6. import javax.annotation.Resource;
  7. @Configuration
  8. @EnableWebSocket
  9. public class MyWsConfig implements WebSocketConfigurer {
  10. @Resource
  11. private MyWsHandler wsHandler;
  12. @Resource
  13. private MyWsInterceptor wsInterceptor;
  14. @Override
  15. public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
  16. registry.addHandler(wsHandler,"/myWs1").addInterceptors(wsInterceptor).setAllowedOriginPatterns("*");
  17. }
  18. }

2.4 前端测试

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>wsClient</title>
  6. </head>
  7. <body>
  8. <script>
  9. // 创建websocket
  10. let ws = new WebSocket("ws://localhost:8080/myWs1")
  11. //向服务器发送hello
  12. ws.onopen=function (){
  13. ws.send("hello")
  14. }
  15. //监听数据ws://localhost:8080/myWs
  16. ws.onmessage=function (message){
  17. console.log(message.data)
  18. }
  19. </script>
  20. </body>
  21. </html>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/954706
推荐阅读
相关标签
  

闽ICP备14008679号