一、websocket是一种有状态的协议,可以实现服务器和客户端进行相互发送消息。以下是一个类似与controller的接口实现,请求的路径:/websocket
1 @ServerEndpoint(value = "/websocket") 2 @Component 3 public class HighfreqAvgController { 4 private TestService testService; 5 6 private static ApplicationContext applicationContext; 7 8 public static void setApplicationContext(ApplicationContext context) { 9 applicationContext = context; 10 } 11 12 // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 13 private static int onlineCount = 0; 14 15 // concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 16 private static CopyOnWriteArraySet<HighfreqAvgController> webSocketSet = new CopyOnWriteArraySet<HighfreqAvgController>(); 17 18 // 与某个客户端的连接会话,需要通过它来给客户端发送数据 19 private Session session; 20 21 /** 22 * 连接建立成功调用的方法 23 * 24 * @throws InterruptedException 25 */ 26 @OnOpen 27 public void onOpen(Session session) throws InterruptedException { 28 testService = applicationContext.getBean(TestService.class); 29 this.session = session; 30 webSocketSet.add(this); // 加入set中 31 addOnlineCount(); // 在线数加1 32 System.out.println("有新连接加入!当前在线人数为" + getOnlineCount()); 33 try { 34 35 while (true) { 36 37 Thread.sleep(1000); 38 String allValue = testService.test(); 39 if (allValue == null) { 40 break; 41 } 42 System.out.println(allValue); 43 sendMessage(allValue); 44 45 } 46 } catch (IOException e) { 47 System.out.println("IO异常"); 48 } 49 } 50 51 /** 52 * 连接关闭调用的方法 53 */ 54 @OnClose 55 public void onClose() { 56 webSocketSet.remove(this); // 从set中删除 57 subOnlineCount(); // 在线数减1 58 System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount()); 59 } 60 61 /** 62 * 收到客户端消息后调用的方法 63 * 64 * @param message 65 * 客户端发送过来的消息 66 */ 67 @OnMessage 68 public void onMessage(String message, Session session) { 69 System.out.println("来自客户端的消息:" + message); 70 71 // 群发消息 72 for (HighfreqAvgController item : webSocketSet) { 73 try { 74 item.sendMessage(message); 75 } catch (IOException e) { 76 e.printStackTrace(); 77 } 78 } 79 } 80 81 @OnError 82 public void onError(Session session, Throwable error) { 83 System.out.println("发生错误"); 84 error.printStackTrace(); 85 } 86 87 public void sendMessage(String message) throws IOException { 88 this.session.getBasicRemote().sendText(message); 89 } 90 91 /** 92 * 群发自定义消息 93 */ 94 public static void sendInfo(String message) throws IOException { 95 for (HighfreqAvgController item : webSocketSet) { 96 try { 97 item.sendMessage(message); 98 } catch (IOException e) { 99 continue; 100 } 101 } 102 } 103 104 public static synchronized int getOnlineCount() { 105 return onlineCount; 106 } 107 108 public static synchronized void addOnlineCount() { 109 HighfreqAvgController.onlineCount++; 110 } 111 112 public static synchronized void subOnlineCount() { 113 HighfreqAvgController.onlineCount--; 114 } 115 116 }
从运行现象来看,该类并没有交给spring容器进行管理,因此注入不了service层中的bean,经过查找网上的大量的资料,在启动springboot类中就注入ApplicationContext对象,然后就可以获取到service层的对象。
@SpringBootApplication public class HighfreqAvgApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContest = SpringApplication.run(HighfreqAvgApplication.class, args); HighfreqAvgController.setApplicationContext(applicationContest); } }
pom导入websocket
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
具体参考博客:https://segmentfault.com/q/1010000010103973