SpringMVC整合websocket实现消息推送及触发

1.创建websocket握手协议的后台

(1)HandShake的实现类

/**
 *Project Name: price
 *File Name:    HandShake.java
 *Package Name: com.yun.websocket
 *Date:         2016年9月3日 下午4:44:27
 *Copyright (c) 2016,578888218@qq.com All Rights Reserved.
*/

package com.yun.websocket;

import java.util.Map;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

/**
 *Title:      HandShake<br/>
 *Description:
 *@Company:   青岛励图高科<br/>
 *@author:    刘云生
 *@version:   v1.0
 *@since:     JDK 1.7.0_80
 *@Date:      2016年9月3日 下午4:44:27 <br/>
*/
public class HandShake implements HandshakeInterceptor{

	@Override
	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
			Map<String, Object> attributes) throws Exception {
		// TODO Auto-generated method stub
		String jspCode = ((ServletServerHttpRequest) request).getServletRequest().getParameter("jspCode");
		// 标记用户
		//String userId = (String) session.getAttribute("userId");
		if(jspCode!=null){
			attributes.put("jspCode", jspCode);
		}else{
			return false;
		}
		return true;
	}

	@Override
	public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
			Exception exception) {
		// TODO Auto-generated method stub
		
	}

}


(2)MyWebSocketConfig的实现类

/**
 *Project Name: price
 *File Name:    MyWebSocketConfig.java
 *Package Name: com.yun.websocket
 *Date:         2016年9月3日 下午4:52:29
 *Copyright (c) 2016,578888218@qq.com All Rights Reserved.
*/

package com.yun.websocket;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

/**
 *Title:      MyWebSocketConfig<br/>
 *Description:
 *@Company:   青岛励图高科<br/>
 *@author:    刘云生
 *@version:   v1.0
 *@since:     JDK 1.7.0_80
 *@Date:      2016年9月3日 下午4:52:29 <br/>
*/
@Component
@EnableWebMvc
@EnableWebSocket
public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{
   @Resource
	MyWebSocketHandler handler;
	
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		// TODO Auto-generated method stub
		registry.addHandler(handler, "/wsMy").addInterceptors(new HandShake());
		registry.addHandler(handler, "/wsMy/sockjs").addInterceptors(new HandShake()).withSockJS();
	}

}

(3)MyWebSocketHandler的实现类

/**
 *Project Name: price
 *File Name:    MyWebSocketHandler.java
 *Package Name: com.yun.websocket
 *Date:         2016年9月3日 下午4:55:12
 *Copyright (c) 2016,578888218@qq.com All Rights Reserved.
*/

package com.yun.websocket;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import com.google.gson.GsonBuilder;

/**
 *Title:      MyWebSocketHandler<br/>
 *Description:
 *@Company:   青岛励图高科<br/>
 *@author:    刘云生
 *@version:   v1.0
 *@since:     JDK 1.7.0_80
 *@Date:      2016年9月3日 下午4:55:12 <br/>
*/
@Component
public class MyWebSocketHandler implements WebSocketHandler{

	public static final Map<String, WebSocketSession> userSocketSessionMap;

	static {
		userSocketSessionMap = new HashMap<String, WebSocketSession>();
	}
	
	
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		// TODO Auto-generated method stub
		String jspCode = (String) session.getHandshakeAttributes().get("jspCode");
		if (userSocketSessionMap.get(jspCode) == null) {
			userSocketSessionMap.put(jspCode, session);
		}
		for(int i=0;i<10;i++){
			//broadcast(new TextMessage(new GsonBuilder().create().toJson("\"number\":\""+i+"\"")));
			session.sendMessage(new TextMessage(new GsonBuilder().create().toJson("\"number\":\""+i+"\"")));
		}
	}

	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
		// TODO Auto-generated method stub
		//Message msg=new Gson().fromJson(message.getPayload().toString(),Message.class);
		//msg.setDate(new Date());
//		sendMessageToUser(msg.getTo(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg)));
		
		session.sendMessage(message);
	}

	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		// TODO Auto-generated method stub
		if (session.isOpen()) {
			session.close();
		}
		Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap
				.entrySet().iterator();
		// 移除Socket会话
		while (it.hasNext()) {
			Entry<String, WebSocketSession> entry = it.next();
			if (entry.getValue().getId().equals(session.getId())) {
				userSocketSessionMap.remove(entry.getKey());
				System.out.println("Socket会话已经移除:用户ID" + entry.getKey());
				break;
			}
		}
	}

	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Websocket:" + session.getId() + "已经关闭");
		Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap
				.entrySet().iterator();
		// 移除Socket会话
		while (it.hasNext()) {
			Entry<String, WebSocketSession> entry = it.next();
			if (entry.getValue().getId().equals(session.getId())) {
				userSocketSessionMap.remove(entry.getKey());
				System.out.println("Socket会话已经移除:用户ID" + entry.getKey());
				break;
			}
		}
	}

	@Override
	public boolean supportsPartialMessages() {
		// TODO Auto-generated method stub
		return false;
	}
	/**
	 * 群发
	 * @Title:       broadcast  
	 * @Description: TODO  
	 * @param:       @param message
	 * @param:       @throws IOException
	 * @return:      void
	 * @author:      刘云生
	 * @Date:        2016年9月10日 下午4:23:30   
	 * @throws
	 */
	public void broadcast(final TextMessage message) throws IOException {
		Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap
				.entrySet().iterator();

		// 多线程群发
		while (it.hasNext()) {

			final Entry<String, WebSocketSession> entry = it.next();

			if (entry.getValue().isOpen()) {
				new Thread(new Runnable() {

					public void run() {
						try {
							if (entry.getValue().isOpen()) {
								entry.getValue().sendMessage(message);
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
					}

				}).start();
			}

		}
	}
	
	/**
	 * 给所有在线用户的实时工程检测页面发送消息
	 * 
	 * @param message
	 * @throws IOException
	 */
	public void sendMessageToJsp(final TextMessage message,String type) throws IOException {
		Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap
				.entrySet().iterator();

		// 多线程群发
		while (it.hasNext()) {

			final Entry<String, WebSocketSession> entry = it.next();
			if (entry.getValue().isOpen() && entry.getKey().contains(type)) {
				new Thread(new Runnable() {

					public void run() {
						try {
							if (entry.getValue().isOpen()) {
								entry.getValue().sendMessage(message);
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
					}

				}).start();
			}

		}
	}
}


2.创建websocket握手处理的前台

<script>
	var path = '<%=basePath%>';
	var userId = 'lys';
	if(userId==-1){
		window.location.href="<%=basePath2%>";
	}
	var jspCode = userId+"_AAA";
	var websocket;
	if ('WebSocket' in window) {
		websocket = new WebSocket("ws://" + path + "wsMy?jspCode=" + jspCode);
	} else if ('MozWebSocket' in window) {
		websocket = new MozWebSocket("ws://" + path + "wsMy?jspCode=" + jspCode);
	} else {
		websocket = new SockJS("http://" + path + "wsMy/sockjs?jspCode=" + jspCode);
	}
	websocket.onopen = function(event) {
		console.log("WebSocket:已连接");
		console.log(event);
	};
	websocket.onmessage = function(event) {
		var data = JSON.parse(event.data);
		console.log("WebSocket:收到一条消息-norm", data);
		alert("WebSocket:收到一条消息");
	};
	websocket.onerror = function(event) {
		console.log("WebSocket:发生错误 ");
		console.log(event);
	};
	websocket.onclose = function(event) {
		console.log("WebSocket:已关闭");
		console.log(event);
	}
</script>


3.通过Controller调用进行websocket的后台推送

/**
 *Project Name: price
 *File Name:    GarlicPriceController.java
 *Package Name: com.yun.price.garlic.controller
 *Date:         2016年6月23日 下午3:23:46
 *Copyright (c) 2016,578888218@qq.com All Rights Reserved.
*/

package com.yun.price.garlic.controller;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.socket.TextMessage;

import com.google.gson.GsonBuilder;
import com.yun.common.entity.DataGrid;
import com.yun.price.garlic.dao.entity.GarlicPrice;
import com.yun.price.garlic.model.GarlicPriceModel;
import com.yun.price.garlic.service.GarlicPriceService;
import com.yun.websocket.MyWebSocketHandler;

/**
 * Title: GarlicPriceController<br/>
 * Description:
 * 
 * @Company: 青岛励图高科<br/>
 * @author: 刘云生
 * @version: v1.0
 * @since: JDK 1.7.0_80
 * @Date: 2016年6月23日 下午3:23:46 <br/>
 */
@Controller
public class GarlicPriceController {
	@Resource
	MyWebSocketHandler myWebSocketHandler;
	@RequestMapping(value = "GarlicPriceController/testWebSocket", method ={RequestMethod.POST,RequestMethod.GET}, produces = "application/json; charset=utf-8")
	@ResponseBody
	public String testWebSocket() throws IOException{
		myWebSocketHandler.sendMessageToJsp(new TextMessage(new GsonBuilder().create().toJson("\"number\":\""+"GarlicPriceController/testWebSocket"+"\"")), "AAA");
		return "1";
	}
	
}


4.所用到的jar包

<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-websocket</artifactId>
		<version>4.0.1.RELEASE</version>
</dependency>  

5.运行的环境

至少tomcat8.0以上版本,否则可能报错
  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
### 回答1: SpringMVC整合WebSocket可以通过以下步骤实现: 1. 添加WebSocket依赖 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>5.3.9</version> </dependency> ``` 2. 配置WebSocketSpringMVC配置文件中添加以下配置: ``` @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new MyWebSocketHandler(), "/my-websocket"); } } ``` 其中,MyWebSocketHandler是自定义的WebSocket处理器,"/my-websocket"是WebSocket的访问路径。 3. 编写WebSocket处理器 自定义的WebSocket处理器需要实现WebSocketHandler接口,例如: ``` public class MyWebSocketHandler implements WebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 连接建立后的处理逻辑 } @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { // 处理收到的消息 } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { // 处理传输错误 } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { // 连接关闭后的处理逻辑 } @Override public boolean supportsPartialMessages() { return false; } } ``` 4. 编写WebSocket客户端 可以使用JavaScript或其他语言编写WebSocket客户端,例如: ``` var socket = new WebSocket("ws://localhost:8080/my-websocket"); socket.onopen = function() { // 连接建立后的处理逻辑 }; socket.onmessage = function(event) { // 处理收到的消息 }; socket.onclose = function(event) { // 连接关闭后的处理逻辑 }; ``` 以上就是SpringMVC整合WebSocket的基本步骤。 ### 回答2: Spring MVC 是一个基于 Java 的 Web 框架,可以将 WebSocket 整合到 Spring MVC 中,实现实时通信的功能。下面详细介绍 Spring MVC 整合 WebSocket 的步骤: 1. 配置 Maven 依赖:在 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>4.3.13.RELEASE</version> </dependency> ``` 2. 配置 WebSocket 消息处理器:创建一个类来处理 WebSocket 消息。该类需要实现 `WebSocketHandler` 接口,实现处理 WebSocket 消息的方法。 ``` public class MyWebSocketHandler implements WebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // WebSocket 连接建立时执行的操作 } @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { // 处理收到的 WebSocket 消息 } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { // 处理 WebSocket 消息传输过程中出现的异常 } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { // WebSocket 连接关闭时执行的操作 } @Override public boolean supportsPartialMessages() { return false; } } ``` 3. 配置 Spring MVC WebSocket 拦截器:创建一个类,实现 `HandshakeInterceptor` 接口。该拦截器可在 WebSocket 握手阶段执行特定的操作,例如在 WebSocket 握手时将用户信息添加到 session 中。 ``` public class MyWebSocketInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { // 在 WebSocket 握手之前执行的操作 return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, @Nullable Exception exception) { // 当 WebSocket 握手成功时执行的操作 } } ``` 4. 配置 Spring MVC WebSocket:在 Spring MVC 配置文件中配置 WebSocket 服务。可以使用 `WebSocketHandlerRegistry` 注册 WebSocket 消息处理器,也可以使用 `HandshakeInterceptorRegistry` 注册 WebSocket 拦截器。 ``` @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Autowired private MyWebSocketHandler myWebSocketHandler; @Autowired private MyWebSocketInterceptor myWebSocketInterceptor; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myWebSocketHandler, "/myWebSocket") .addInterceptors(myWebSocketInterceptor) .setAllowedOrigins("*"); } } ``` 5. 创建 WebSocket 客户端:在客户端中可以使用 JavaScript 代码调用 WebSocket 服务。使用 `var ws = new WebSocket("ws://localhost:8080/myWebSocket");` 创建 WebSocket 连接,然后可以监听 `ws.onopen`、`ws.onerror`、`ws.onmessage` 和 `ws.onclose` 等事件,并在这些事件发生时执行相应的操作。 总结来说,Spring MVC 整合 WebSocket 的步骤包括配置 Maven 依赖、配置 WebSocket 消息处理器、配置 WebSocket 拦截器、配置 Spring MVC WebSocket 和创建 WebSocket 客户端等。使用 Spring MVC 整合 WebSocket 可以使得在 Web 应用中实现实时通信变得更加简单和方便。 ### 回答3: Spring MVC 是一个基于 MVC(Model-View-Controller) 模式的 WEB 应用程序开发框架,而 WebSocket 是 HTML5 提出的基于 TCP 协议的全双工通讯技术,它可以让浏览器与服务器进行实时的双向数据传输。为了实现 Websocket 和 Spring MVC 的整合,我们需要通过以下步骤: 1. 添加 Spring WebSocket 依赖 首先在 Maven 或 Gradle 项目的 `pom.xml` 或 `build.gradle` 文件中添加 Spring WebSocket 的依赖,如果是手动添加 jar 包,则需要添加 `spring-websocket.jar` 和 `javax-websocket-client-api.jar` ,并且需要确保其版本和 Spring 的版本匹配。 2. 配置 WebSocket 处理器 接下来我们需要为 WebSocket 客户端和服务端分别配置其处理器。 在服务端,我们需要创建一个类来处理 WebSocket 连接请求,该类需要继承 `WebSocketHandler` 接口并实现其中的 `handleMessage`、`handleTransportError` 和 `afterConnectionClosed` 方法。 然后将这个类注册到 `WebSocketHandlerRegistry` 中,代码如下: ``` @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new MyWebSocketHandler(), "/myHandler").setAllowedOrigins("*"); } } public class MyWebSocketHandler extends TextWebSocketHandler { @Override public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException { // 处理收到的消息 } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { // 处理传输错误 } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { // 处理关闭连接事件 } } ``` 在上述代码中,我们创建了一个 `WebSocketConfig` 配置类,并使用 `@EnableWebSocket` 注解开启 WebSocket 支持。 然后在 `registerWebSocketHandlers` 方法中,我们注册了一个 `MyWebSocketHandler` 处理器,并为其指定了路径 `"/myHandler"`。需要注意的是,我们使用 `setAllowedOrigins("*")` 方法指定了跨域访问的规则。 3. 在客户端发起连接 客户端连接 WebSocket 时需要通过标准的 WebSocket API 建立连接。这里我们以 JavaScript 代码为例: ``` var ws = new WebSocket("ws://localhost:8080/myHandler"); ws.onopen = function() { console.log("连接成功"); }; ws.onmessage = function(event) { console.log("收到消息:" + event.data); } ws.onclose = function() { console.log("连接关闭"); } ``` 在上述代码中,我们首先创建了一个 WebSocket 对象,并指定连接的 URL 为 `ws://localhost:8080/myHandler`。然后通过 `onopen`、`onmessage` 和 `onclose` 等事件监听器来处理连接成功、接收消息和连接关闭事件。 通过以上步骤,我们就完成了 WebSocket 和 Spring MVC 的整合。在实际的应用中,我们可以根据自己的需要来进一步扩展和优化代码,以达到更好的性能和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liuyunshengsir

微信:lys20191020

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值