springboot成神之——websocket发送和请求消息
本文介绍如何使用websocket发送和请求消息
项目目录

依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
DemoApplication
package com.springlearn.learn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
MessageModel
package com.springlearn.learn.model;
public class MessageModel {
private String name;
public String getName() {
return "测试成功" + name;
}
public void setName(String name) {
this.name = name;
}
}
WebConfig
package com.springlearn.learn.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableScheduling
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
.allowedHeaders("*");
}
}
WebSocketConfig
package com.springlearn.learn.config;
import com.springlearn.learn.Handler.HttpHandshakeInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Autowired
private HttpHandshakeInterceptor handshakeInterceptor; // 这个是自定义的拦截器
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS().setInterceptors(handshakeInterceptor);
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app"); // 前端发送消息的前缀
registry.enableSimpleBroker("/topic"); // 前端接收后台消息和后台发送消息给前端的前缀
}
}
HttpHandshakeInterceptor
package com.springlearn.learn.Handler;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
@Component
public class HttpHandshakeInterceptor implements HandshakeInterceptor {
private static final Logger logger = LoggerFactory.getLogger(HttpHandshakeInterceptor.class);
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
logger.info("Call beforeHandshake"); // 和out一样,输出语句,正式开发用这个多
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
attributes.put("sessionId", session.getId());
}
return true;
}
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
logger.info("Call afterHandshake");
}
}
WebSocketEventListener
// 监听器,监听socket连接和短线
package com.springlearn.learn.listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectedEvent;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
@Component
public class WebSocketEventListener {
private static final Logger logger = LoggerFactory.getLogger(WebSocketEventListener.class);
@Autowired
private SimpMessageSendingOperations messagingTemplate;
@EventListener
public void handleWebSocketConnectListener(SessionConnectedEvent event) {
logger.info("Received a new web socket connection");
}
@EventListener
public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
String username = (String) headerAccessor.getSessionAttributes().get("username");
if(username != null) {
logger.info("User Disconnected : " + username);
messagingTemplate.convertAndSend("/topic/getResponse", "User Disconnected : " + username);
}
}
}
WebSocketController
package com.springlearn.learn.controller;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.springlearn.learn.model.MessageModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
@Controller
public class WebSocketController {
private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss sss");
@Autowired
private SimpMessageSendingOperations messagingTemplate;
@MessageMapping("/welcome")
@SendTo("/topic/getResponse")
public MessageModel sendMessage(@Payload MessageModel requestMessage, SimpMessageHeaderAccessor headerAccessor) {
headerAccessor.getSessionAttributes().put("username", requestMessage.getName());
MessageModel message = new MessageModel();
message.setName(requestMessage.getName());
return message;
}
@Scheduled(cron="* * * * * *" )
@SendTo("/topic/getResponse")
public Object callback() throws Exception {
Date now = new Date();
messagingTemplate.convertAndSend("/topic/getResponse", df.format(now));
return "callback";
}
}
前端测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<link rel="stylesheet" href="//unpkg.com/iview/dist/styles/iview.css">
<script src="//unpkg.com/iview/dist/iview.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
</head>
<body>
<div id="app">
</div>
<script>
new Vue({
el: '#app',
mounted () {
var stompClient = null;
var socket = new SockJS('http://localhost:9001/ws');
stompClient = Stomp.over(socket);
stompClient.connect(
{},
function (frame) {
stompClient.subscribe('/topic/getResponse', function (payload) {
console.log(payload.body)
})
stompClient.send(
"/app/welcome",
{},
JSON.stringify({name: "yejiawei"})
)
},
function(error) {
connectingElement.textContent = 'Could not connect to WebSocket server. Please refresh this page to try again!';
connectingElement.style.color = 'red';
}
);
setTimeout(function() {
stompClient.send(
"/app/welcome",
{},
JSON.stringify({name: "来自前端的请求"})
)
}, 3000)
}
})
</script>
</body>
</html>
springboot成神之——websocket发送和请求消息的更多相关文章
- springboot成神之——ioc容器(依赖注入)
springboot成神之--ioc容器(依赖注入) spring的ioc功能 文件目录结构 lang Chinese English GreetingService MyRepository MyC ...
- springboot成神之——springboot入门使用
springboot创建webservice访问mysql(使用maven) 安装 起步 spring常用命令 spring常见注释 springboot入门级使用 配置你的pom.xml文件 配置文 ...
- springboot成神之——mybatis和mybatis-generator
项目结构 依赖 generator配置文件 properties配置 生成文件 使用Example 本文讲解如何在spring-boot中使用mybatis和mybatis-generator自动生成 ...
- springboot成神之——swagger文档自动生成工具
本文讲解如何在spring-boot中使用swagger文档自动生成工具 目录结构 说明 依赖 SwaggerConfig 开启api界面 JSR 303注释信息 Swagger核心注释 User T ...
- springboot成神之——log4j2的使用
本文介绍如何在spring-boot中使用log4j2 说明 依赖 日志记录语句 log4j2配置文件 本文介绍如何在spring-boot中使用log4j2 说明 log4j2本身使用是非常简单的, ...
- springboot成神之——mybatis在spring-boot中使用的几种方式
本文介绍mybatis在spring-boot中使用的几种方式 项目结构 依赖 WebConfig DemoApplication 方式一--@Select User DemoApplication ...
- springboot成神之——发送邮件
本文介绍如何用spring发送邮件 目录结构 依赖 MailConfig TestController 测试 本文介绍如何用spring发送邮件 目录结构 依赖 <dependency> ...
- springboot成神之——basic auth和JWT验证结合
本文介绍basic auth和JWT验证结合 目录结构 依赖 config配置文件WebSecurityConfig filter过滤器JWTLoginFilter filter过滤器JWTAuthe ...
- springboot成神之——Basic Auth应用
本文介绍Basic Auth在spring中的应用 目录结构 依赖 入口DemoApplication 验证Authenication 配置WebSecurityConfig 控制器TestContr ...
随机推荐
- 开源分布式版本控制工具 —— Git 之旅
Git 主张的分布式代码库与文件快照的设计思想,相对于传统 CVS.SVN 等集中式.文件差异式版本控制工具是一种挑战与颠覆.Git 带来了离线提交.轻量级分支等诸多便利.不过,也有人质疑 Git 的 ...
- jfinal微信支付
private static final String appid = PropKit.get("appid"); //应用ID private static final Stri ...
- 【Hive】自定义函数
Hive的自定义函数无法满足实际业务的需要,所以为了扩展性,Hive官方提供了自定义函数来实现需要的业务场景. 1.定义 (1)udf(user defined function): 自定义函数,特 ...
- [转载]SVN trunk、branch、tag的用法
Subversion有一个很标准的目录结构,是这样的. 比如项目是proj,svn地址为svn://proj/,那么标准的svn布局是 svn://proj/|+-trunk+-branches+-t ...
- NSURLConnection / NSURLSession/ SDWebImage
1. NSURLConnection (iOS9开始被弃用)=========================================== 此类的对象加载一个URL请求对象,通过异步/同步的方 ...
- js 复制粘贴功能记录
最近工作中需要在前端页面中使用代码完成剪贴板的读写,网上搜索了下相应的资料,记录下... 这个功能有两个办法一个是js方式,一个是使用flash 一.JS方法 1.复制 首先复制的过程分为两步曲,无论 ...
- WAL日志文件名称格式详解
转自:http://blog.osdba.net/534.html WAL日志文件名称格式详解 PostgreSQL的WAL日志文件在pg_xlog目录下,一般情况下,每个文件为16M大小: osdb ...
- 西交利物浦大学Java PAPER CODE: CSE105/12-13/S1/Resit Coursework
Question 6:What is an accessor method?What is a mutator method? 答案参考:http://www.xmsydw.com Number An ...
- Android 发布Apk签名
1.签名的意义 为了保证每个应用程序开发商合法ID,防止部分开放商可能通过使用相同的Package Name来混淆替换已经安装的程序,我们需要对我们发布的APK文件进行唯一签名,保证我们每次发布的版本 ...
- kali视频(21-25)学习
第六周 kali视频(21-25)学习 21.密码攻击之在线攻击工具 22.密码攻击之离线攻击工具(一) 23.密码攻击之离线攻击工具(二) 24.密码攻击之哈希传递攻击 25.无线安全分析工具 21 ...