Spring WebSocket实现消息订阅

WebSocket是底层协议,传输的都是没有没有定义格式的字符流或者字节流,那么在这个这个协议的基础之上的上层协议主要作用是定义传输的数据格式,方便业务需要,那么STOMP协议正是简单的格式定义,灵活的提供了在网页实现了消息的订阅,下面来看看Spring提供的消息模块实现消息订阅的一个简单例子。

创建项目

创建Spring mvc项目,参见之前的文章:spring-mvc简单配置

在pom.xml中加入websocket相关两个包的引用

		<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>

相应的在spring的配置文件中加上websocket的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">

	 <websocket:message-broker application-destination-prefix="/websocket">
        <websocket:stomp-endpoint path="/wsport" >
            <!-- <websocket:sockjs/> -->
        </websocket:stomp-endpoint>
        <websocket:simple-broker prefix="/topic,/queue" />
    </websocket:message-broker>

</beans>

websocket的配置简单说一下,application-destination-prefix=”/websocket” 这个是配置整个spring websocket服务端controller的访问跟路径即客户端发送消息的路径,这个path=”/wsport”就是服务端提供的订阅根路径了,最后prefix=”/topic,/queue” 是定义可以订阅的主题,订阅根路径加上订阅的主题就是一个完整的路径

这就是所有的配置了,下面看看后台的控制器写法,简单的例子

服务端

@Controller
public class ChatController {

private final SimpMessagingTemplate messagingTemplate;

@Autowired
public ChatController(SimpMessagingTemplate messagingTemplate) {
    this.messagingTemplate = messagingTemplate;
}


    /**
     * 发送消息到某个主题
     */
    @MessageMapping("/sendToTopic")
    public void sendToTopic(HashMap message){
        //发送
        this.messagingTemplate.convertAndSend("/topic/"+message.get("topic"),message.get("msg"));
    }

}

这个控制器的作用就是往某个主题发送消息,客户端传过来主题topic和要发送的消息msg,下面看看客户端的写法

这里客户端自然是使用sockjs , 可以从这里下载https://github.com/sockjs/sockjs-client/tree/master/dist

stomp可以从这里下载https://github.com/jmesnil/stomp-websocket/tree/master/lib , 这个脚本虽然作者不再维护了,但是一般应用也没啥问题。

把上面两个脚本引入到页面上之后,看看如何实现消息订阅和消息的发送

客户端

客户端和服务端握手连接

function connect() {
    stompClient =Stomp.client("ws://localhost:8080/fullstacks/wsport"); //注意这里/fullstacks是启动tomcat的项目名,换上自己的正确路径
    stompClient.connect({}, function(frame) {
        console.log('Connected: ' + frame);

//订阅
        stompClient.subscribe('/topic/greetings', function(greeting){
            console.log(greeting.body);
        });
    });
}

发送消息的方法

function sendToTopic() {
    stompClient.send("/websocket/sendToTopic", null,JSON.stringify({msg: "你好",topic:"greetings"})); //注意这里topic和订阅的地方一定要一致,要不然就收不到消息了啊
}

 

那么客户端就这么多代码,一个简单的订阅消息和发送消息的例子就完成,运行起来,然后发送一下试试看效果:

在调试窗口运行connect()

image

连接成功之后发送消息sendToTopic()

image

 

看看命令行打出来的日志,发送的内容和stomp协议对照一下,一步了然,我们发送的是json格式的数据,那么接收的消息也是一样的,下面接收消息有两行你好,不要紧张,上面是打印消息体的内容,下面那一行是接收到消息俺们自己打印出来的。

Overall

总的来讲,使用spring的东西就是配置配置,然后写一写很简单的代码就能实现很多内容,简单就是美,根据以上的思路完全可以实现属于自己的聊天或者在线会议之类,图片文件传送也是可以的,文件以base64编码传送过去,稍微封装一下就可以了。

当然,这个websocket服务是通用的,客户端是不局限于浏览器了,在移动设备上也是完全可以使用的,后续将会献上这项方面的一些实例。