该例是SpringBoot实战一书中的WebSocket实例,相当于照着打了一遍代码。。。
js下载:
http://download.youkuaiyun.com/download/qq_20867981/9959912
添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
配置文件:
package com.example.demo.part3.chapter7.WebSocket;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
//注解开启使用STOMP协议来传输基于代理message broker的消息
//这时控制器支持使用@messagemapping,就像使用@requestmapping一样
public class Ch763Config extends AbstractWebSocketMessageBrokerConfigurer {
@Override
////注册STOMP协议的节点(endpoint),并映射指定的Url
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
//注册一个stomp协议的endpoint,并指定使用socjJS协议
stompEndpointRegistry.addEndpoint("/endpointWisely").withSockJS();
}
@Override
//配置消息代理message broker
public void configureMessageBroker(MessageBrokerRegistry registry) {
//super.configureMessageBroker(registry);
//广播式应配置一个/topic消息代理
registry.enableSimpleBroker("/topic");
}
}
控制层:
package com.example.demo.part3.chapter7.WebSocket;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/ws")
public class WsController {
//这里的MessageMapping类似于RequestMapping
@MessageMapping("/welcome")
//当服务端有消息时,会对订阅了@sendto中 多路径的浏览器发送消息
@SendTo("/topic/getResponse")
public WiselyResponse sayWelcome(WiselyRequest request){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new WiselyResponse("Welcome"+request.getName()+"!");
}
}
两个实体类:
package com.example.demo.part3.chapter7.WebSocket;
//浏览器向服务端发送消息用此类接收
public class WiselyRequest {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.example.demo.part3.chapter7.WebSocket;
public class WiselyResponse {
private String resMsg;
public WiselyResponse(String resMsg) {
this.resMsg = resMsg;
}
public WiselyResponse() {
}
public String getResMsg() {
return resMsg;
}
public void setResMsg(String resMsg) {
this.resMsg = resMsg;
}
}
页面:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>SpringBoot+WebSocket+广播式</title>
</head>
<body onload="disconnect();">
<noscript><h2 style="color:#ff0000">貌似你的浏览器不支持websocket</h2></noscript>
<div>
<div>
<button id="connect" onclick="connect();">连接</button>
<button id="disconnect" onclick="disconnect();">断开连接</button>
</div>
<div id="inputDiv">
<label>输入你的名字</label><input type="text" id="name"/>
<button id="sendName" onclick="sendName();">发送</button>
<p id="response"></p>
</div>
</div>
<script th:src="@{sockjs.min.js}"></script>
<script th:src="@{stomp.min.js}"></script>
<script th:src="@{jquery-1.8.3.min.js}"></script>
<script type="text/javascript">
var stompClient=null;
function setConnected(connected) {
$("#connect").disable=connected;
$("#disconnect").disable=!connected;
// $("#inputDiv").style.visibility==connected? 'visible':'hidden';
$("#response").html();
}
function connect() {
//连接sockJs的endpoint名称为/endpointWisely
var socket=new SockJS('/endpointWisely');
//使用stomp子协议的websocket客户端
stompClient=Stomp.over(socket);
//连接websocket服务端
stompClient.connect({},function (frame) {
setConnected(true);
console.log('connected'+frame);
//通过stompClient.subscribe订阅/topic/getResponse目标(destination)发送的消息
//这个是在@SendTo("/topic/getResponse")中定义的
stompClient.subscribe('/topic/getResponse',function (response) {
showResponse(JSON.parse(response.body).responseText);
})
})
}
function disconnect() {
if(stompClient!=null){
stompClient.disconnect();
}
setConnected(false);
console.log("disconnected");
}
function sendName() {
var name=$("#name").val();
//通过stompClient.send向/welcome目标(destination)发送消息
//这个是在控制器的@MessageMapping("/welcome")中定义的
stompClient.send("/welcome",{},JSON.stringify({"name":name}));
}
function showResponse(message) {
var response=$("#response");
response.html(message);
}
</script>
</body>
</html>
配置viewController,为访问ws.html提供便捷的路径映射:
package com.example.demo.part3.chapter7.WebSocket;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//super.addViewControllers(registry);
registry.addViewController("/ws").setViewName("/ws");
}
}