admin 管理员组文章数量: 1086866
SpringBoot 2.0+ /springframwork 5 自带的websocket, 实现后台主动推消息给前端,及前端发消息给后台(全双工模式通信)
java实现 websocket 全双工模式的通信,除了 springframwork 5 自带的websocket,还可以用Tomcat 7+ 来实现,但 tomcat 7 onOpen() ,onMessage() , onClose() 感觉没有springframwork 5实现来的自然顺畅。
下面介绍实现实列 包括java 服务端,java客户端, 及 前端js部分 (附源码)
1.导入maven依赖
<!--核心依赖项--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-messaging</artifactId></dependency><!--自动生成 get set 等方法--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--js客户端的静态资源--><dependency><groupId>org.webjars</groupId><artifactId>webjars-locator-core</artifactId></dependency><dependency><groupId>org.webjars</groupId><artifactId>sockjs-client</artifactId><version>1.0.2</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>stomp-websocket</artifactId><version>2.3.3</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>bootstrap</artifactId><version>3.3.7</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.1.0</version></dependency>
2.工具类配置
定义一个访问地址的静态变量类
public class GlobalConsts {public static final String TOPIC = "/topic/greetings";public static final String ENDPOINT = "/gs-guide-websocket";public static final String APP_PREFIX = "/app";public static final String HELLO_MAPPING = "/hello";
}
服务端发消息的实体类
package com.ryh.websocket.demo.model;import lombok.AllArgsConstructor;
import lombok.Data;/*** @author ryh*/
@Data
@AllArgsConstructor
public class ServerMessage {private String content;public ServerMessage() {}@Overridepublic String toString() {return content;}}
客户端发消息的实体类
package com.ryh.websocket.demo.model;import lombok.AllArgsConstructor;
import lombok.Data;/*** @author ryh*/
@Data
@AllArgsConstructor
public class ClientMessage {private String name;public ClientMessage() {}}
3.websocket 服务端 配置类
package com.ryh.websocket.demo.config;import com.ryh.websocket.demo.consts.GlobalConsts;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;/*** @author ryh*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {config.enableSimpleBroker("/topic");// 设置主题config.setApplicationDestinationPrefixes(GlobalConsts.APP_PREFIX);// 设置访问前缀}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint(GlobalConsts.ENDPOINT).withSockJS();// 注册套接字js}}
4.服务端启动类
package com.ryh.websocket.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;/*** @author ryh*/
@EnableScheduling
@SpringBootApplication
public class DemoWebSocketServer {public static void main(String[] args) {SpringApplication.run(DemoWebSocketServer.class, args);}
}
5.服务端与客户端及前端通信的控制类
package com.ryh.websocket.demo.controller;import com.ryh.websocket.demo.consts.GlobalConsts;
import com.ryh.websocket.demo.model.ClientMessage;
import com.ryh.websocket.demo.model.ServerMessage;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.util.HtmlUtils;/*** Created with IntelliJ IDEA.* Description:** @author ryh**/
@Controller
public class GreetingController {@MessageMapping(GlobalConsts.HELLO_MAPPING)@SendTo(GlobalConsts.TOPIC)public ServerMessage greeting(ClientMessage message) throws Exception {// 模拟延时,以便测试客户端是否在异步工作Thread.sleep(1000);return new ServerMessage("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");}
}
6.js 及 html 客户端
html
<!DOCTYPE html>
<html>
<head><title>Hello WebSocket</title><link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet"><link href="/main.css" rel="stylesheet"><script src="/webjars/jquery/jquery.min.js"></script><script src="/webjars/sockjs-client/sockjs.min.js"></script><script src="/webjars/stomp-websocket/stomp.min.js"></script><script src="/app.js"></script>
</head>
<body>
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript beingenabled. Please enableJavascript and reload this page!</h2></noscript>
<div id="main-content" class="container"><div class="row"><div class="col-md-6"><form class="form-inline"><div class="form-group"><label for="connect">WebSocket connection:</label><button id="connect" class="btn btn-default" type="submit">Connect</button><button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect</button></div></form></div><div class="col-md-6"><form class="form-inline"><div class="form-group"><label for="name">What is your name?</label><input type="text" id="name" class="form-control" placeholder="Your name here..."></div><button id="send" class="btn btn-default" type="submit">Send</button></form></div></div><div class="row"><div class="col-md-12"><table id="conversation" class="table table-striped"><thead><tr><th>Greetings</th></tr></thead><tbody id="greetings"></tbody></table></div></div>
</div>
</body>
</html>
js
var stompClient = null;function setConnected(connected) {$("#connect").prop("disabled", connected);$("#disconnect").prop("disabled", !connected);if (connected) {$("#conversation").show();}else {$("#conversation").hide();}$("#greetings").html("");
}function connect() {var socket = new SockJS('/gs-guide-websocket');stompClient = Stomp.over(socket);stompClient.connect({}, function (frame) {setConnected(true);console.log('Connected: ' + frame);stompClient.subscribe('/topic/greetings', function (greeting) {showGreeting(JSON.parse(greeting.body).content);});});
}function disconnect() {if (stompClient !== null) {stompClient.disconnect();}setConnected(false);console.log("Disconnected");
}function sendName() {stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}function showGreeting(message) {$("#greetings").append("<tr><td>" + message + "</td></tr>");
}$(function () {$("form").on('submit', function (e) {e.preventDefault();});$( "#connect" ).click(function() { connect(); });$( "#disconnect" ).click(function() { disconnect(); });$( "#send" ).click(function() { sendName(); });
});
7.定时推送消息类
该类实现了,每分钟往前端发送消息的推送,(前提前端有和 服务端进行长连接,且没断开)
@Slf4j
@Component
public class SendMessageSchedule {@Autowiredprivate SimpMessagingTemplate simpMessagingTemplate;@Scheduled(fixedRate = 1000 * 60 * 1)//每分钟发一次public void releaseClaimPoint() {ServerMessage msg = new ServerMessage();Random random = new Random();Map<Integer, String> map = new HashMap<>();map.put(1,"德玛西亚之力 盖伦");map.put(2,"至高之拳 李青");map.put(3,"疾风剑豪 亚索");map.put(4,"迅捷斥候 提莫");map.put(5,"恐惧新星 德莱厄斯");map.put(6,"祖安狂人 蒙多");Integer[] keys = map.keySet().toArray(new Integer[0]);Integer randomKey = keys[random.nextInt(keys.length)];String randomName = map.get(randomKey);msg.setContent(randomName);log.info("往客户端发送的name是 "+randomName);simpMessagingTemplate.convertAndSend(TOPIC, msg);}
}
8.服务端发送消息
9.客户端接收请求
10.源码下载
本文标签: SpringBoot20springframwork 5 自带的websocket 实现后台主动推消息给前端,及前端发消息给后台(全双工模式通信)
版权声明:本文标题:SpringBoot2.0+springframwork 5 自带的websocket, 实现后台主动推消息给前端,及前端发消息给后台(全双工模式通信) 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1693756367a240995.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论