Spring Boot使用EventSource和观察者模式实现服务端推送

5 篇文章 1 订阅
3 篇文章 0 订阅

服务端:

Controller:

package com.example.demo;

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import com.example.demo.service.MsgService;


@Controller
@RequestMapping("/")
public class MsgControl {
	
	@Resource(name="msgService")
	private MsgService msgService;
	
	@ResponseBody
	@RequestMapping(value = "/getMsg", produces="text/event-stream;charset=UTF-8")
	DeferredResult<String> getMsg(HttpServletResponse response) throws IOException {
		response.setContentType("text/event-stream");
    	response.setCharacterEncoding("UTF-8");
    	response.setStatus(200);
    	msgService.removeErrorResponse();
    	msgService.getListRes().add(response);
    	if(!response.getWriter().checkError()){
    		response.getWriter().write("data:hello\n\n");
    		response.getWriter().flush();
    	}
    	DeferredResult<String> df = new DeferredResult<String>(60000l);
    	return df;
    }
}

Service:

package com.example.demo.service;

import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Vector;
import java.util.Random;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Lazy(value = false)
@EnableScheduling
@Service(value="msgService")
public class MsgService {
	
	final Vector<HttpServletResponse> list_res= new Vector<HttpServletResponse>();
	
	public Vector<HttpServletResponse> getListRes()
	{
		return list_res;
	}
	
	@Scheduled(initialDelay = 0, fixedDelay = 3*1000)
	public void run() {
		this.removeErrorResponse();
		Iterator<HttpServletResponse> it = list_res.iterator();
		Random rand =new Random();
		int num=rand.nextInt(100);
		while(it.hasNext())
		{
			PrintWriter pw = null;
			try {
				pw = it.next().getWriter();
				if(pw == null || pw.checkError())
				{				
					continue;
				}
	    		pw.write("data:msg: hello, the random num is: " + num + "\n\n");
	    		pw.flush();
			} catch (Exception e) {
				
			} 
		}
	}
	
	public synchronized void removeErrorResponse(){
		Iterator<HttpServletResponse> it = list_res.iterator();
		while(it.hasNext())
		{
			PrintWriter pw = null;
			try {
				pw = it.next().getWriter();
				if(pw == null)
				{
					it.remove();
					continue;
				}
				else if(pw.checkError()){
					pw.close();
					it.remove();
					continue;
				}
			} catch (Exception e) {				
				it.remove();
			} 	
		}
	}
}

前端代码:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>信息</title>
</head>
<body>
	<div id='msg'>
</div>
<script>
	if (typeof(EventSource) !== "undefined") {
		var eventSource = new EventSource("/getMsg");
		
		eventSource.onmessage = function (event) {
			document.getElementById("msg").innerHTML = event.data;
			  
		}	        
		eventSource.addEventListener('error', function (event) {
			console.log("错误:" + event);
		});
		eventSource.addEventListener('open', function (event) {
			console.log("建立连接:" + event);
		});
	}
	else {
		document.getElementById("msg").innerHTML = "抱歉,您的浏览器不支持 server-sent 事件 ...";
	}   
</script>
</body>
</html>

运行结果:

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot可以通过WebSocket实现信息推送。WebSocket是一种在单个TCP连接上进行全双工通信的协议,可以实现实时通信。在Spring Boot中,可以使用Spring WebSocket模块来实现WebSocket功能。具体实现步骤如下: 1. 添加Spring WebSocket依赖 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建WebSocket配置类 创建一个WebSocket配置类,用于配置WebSocket相关的参数和处理器。可以继承`AbstractWebSocketMessageBrokerConfigurer`类,重写其中的方法。 ``` @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/websocket").withSockJS(); } } ``` 上述代码中,`configureMessageBroker`方法用于配置消息代理,`registerStompEndpoints`方法用于注册WebSocket端点。 3. 创建WebSocket处理器 创建一个WebSocket处理器,用于处理WebSocket连接、消息发送和接收等操作。可以继承`TextWebSocketHandler`类,重写其中的方法。 ``` @Component public class WebSocketHandler extends TextWebSocketHandler { private final SimpMessagingTemplate messagingTemplate; @Autowired public WebSocketHandler(SimpMessagingTemplate messagingTemplate) { this.messagingTemplate = messagingTemplate; } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 连接建立时触发 } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理文本消息 messagingTemplate.convertAndSend("/topic/messages", message.getPayload()); } } ``` 上述代码中,`afterConnectionEstablished`方法用于处理连接建立事件,`handleTextMessage`方法用于处理文本消息。 4. 发送消息 在需要发送消息的地方,可以使用`SimpMessagingTemplate`类的`convertAndSend`方法发送消息。 ``` @Autowired private SimpMessagingTemplate messagingTemplate; public void sendMessage(String message) { messagingTemplate.convertAndSend("/topic/messages", message); } ``` 上述代码中,`/topic/messages`是消息的目的地,可以根据实际情况修改。 5. 接收消息 在需要接收消息的地方,可以使用`@MessageMapping`注解和`@SendTo`注解处理消息。 ``` @MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { return new Greeting("Hello, " + message.getName() + "!"); } ``` 上述代码中,`/hello`是消息的目的地,`/topic/greetings`是消息的返回目的地,可以根据实际情况修改。 通过以上步骤,就可以在Spring Boot实现WebSocket信息推送
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值