本文介绍如何使用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发送和请求消息的更多相关文章

  1. springboot成神之——ioc容器(依赖注入)

    springboot成神之--ioc容器(依赖注入) spring的ioc功能 文件目录结构 lang Chinese English GreetingService MyRepository MyC ...

  2. springboot成神之——springboot入门使用

    springboot创建webservice访问mysql(使用maven) 安装 起步 spring常用命令 spring常见注释 springboot入门级使用 配置你的pom.xml文件 配置文 ...

  3. springboot成神之——mybatis和mybatis-generator

    项目结构 依赖 generator配置文件 properties配置 生成文件 使用Example 本文讲解如何在spring-boot中使用mybatis和mybatis-generator自动生成 ...

  4. springboot成神之——swagger文档自动生成工具

    本文讲解如何在spring-boot中使用swagger文档自动生成工具 目录结构 说明 依赖 SwaggerConfig 开启api界面 JSR 303注释信息 Swagger核心注释 User T ...

  5. springboot成神之——log4j2的使用

    本文介绍如何在spring-boot中使用log4j2 说明 依赖 日志记录语句 log4j2配置文件 本文介绍如何在spring-boot中使用log4j2 说明 log4j2本身使用是非常简单的, ...

  6. springboot成神之——mybatis在spring-boot中使用的几种方式

    本文介绍mybatis在spring-boot中使用的几种方式 项目结构 依赖 WebConfig DemoApplication 方式一--@Select User DemoApplication ...

  7. springboot成神之——发送邮件

    本文介绍如何用spring发送邮件 目录结构 依赖 MailConfig TestController 测试 本文介绍如何用spring发送邮件 目录结构 依赖 <dependency> ...

  8. springboot成神之——basic auth和JWT验证结合

    本文介绍basic auth和JWT验证结合 目录结构 依赖 config配置文件WebSecurityConfig filter过滤器JWTLoginFilter filter过滤器JWTAuthe ...

  9. springboot成神之——Basic Auth应用

    本文介绍Basic Auth在spring中的应用 目录结构 依赖 入口DemoApplication 验证Authenication 配置WebSecurityConfig 控制器TestContr ...

随机推荐

  1. 对CSS了解-选择器权重

    <style type="text/css"> div.ui_infor p {font-size: 16px;} .ui_infor p {font-size: 14 ...

  2. 【spark】RDD操作

    RDD操作分为转换操作和行动操作. 对于RDD而言,每一次的转化操作都会产生不同的RDD,供一个操作使用. 我们每次转换得到的RDD是惰性求值的 也就是说,整个转换过程并不是会真正的去计算,而是只记录 ...

  3. Linux下的目录结构

    1./ -根 每个文件和目录从根目录开始 只有root用户具有该目录下的写权限,请注意,/root是root用户的主目录,这与/.不一样. 2. /bin  -用户二进制文件 包含二进制可执行的文件 ...

  4. 2017.11.7 Python 制作EFM32/ AVR批量烧录工具

    Customer need program quickly asap. ok,I need to set up a table for test. 1 reference data http://ww ...

  5. 探索Javascript 异步编程

    在我们日常编码中,需要异步的场景很多,比如读取文件内容.获取远程数据.发送数据到服务端等.因为浏览器环境里Javascript是单线程的,所以异步编程在前端领域尤为重要. 异步的概念 所谓异步,是指当 ...

  6. Thrift之java实例

    一.java实例 1.下载与安装thrift工具 http://thrift.apache.org/download/ .服务器代码 服务Test实现类 package com.zychen.thri ...

  7. 深度学习(六十二)SqueezeNet网络设计思想笔记

  8. python 环境变量设置

    Win+E --> 我的电脑 --> 右击 选择属性 --> 高级系统设置 --> 环境变量 --> 用户变量 中 找到 PATH(Path) --> 编辑 --& ...

  9. 机器学习(九)—FP-growth算法

    本来老师是想让我学Hadoop的,也装了Ubuntu,配置了Hadoop,一时间却不知从何学起,加之自己还是想先看点自己喜欢的算法,学习Hadoop也就暂且搁置了,不过还是想问一下园子里的朋友有什么学 ...

  10. 【ACM非算法部分】scanf()函数

    scanf函数 格式说明符: %c    字符型 %d    十进制数 %i     读入十进制,八进制,十六进制数.输入的时候正常是十进制数,若输入0前缀的数将读入八进制,0x前缀读入16进制.若输 ...