栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【WebSocket】基于 stomp协议的WebSocket,Springboot中实现订阅主题的WebSocket

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【WebSocket】基于 stomp协议的WebSocket,Springboot中实现订阅主题的WebSocket

1.使用场景

我们在与前端即时推送一些消息的时候,基本都是靠WebSocket实现的,而当前端的项目中需要建立多个WebSocket或者给特定的用户发送不同的消息时,传统的实现方式,我们在WebSocket中会传一些特定的参数当做标识,而今天我们所说的这种基于stomp协议的WebSocket,可以支持客户端订阅不同的主题,我们只要向不同的主题发送信息就行了。

2.SpringBoot中的实现 2.1 Maven依赖

    org.springframework.boot
    spring-boot-starter-websocket
    2.1.1.RELEASE
2.2 配置基于stomp协议的WebSocket
@Configuration
//注解开启使用STOMP协议来传输基于代理(message broker)的消息,这时控制器支持使用@MessageMapping,就像使用@RequestMapping一样
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer
{

    //某些特定业务中,可能要对WebSocket传入的值做一些操作,或者在刚刚建立连接的时候做一些操作,
    //这里支持我们配置自定义的拦截器,去做拦截的操作。
    @Autowired
    private ConnWebSocketInterceptor connWebSocketInterceptor;

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //注册一个STOMP的endpoint,并指定使用SockJS协议
        registry.addEndpoint("/endpoint").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //客户端发送消息的请求前缀
        registry.setApplicationDestinationPrefixes("/app");
        //客户端订阅消息的请求前缀,topic一般用于广播推送,queue用于点对点推送
        registry.enableSimpleBroker("/topic", "/queue");
        //服务端通知客户端的前缀,可以不设置,默认为user
        registry.setUserDestinationPrefix("/user");
    }

    // 注册拦截器
    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(connWebSocketInterceptor);
    }
}
2.3(视业务而定)配置WebSocket拦截器
@Component
public class ConnWebSocketInterceptor implements ChannelInterceptor {

    // 这里使用的是消息模板,注意,这里的消息模板需要等上面的配置类配置结束之后才能使用
    // 但是上面的配置类同样需要我们拦截器的Bean,如何这里不加@Lazy注解,会导致上面的配置类配置失败。
    @Lazy
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    // 这里实现的是在客户端与服务端建立连接之后,直接发送一条信息给客户端
    @Override
    public void afterSendCompletion(Message message, MessageChannel channel, boolean sent, Exception ex) {
         messagingTemplate.convertAndSend("/topic/mytopic","Hello Client!");
    }
}
2.4 通过握手拦截器校验安全
public class HandleShakeInterceptors implements HandshakeInterceptor {

    
    
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Map attributes) throws Exception {
        //这里写业务代码,判断连接的用户名密码,或者有无Token等,判断让不让连接,不让连接返回false
        return true;
    }

    
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                               WebSocketHandler wsHandler, Exception exception) {

    }
    
}
2.5 服务端配置接收消息的方法
@Controller
public class TestController
{

    // 消息发送模板
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    // 接收后缀为/test的消息,可以是/app/test
    //@SendTo  发送给/topic/test的主题
    @MessageMapping("/test")
    @SendTo("/topic/test")
    public void test(String str){
        messagingTemplate.convertAndSend("receive:" + str);
    }

    //点对点式的发送消息
    public void P2P(){
        User user=new User();
	    user.setUserId(1);
        messagingTemplate.convertAndSendToUser(user.getUserId,"/queue/p2p","Hello" + user.getUserId);
    } 
}
3.前端实现

这里只写JS中的方法实现


订阅主题 

var stompClient = null;


// 订阅主题
function connect() {
    var socket = new SockJS('http://192.168.1.42:8080/endpoint');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/test', function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

// 订阅点对点
function connect() {
    var userId = 1;
    var socket = new SockJS('http://192.168.1.42:8080/endpoint');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/user/' + userId + '/queue/getResponse', function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}


//断开连接
function disconnect() {
    if (stompClient !== null) {
        stompClient.disconnect();
    }
}

function showGreeting(message) {
    $("#greetings").append("" + message + "");
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/756569.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号