我是靠谱客的博主 平淡鸭子,最近开发中收集的这篇文章主要介绍基于STOMP协议的WebSocket,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 

使用spring websocket 有两种方式:

 

1.SpringFramework提供了一个WebSocketAPI,您可以使用它来编写处理WebSocket消息的客户端和服务器端应用程序。

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myHandler");
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }

}
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.TextMessage;

public class MyHandler extends TextWebSocketHandler {

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        // ...
    }

}

 

 

 

2.Enable STOMP

import java.security.Principal;
import java.util.Map;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

/**
 * @author lyy
 */

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
	
    
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/stomp-endpoint").setHandshakeHandler(new  DefaultHandshakeHandler() {
			 @Override
             protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
				 String name= ((ServletServerHttpRequest) request).getServletRequest().getParameter("username");
				 return new MyPrincipal(name);
			 }

        })
        .withSockJS();  
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
    	//当客户端发送消息或订阅消息时,url路径开头如果是/app/xxx 时,会先解析stomp协议,然后路由到@controller的@MessageMapping("/xxx")的方法上执行。
    	//如果不设置,客户端所有发送消息或订阅消息时、都将去匹配@messageMapping。所以最好还是配置上。
        config.setApplicationDestinationPrefixes("/app"); 
        
        //声明消息中间件Broker的主题名称,当向这个主题下发送消息时(js: stompclient.send("/topic/target1",{},"hello" )  ),订阅当前主题的客户端都可以收到消息。
        //注意:js 客户端如果发送时、直接是/topic/xxx,spring收到消息会直接发送给broker中。
        //  点对点发送时:enableSimpleBroker 中要配置 /user才可能用: template.convertAndSendToUser("zhangsan","/aaa/hello","111"),否则收不到消息。
        config.enableSimpleBroker("/topic","/user"); 
        
        //点对点发送前缀
        config.setUserDestinationPrefix("/user");
    }
    
    class MyPrincipal implements Principal{
    	 
        private String key;
 
        public MyPrincipal(String key) {
            this.key = key;
        }
 
        @Override
        public String getName() {
            return key;
        }
 
    }

对以上代码最好的解析就是官方的图:

 

 

java推送消息方式

/**
 * @author lyy
 */
@Controller
@EnableScheduling
public class PayTestController {


  	@Autowired
    public SimpMessagingTemplate template;  
  
  	//这个注解其实就是用来定义接受客户端发送消息的url(不能是topic开头,如果是topic直接发送给broker了,要用/app/hello)
  	//如果有返回只则会将返回的内容转换成stomp协议格式发送给broker(主题名:/topic/hello)。如果要换主题名可使用@sentTo
  	//@SubscribeMapping注解和@messageMapping差不多,但不会再把内容发给broker,而是直接将内容响应给客户端,
    @MessageMapping("/hello")  
    public void greeting(String content) throws Exception { 
    	System.out.println("收到内容: "+content );
    }
    

    //广播推送消息
    @Scheduled(fixedRate = 10000)
    public void sendTopicMessage() {
	System.out.println("后台广播推送!");
    this.template.convertAndSend("/topic/hello","test");
    }
    
    
    //点对点
    @Scheduled(fixedRate = 10000)
    public void sendQueueMessage() {
	System.out.println("后台一对一推送!");
	this.template.convertAndSendToUser("zhangsan","/aaa/hello","111");
    }

}

 

一共就两种,注解或SimpMessagingTemplate 。

注意:js是可以直接填写主题路径来发送消息给订阅者的。所以最好有认证限制。省得客户端乱推送消息

后台推送流程:template.convertAndSend("xxx")将消息转换成stomp格式、然后发送到broker中,broker利用websocket链接发送消息给所以的订阅者。

 

js推送流程: stompClient.send("/topic/hello",{},"222") 利用websocket链接、将stomp格式的消息发送给Spring 的clientInboundChannel,Spring转发到broker中(brokerChannel),broker利用websocket链接发送消息给所以的订阅者。

 

 

pom

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

 

建议使用第二种,好处:

1.更加简单,灵活。

2.不用自己管理websocket  session

3.可以很方便的集成  消息代理(如RabbitMQ、ActiveMQ和其他)来管理订阅和广播消息。提高效率

4.利用stomp消息协议、规范传输的消息格式。客户端和服务器端的交互,只是利用websocket 的链接。

5.可以利用推送消息来保持sesssion。要集成spring session(原理就是推送消息时刷新session的最后更新时间)

https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-websocket.html

6,支持topic订阅模式,和点对点发送消息。

 

 

js客户端:

 

<script type="text/javascript">

//建立连接对象(还未发起连接)
var socket=new SockJS("/platform/stomp-endpoint?username=aaaa"); 
// 获取 STOMP 子协议的客户端对象 
var stompClient = Stomp.over(socket); 
// 向服务器发起websocket连接并发送CONNECT帧 
stompClient.connect( {}, 
	function connectCallback (frame) { 
	// 连接成功时(服务器响应 CONNECTED 帧)的回调方法 
	console.log('已连接【' + frame + '】'); 
	//订阅一个消息
	stompClient.subscribe('/user/zhangsan/aaa/hello',
	function (response) { 
		console.log("zhangsan: "+response.body);
	});
	},
		function errorCallBack (error) { 
		// 连接失败时(服务器响应 ERROR 帧)的回调方法 
	console.log('连接失败【' + error + '】'); 
});

//发送消息
 function send(){
	 //可以理解成直接让应用将推送消息转发到broker中。
	 //stompClient.send("/user/zhangsan/aaa/hello",{},"222") 
	 
	 //先进@messageMapping的controller方法,再决定消息的去向
	 stompClient.send("/app/hello",{},"222")
	 
 }

 //这里10妙后才调用发送,如果立马调用发送一般会失败。因为链接状态还没完成。
setTimeout(send,10000)



</script>

 

最后

以上就是平淡鸭子为你收集整理的基于STOMP协议的WebSocket的全部内容,希望文章能够帮你解决基于STOMP协议的WebSocket所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部