spring websocket + stomp 实现广播通信和一对一通信

转载 2016年08月31日 11:57:26

spring对于基于stomp协议的websocket通信,其官网上面有一个guide,但是根据guide你只能写出来广播方式的通信,不能实现一对一的通信,这篇文章在这里把广播和一对一一起整理一下给大家。

服务端:

一,依赖,spring-websocket和spring-messaging,这里给出maven方式:

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

二,服务端代码:

服务端的初始化,只需要两个类:WebsocketConfig和WebSocketController

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

	@Override
	public void configureMessageBroker(MessageBrokerRegistry config) {
		config.enableSimpleBroker("/topic","/user");
		config.setApplicationDestinationPrefixes("/app");
        config.setUserDestinationPrefix("/user/");
	}

	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/webServer").withSockJS();
	}

}

这个类表示启用websocket消息处理,以及收发消息的域

config.enableSimpleBroker("/topic","/user");这句表示在topic和user这两个域上可以向客户端发消息;config.setUserDestinationPrefix("/user/");这句表示给指定用户发送(一对一)的主题前缀是“/user/”;  config.setApplicationDestinationPrefixes("/app"); 这句表示客户端向服务端发送时的主题上面需要加"/app"作为前缀;registry.addEndpoint("/webServer").withSockJS();这个和客户端创建连接时的url有关,后面在客户端的代码中可以看到。


下面是一个spring风格的controller,用于接收客户端的消息及响应客户端:

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.stereotype.Controller;

@Controller
public class WebSocketController {

    public SimpMessagingTemplate template;

    @Autowired
    public WebSocketController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @MessageMapping("/hello")
    @SendTo("/topic/hello")
    public Greeting greeting(Greeting message) throws Exception {
        return message;
    }

    @MessageMapping("/message")
    @SendToUser("/message")
    public UserMessage userMessage(UserMessage userMessage) throws Exception {
        return userMessage;
    }

}
这个类里面织入SimpMessagingTemplate对象,后面动态发送消息时,需要用到这个对象。

第一个方法,表示服务端可以接收客户端通过主题“/app/hello”发送过来的消息,客户端需要在主题"/topic/hello"上监听并接收服务端发回的消息

第二个方法道理相同,只是注意这里用的是@SendToUser,这就是发送给单一客户端的标志。本例中,客户端接收一对一消息的主题应该是“/user/” + 用户Id + “/message” ,这里的用户id可以是一个普通的字符串,只要每个用户端都使用自己的id并且服务端知道每个用户的id就行。

这里的Greeting和UserMessage是一个普通的实现了序列化的java bean

就这样,那么,在程序中的其他地方要动态发送消息,就是下面这两句代码:

webSocketController.template.convertAndSend("/topic/hello",greeting) //广播
webSocketController.template.convertAndSendToUser(userId, "/message",userMessage) //一对一发送,发送特定的客户端


客户端:

js客户端需要导入两个js组件:sockjs-0.3.4.js,stomp.js

var url = 'http://localhost:8080/appRoot/webServer'
var socket = new SockJS(url, undefined, {protocols_whitelist: ['websocket']});
var stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
	stompClient.subscribe('/topic/hello', function(message){
		var json = JSON.parse(message.body);
	});

	 stompClient.subscribe('/user/' + userId + '/message', function(message){
		 var messageEntity = JSON.parse(message.body);
	});
});

第一个subscribe,是接收广播消息,第二个是接收一对一消息,其主题是'/user/' + userId+ '/message' , 不同客户端具有不同的userId

看到这里,你会发现,这里所谓的一对一,只是业务层面的一对一,也就是,需要不同客户端具有不同的userId才能实现,如果两个客户端使用相同的userid, 那么服务端给这个userId发送消息时,这两个客户端都会收到。要真正实现websocket技术层面的一对一发送,那就要使用websocket的session了。关于session方式,我这里上传一个demo,有兴趣可以下载:http://download.csdn.net/detail/valenon/8725195

spring websocket + stomp 实现广播通信和一对一通信

spring对于基于stomp协议的websocket通信,其官网上面有一个guide,但是根据guide你只能写出来广播方式的通信,不能实现一对一的通信,这篇文章在这里把广播和一对一一起整理一下给大...
  • valenon
  • valenon
  • 2015年05月21日 16:33
  • 3755

Spring+STOMP实现WebSocket广播订阅、权限认证、一对一通讯(附源码)

当使用 Spring 实现 STOMP 时,Spring WebSocket 应用程序充当客户端的 STOMP 代理。消息被路由到 @Controller 消息处理方法,或路由到一个简单的内存代理,经...

Spring WebSocket+SockJS+Stomp实现一对一、一对多通信

最近项目上要做扫码登录,所以研究了一下Spring WebSocket。网上找了很多资料 springmvc(18)使用WebSocket 和 STOMP 实现消息功能、spring websock...

spring+stomp+webSocket+SockJS 实现简单的订阅广播消息和订阅个人消息

个人第一篇CSDN的博客,记录自己的IT成长过程。

spring中使用stomp协议进行长连接通信

在项目当中需要和前端进行长连接,将一些实时信息给到前端。前端提出用一些比较现成的协议框架,对一些异常情况的处理要好于基础的websocket。然后就用了stomp进行长连接。...

使用spring websocket 和stomp实现消息功能

实现一个消息驱动pojo public class MarcHandler extends AbstractWebSocketHandler{ private Logger LOGGER = ...

Spring项目中使用webservice实现h5的websocket通信

一、在项目中建立一个webservice来做后台操作。 package org.calonlan.soulpower.websocket; import java.text.SimpleDateF...

web即时通信2--基于Spring websocket实现web聊天室

转自:http://blog.csdn.net/jrn1012/article/details/42079821    文中代码部分参考了Spring WebSocket教程(一)和Spring...

Spring+Websocket实现服务器与Andoird端通信

本博客服务器端内容参考于博客:http://www.cnblogs.com/3dianpomian/p/5902084.html。 写这篇博客的原因是在网上查阅了很多资料,关于websocket的介...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:spring websocket + stomp 实现广播通信和一对一通信
举报原因:
原因补充:

(最多只允许输入30个字)