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 ...
随机推荐
- PinYin4JUtils
import java.util.Arrays; import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin ...
- python扫描proxy并获取可用代理ip列表
mac或linux下可以work的代码如下: # coding=utf-8 import requests import re from bs4 import BeautifulSoup as bs ...
- DDOS工具合集---CC 2.0(僵尸网络proxy,单一url,可设置cookie,refer),传奇克星(代理+单一url,可设置cookie),NetBot_Attacker网络僵尸1.0(僵尸网络,HTTP NO-Cache Get攻击模式,CC攻击,HTTP空GET请求攻击),傀儡僵尸VIP1.4版(僵尸网络,动态单一url)、上兴网络僵尸2.3、中国制造网络僵尸、安全基地网络僵尸==
DDOS工具合集 from:https://blog.csdn.net/chinafe/article/details/74928587 CC 著名的DDOS CC工具,效果非常好!CC 2.0使用了 ...
- 条款1:将c++视作一个语言联邦
c++是一个多重泛型编程语言,其所支持的泛型有: 面向过程编程(procedual) 面向对象编程(object-oriented) 面向函数编程(functional) 泛型编程(generic) ...
- Week03-Java学习笔记第三次作业
Week03-面向对象入门 1.本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联系. ...
- CSS3 Media Query 响应式媒体查询
在CSS中,有一个极其实用的功能:@media 响应式布局.具体来说,就是可以根据客户端的介质和屏幕大小,提供不同的样式表或者只展示样式表中的一部分.通过响应式布局,可以达到只使用单一文件提供多平台的 ...
- node 一站式 学习 教程
还是比较全面的, 包括了 : monogoDB的安装 使用 , 各种插件, 中间件的介绍, 路由的介绍, 各种数据库框架的介绍, 测试介绍; 掌握后应该可以开发一个中型的程序, 大型程序因为有性能的 ...
- scrapy 碎片
1.启动命令 2.目录结构 3.文件说明 4.架构图示 5.代码流程 参考资料: http://www.cnblogs.com/yangxt90/articles/9021530.html http: ...
- Flask的请求与响应
Flask的请求与响应 1 请求相关信息 request.method # 请求方法 request.args # get 请求的参数 request.form # post请求的参数 request ...
- java调用cmd执行maven命令
一.原理介绍 Java的Runtime.getRuntime().exec(commandStr)可以调用执行cmd指令. cmd /c dir 是执行完dir命令后封闭命令窗口. cmd /k di ...