`
huangyongxing310
  • 浏览: 508747 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

SpringBootSpringSockJs 例子说明

阅读更多
SpringBootSpringSockJs 例子说明


<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-websocket</artifactId>
	<version>${spring.version}</version>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>



后端代码:
package com.cesmart.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
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
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
	@Override
	public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
		// 在网页上可以通过"/applicationName/hello"来和服务器的WebSocket连接
		// ,如:http://localhost:8090/test
		// setAllowedOrigins("*")表示可以跨域
		// withSockJS()表示支持socktJS访问,在浏览器中使用
		stompEndpointRegistry.addEndpoint("/test").setAllowedOrigins("*").withSockJS();

	}

	@Override
	public void configureMessageBroker(MessageBrokerRegistry messageBrokerRegistry) {
		// 1.订阅模块定义,可以多个,如:"/topic","/uset"
		// 2.就是前端订阅了那个模块,当服务器要向那个模块发送信息时就从模块中取出对应的session,(session表明了是那个前端用户)
		// 3.就是那些前缀的URL可以
		messageBrokerRegistry.enableSimpleBroker("/topicTest", "/userTest"); // ,"/user"
		// 这句表示客户端向服务端发送时的主题上面需要加"/app"作为前缀,如:/app/hello
		messageBrokerRegistry.setApplicationDestinationPrefixes("/app");
		// 1.这句表示给指定用户发送(一对一)的主题前缀,如“'/user/'+userid + '/otherMessage'”
		// 2.如果要使用@SendToUser,就不能设置这个,里面会自动实现一套方法,是在@SendToUser的URL前加“user+sessionId"组成
		messageBrokerRegistry.setUserDestinationPrefix("/userTest");
	}
}


package com.cesmart.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebTest {

	@Autowired
	private SimpMessagingTemplate simpMessagingTemplate;

	// 表示服务端接收客户端通过主题“/app/hello”发送过来的消息(服务端接收消息接口)
	@MessageMapping("/hello")
	// 表示这个函数执行完成后会广播结果到"/topicTest/sayHello"这个主题,前端如果订阅了这个主题就会收到这个信息,
	// 相当于simpMessagingTemplate.convertAndSend("/topicTest/sayHello",
	// "sayHello");
	@SendTo("/topicTest/sayHello")
	public String greeting(String msg) throws Exception {
		System.out.println("greeting == " + msg);
		// simpMessagingTemplate.convertAndSend("/topicTest/sayHello",
		// "sayHello");
		msg = msg + "表示服务端接收客户端通过主题";
		return msg;
	}

	// 表示服务端接收客户端通过主题“/app/hello”发送过来的消息(服务端接收消息接口)
	@MessageMapping("/hello2")
	// 表示这个函数执行完成后会广播结果到"/topicTest/sayHello"这个主题,前端如果订阅了这个主题就会收到这个信息,
	// 相当于simpMessagingTemplate.convertAndSend("/topicTest/sayHello",
	// "sayHello");
	// @SendToUser("/topicTest/sayHello2/otherMessage")
	// 相当于simpMessagingTemplate.convertAndSendToUser(user, "/otherMessage", "
	// ==SendToUser推送给单一用户2==");
	public String greeting2(String msg) throws Exception {
		System.out.println("greeting2 == " + msg);
		String user = msg;
		simpMessagingTemplate.convertAndSendToUser(user, "/otherMessage", "==SendToUser推送给单一用户2==");

		return msg;
	}

	// 表示服务端接收客户端通过主题“/app/hello”发送过来的消息(服务端接收消息接口)
	@MessageMapping("/hello3")
	// 表示这个函数执行完成后会广播结果到"/topicTest/sayHello"这个主题,前端如果订阅了这个主题就会收到这个信息,
	// 相当于simpMessagingTemplate.convertAndSend("/topicTest/sayHello",
	// "sayHello");
	@SendToUser("/userTest/sayHello3")
	// 相当于simpMessagingTemplate.convertAndSendToUser(user, "/otherMessage", "
	// ==SendToUser推送给单一用户2==");
	public String greeting3(String msg) throws Exception {
		System.out.println("greeting3 == " + msg);
		String user = msg;
		msg = msg + " ==SendToUser推送给单一用户3==";
		return msg;
	}
}



package com.cesmart;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@EnableAutoConfiguration
@ComponentScan(basePackages = "com.cesmart") // 扫描那些包得到bean.@ComponentScan({"com.teradata.notification","com.teradata.dal"})
public class Application {
	public static void main(String[] args) {
		ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
	}
}



前端代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <script src="http://121.43.38.142/webSocket/jquery-1.11.3.min.js"></script>
    <script type="text/javascript" src="//cdn.bootcss.com/sockjs-client/1.1.1/sockjs.min.js"></script>
    <script src="//cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>

    <script type="text/javascript">
        function connect() {
            var socket = new SockJS('http://localhost:8090/test');
            var userid = document.getElementById('userId').value;
            stompClient = Stomp.over(socket);
            stompClient.connect('', '', function (frame) {
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topicTest/sayHello', function(message) {
                    console.log('message ==  ' + message.body);
                    //alert(message.body);
                });
                stompClient.subscribe('/userTest/'+userid + '/otherMessage', function(message) {
                    console.log('sayHello2 message  ==  ' + message.body);
                });
                stompClient.subscribe('/user/userTest/sayHello3', function(message) {
                    console.log('sayHello3 message  ==  ' + message.body);
                });
            });
        }

        function disconnect() {
            if (stompClient != null) {
                stompClient.disconnect();
            }
            setConnected(false);
            console.log("Disconnected");
        }

        function sendName() {
            console.log("sendName");
            var name = document.getElementById('message').value;
            stompClient.send("/app/hello", {}, "sendName");
            console.log("sendName2");
        }

        function sendName2() {
            console.log("sendName");
            var userid = document.getElementById('userId').value;
            var name = document.getElementById('message').value;
            stompClient.send("/app/hello2", {}, userid);
            console.log("sendName2");
        }
        function sendName3() {
            console.log("sendName");
            var userid = document.getElementById('userId').value;
            var name = document.getElementById('message').value;
            stompClient.send("/app/hello3", {}, userid);
            console.log("sendName3");
        }

    </script>
</head>
<body>
<div>
    <button id="connect" onclick="connect()">连接</button>
    <button id="disconnect" onclick="disconnect()">断开连接</button>
    <button id="send" onclick="sendName()">发送消息</button>
    <button id="send2" onclick="sendName2()">发送消息2</button>
    <button id="send3" onclick="sendName3()">发送消息3</button>
    <button id="reconnect" onclick="reconnect()">重新连接</button>
</div>
<div>
    <textarea id="message" style="width: 350px">Here is a message!</textarea>
</div>
<div>
    <textarea id="userId" style="width: 350px">123456789</textarea>
</div>
<div>日志信息:</div>
<p id="console" width="600px"></p>
</body>
</html>



参考(spring websocket 使用@SendToUser):http://blog.csdn.net/yingxiake/article/details/51224569
参考(Spring WebSocket教程):http://www.tuicool.com/articles/EFJvya
分享到:
评论

相关推荐

    安川MP7系列工控系统源码解析:关键算法与硬件交互揭秘

    内容概要:本文深入剖析了安川MP7系列工业控制系统的关键源码,重点介绍了运动轨迹规划、通信协议处理以及故障处理机制等方面的技术细节。通过对实际代码片段的解读,揭示了该系统在硬件寄存器直接访问、特殊功能码处理等方面的独特之处。同时,文中还分享了一些基于实践经验得出的重要参数设置及其背后的故事,如特定摩擦补偿系数的选择原因等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对安川产品有一定了解并希望深入了解其内部工作机制的专业人士。 使用场景及目标:帮助读者掌握安川MP7系列控制器的工作原理,提高对类似系统的维护能力和故障排查效率。对于想要进一步研究或二次开发该系统的开发者来说,也能提供宝贵的参考资料。 其他说明:文章不仅限于理论讲解,还包括了许多来自一线的实际案例和经验教训,使读者能够更好地理解和应用所学知识。

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_.zip

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    风储直流微电网母线电压控制策略与双闭环MPPT技术研究

    内容概要:本文详细探讨了风储直流微电网中母线电压控制的关键技术。首先介绍了风储直流微电网的背景和发展现状,强调了母线电压控制的重要性。接着阐述了永磁风机储能并网技术,解释了永磁风机如何通过直接驱动发电机将风能转化为电能,并确保与电网的同步性和稳定性。然后深入讨论了双闭环控制MPPT技术,这是一种通过内外两个闭环控制系统来实现实时调整发电机运行参数的技术,确保风机始终处于最大功率点附近。最后,文章探讨了储能控制母线电压平衡的方法,即通过储能系统的充放电操作来维持母线电压的稳定。结论部分指出,通过这些技术的有机结合,可以实现对风储直流微电网的有效管理和优化控制。 适合人群:从事新能源技术研发的专业人士、电气工程研究人员、风电系统工程师。 使用场景及目标:适用于希望深入了解风储直流微电网母线电压控制策略的研究人员和技术人员,旨在帮助他们掌握最新的控制技术和方法,以提高系统的稳定性和效率。 其他说明:文章还对未来风储直流微电网的发展进行了展望,指出了智能化和自动化的趋势,以及储能技术的进步对系统性能的影响。

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    【操作系统开发】HarmonyOS目录结构详解:构建高效开发环境与跨设备协同应用

    内容概要:文章详细介绍了HarmonyOS的目录结构及其重要性,从整体框架到核心目录的具体功能进行了全面剖析。HarmonyOS凭借其分布式架构和跨设备协同能力迅速崛起,成为全球操作系统领域的重要力量。文章首先概述了HarmonyOS的背景和发展现状,强调了目录结构对开发的重要性。接着,具体介绍了根目录文件、AppScope、entry和oh_modules等核心目录的功能和作用。例如,AppScope作为全局资源配置中心,存放应用级的配置文件和公共资源;entry目录是应用的核心入口,负责源代码和界面开发。此外,文章还对比了HarmonyOS与Android、iOS目录结构的异同,突出了HarmonyOS的独特优势。最后,通过旅游应用和电商应用的实际案例,展示了HarmonyOS目录结构在资源管理和代码组织方面的应用效果。; 适合人群:具备一定编程基础,尤其是对移动操作系统开发感兴趣的开发者,包括初学者和有一定经验的研发人员。; 使用场景及目标:①帮助开发者快速理解HarmonyOS的目录结构,提高开发效率;②为跨设备应用开发提供理论和技术支持;③通过实际案例学习资源管理和代码组织的最佳实践。; 其他说明:HarmonyOS的目录结构设计简洁明了,模块职责划分明确,有助于开发者更好地管理和组织代码和资源。随着万物互联时代的到来,HarmonyOS有望在开发便利性和生态建设方面取得更大进展,吸引更多开发者加入其生态系统。

    飞轮储能充放电控制Simulink仿真模型:基于永磁同步电机的矢量控制与dq轴解耦

    内容概要:本文详细介绍了飞轮储能充放电控制的Simulink仿真模型,重点在于采用永磁同步电机的矢量控制和dq轴解耦控制策略。充电时,外环控制转速,内环控制dq轴电流;放电时,外环控制直流母线电压,内环同样控制dq轴电流。文中还讨论了硬件与软件环境的选择,以及仿真模型的调试与运行情况,最终得出该模型具有良好的跟随性能和波形完美度。 适用人群:从事电力电子系统、储能技术和Simulink仿真的研究人员和技术人员。 使用场景及目标:适用于需要对飞轮储能系统进行深入研究和仿真的场合,旨在提高充放电效率和稳定性,满足不同应用场景的需求。 其他说明:该仿真模型已调试完成,可以直接用于进一步的研究和实际应用,为未来的飞轮储能技术研发提供了有价值的参考。

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    1_15套python PDF格式.zip

    1_15套python PDF格式.zip

    三相三电平整流器仿真:基于电压电流双闭环控制与SPWM调制的性能分析

    内容概要:本文详细介绍了三相三电平整流器的仿真过程及其性能分析。文中首先概述了三相三电平整流器的基本概念及其在电力系统中的重要作用,接着重点探讨了电压电流双闭环控制方式的工作原理和优势,以及SPWM调制技术的具体应用。通过仿真文件展示了整流器在不同条件下的响应情况,验证了这两种技术的有效性和优越性。最后,作者表达了对未来实际应用的期望。 适合人群:从事电力电子研究的技术人员、高校相关专业师生、对电力控制系统感兴趣的工程爱好者。 使用场景及目标:适用于希望深入了解三相三电平整流器工作原理和技术细节的研究人员;目标是在理论基础上掌握电压电流双闭环控制和SPWM调制的实际应用方法。 其他说明:本文提供的仅为仿真文件,未涉及实物实验数据。

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    Arduino UART实验例程【正点原子EPS32S3】

    Arduino UART实验例程,开发板:正点原子EPS32S3,本人主页有详细实验说明可供参考。

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

    嵌入式八股文面试题库资料知识宝典-中科中科长青笔试题.zip

    嵌入式八股文面试题库资料知识宝典-中科中科长青笔试题.zip

    智能车辆自适应巡航ACC与纵向跟车避撞的分层式控制及模糊权重调整策略

    内容概要:本文详细介绍了自适应巡航(ACC)控制和纵向跟车避撞控制的分层式控制策略。上层控制通过建立离散跟车运动学模型和基于反馈校正的跟车预测模型,获得期望加速度;下层控制则根据上层提供的数据计算期望制动压力和节气门开度。文中特别强调了引入松弛因子进行多目标优化求解,以及利用模糊控制动态调整权重系数的方法,如车间距误差权重系数q_Δd、两车相对速度权重系数q_vrel和自车加速度权重系数q_ar。通过这种方式,系统能够在复杂多变的道路环境中保持灵活性和稳定性。仿真结果显示,在前车以50~70km/h的正弦速度变化行驶的情况下,自车能够平稳跟车,各项参数变化平稳。 适合人群:从事智能车辆研究的技术人员、自动驾驶领域研究人员、高校相关专业师生。 使用场景及目标:适用于智能车辆系统的设计与开发,特别是需要提升ACC系统性能的研究项目。目标是提高驾驶的安全性、舒适性和经济性。 其他说明:实验基于Matlab/Simulink 2021a和Carsim 2019.0版本完成,提供了完整的运行视频和参考资料。

Global site tag (gtag.js) - Google Analytics