Spring4+WebSocket+Socket+STOMP+Jetty构建示例

阅读更多

 

Spring 4引入了WebSocket API,浏览器和Web服务器可以根据WebSocket API通过WebSocket协议进行通信。通过这种方式,我们可以创建一个高度交互的UI和在线游戏,需要从服务器快速响应。SockJS在UI上提供类似WebSocket的对象。STOMP客户端用于通过WebSocket协议进行通信。我正在使用tomcat服务器来部署项目。下图为WebSocket通信的图表。

 Spring4+WebSocket+Socket+STOMP+Jetty构建示例_第1张图片

 

WebSocket协议

WebSocket是一种在浏览器和Web服务器之间进行通信的协议。WebSocket通过TCP协议工作。它在浏览器和Web服务器之间打开套接字连接并开始通信,它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。WebSocket可以轻松嵌入子协议,如STOMP。

 

STOMP协议

stomp是一个用于client之间进行异步消息传输的简单文本协议, 全称是Simple Text Oriented Messaging Protocol。STOMP使用连接,发送,订阅,断开等不同的命令进行通信。严格意义上来说STOMP并不是WebSocket的子协议,它是属于消息队列的一种协议,和AMQP/JMS一个层级。

 

SockJS

SockJS是一个java脚本库,为浏览器提供类似websocket的对象。SockJS提供跨浏览器兼容性,并支持STOMP协议与任何消息代理进行通信。SockJS的工作方式是我们需要提供URL来连接消息代理,然后让stomp客户端进行通信。

 

工程示例概览图

Spring4+WebSocket+Socket+STOMP+Jetty构建示例_第2张图片

 

所需的jar


	4.0.0
	
	com.rongdu.framework
	spring-websocket-stomp-demo
	1.0
	war
		
	
		UTF-8
		4.3.18.RELEASE
		9.4.9.v20180320
		2.7.3
	
	
	
		
		
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        
		
            org.springframework
            spring-webmvc
            ${spring.version}
        
		 
		    com.fasterxml.jackson.core
		    jackson-databind
		    ${jackson.version}
		

		
		
		
		
		
            org.eclipse.jetty.websocket
            websocket-api
            ${jettyVersion}
        
        
            org.eclipse.jetty.websocket
            websocket-server
            ${jettyVersion}
        
        
		
		
			javax.websocket
			javax.websocket-api
			1.1
		
		
            org.springframework
            spring-websocket
            ${spring.version}
        
        
            org.springframework
            spring-messaging
            ${spring.version}
        
		
            org.java-websocket
            Java-WebSocket
            1.3.0
        
        				
		
        
        
            org.webjars
            webjars-locator-core
            0.35
        
        
            org.webjars
            sockjs-client
            1.0.2
        
        
            org.webjars
            stomp-websocket
            2.3.3
        
        
            org.webjars
            jquery
            3.1.0
        

		
		
			com.rabbitmq
			amqp-client
			3.5.1
		
		
			org.springframework.amqp
			spring-rabbit
			1.4.5.RELEASE
		
		
		 
		
			org.apache.logging.log4j
			log4j-slf4j-impl
			2.7
		
		
		
			junit
			junit
			4.11
			test
		
	
	
	
		
			
				org.apache.maven.plugins
				maven-compiler-plugin
				3.1
				
					1.8
					1.8
					utf-8
				
			
		
	

 

 

web.xml配置



	
	
		contextConfigLocation
		classpath:/config/spring/*-beans.xml
	

	
	
		characterEncodingFilter
		org.springframework.web.filter.CharacterEncodingFilter
		
			encoding
			UTF-8
		
		
			forceEncoding
			true			
		
	
	
		characterEncodingFilter
		/*
		ASYNC
	

	
		org.springframework.web.context.ContextLoaderListener
		
	
	
		springServlet
		org.springframework.web.servlet.DispatcherServlet
		
			contextConfigLocation
			classpath:/config/web/web-main.xml
		
		1
		true
	
	
		springServlet
		/
	
	
	
		index.html
	
	

 

 

spring的mvc-servlet.xml配置




	
	
    
	
 	
 	
 	
        
            
        
        
    
    
    
    
		 		 
		 
         
	
 	 	
 	
 	
 		
 			
 				
 				
 			
 		
 	
 	 	 	
 	
 	
 		
 	
	
 	
 	
 	      
        
    
 	
 	

 

添加控制器类

package com.huatech.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;

@Controller
public class TopicController {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(TopicController.class);
	
	@Autowired
	private SimpMessagingTemplate template;
	
    /*收到消息后广播推送*/
    @MessageMapping("/boardcast")
    @SendTo("/topic/boardcast")
    public String sendtousers(String s){
    	LOGGER.info(s);
        return "我是广播消息";
    }

    /*收到消息后精准投送到单个用户*/
    @MessageMapping("/precise")
    /*broadcast = false避免把消息推送到同一个帐号不同的session中*/
    @SendToUser(value = "/topic/precise",broadcast = false)
    public String sendtouser(String s){
    	LOGGER.info(s);
        return "我是精准投送消息";
    }


    /*下面2个是不用接收消息动态发送消息的方法*/
    /*Scheduled为定时任务,演示*/
    @Scheduled(fixedDelay = 1500)
    public void boardcast(){
        this.template.convertAndSend("/topic", "来自服务器广播消息");
    }

    @Scheduled(fixedDelay = 1500)
    public void precise(){
        this.template.convertAndSendToUser("abc", "/message","来自服务器精准投送消息");
    }

}

 

index.jsp示例页面

<%@ page language="java" pageEncoding="UTF-8"%>

  
  	
    spring-websocket-stomp
  
  
  

spring-websocket-stomp

 

app.js

var stompClient = null;
var subscription = null;
$(function () {
   var ws = new SockJS("/websocket-address");
    stompClient = Stomp.over(ws);
    stompClient.connect({'client-id': 'my-client'},function () {
    });

    $("#btn-send").click(function () {
        if(subscription != null){subscription.unsubscribe();}
        subscription = stompClient.subscribe("/topic/boardcast", function(){});
        stompClient.send("/app/boardcast",{},"请求广播");
    });
    $("#btn-send2").click(function () {
        if(subscription != null){subscription.unsubscribe();}
        subscription = stompClient.subscribe("/queue/topic/precise", function(){});
        stompClient.send("/app/precise",{},"请求精准投送");
    });
    // 请求动态广播
    $("#btn-send3").click(function () {
        if(subscription != null){subscription.unsubscribe();}
        subscription = stompClient.subscribe("/topic", function(){});
    });
    // 请求精准投送
    $("#btn-send4").click(function () {
        if(subscription != null){subscription.unsubscribe();}
        subscription = stompClient.subscribe("/queue/abc/message", function(){});
    });
});

 

遇到的问题

1、spring引入webjars页面报404问题

参考:https://blog.csdn.net/chao_1990/article/details/53449494

 

2、Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.canSerialize(Ljava/lang/Class;Ljava/util/concurrent/atomic/AtomicReference;)Z

答:jackson版本冲突

 

3、@MessageMapping注解配置后不起作用

答:websocket相关的配置需通过mvc进行初始化,而不是交给IOC

参考:

https://stackoverflow.com/questions/42441837/messagemapping-does-not-work-with-spring-security-and-mvc

  • Spring4+WebSocket+Socket+STOMP+Jetty构建示例_第3张图片
  • 大小: 8.8 KB
  • Spring4+WebSocket+Socket+STOMP+Jetty构建示例_第4张图片
  • 大小: 14.2 KB
  • spring-websocket-stomp-demo.zip (9.1 KB)
  • 下载次数: 0
  • 查看图片附件

你可能感兴趣的:(spring,websocket,stomp)