最近小编接到一项紧急任务:国外同事让让我三天搭建一个基于stomp 协议的websocket服务。这项服务允许用户在切换region的时候订阅后端对应的topic. 看完这篇文章你将了解什么是stomp over websocket,如何订阅topic,如何取消订阅topic以及如何将rxjs 与stomp 融合
- 什么是stomp over websocket
stomp 是一种简单的面相文本的消息传输协议。而websocket是一种长链接
由于小编最近 有点忙,废话不说先上代码。后续补充理论
import SockJS from 'sockjs-client'
import Stomp from 'stompjs'
import { Observable, Subject } from 'rxjs'
export default class AutoConnectWebSocket {
constructor(url, headers) {
this.url = url
this.stompClient = null
this.subscriptions = new Map()
this.headers = !headers ? {} : headers
this._subscribe = this._subscribe.bind(this)
this._output = new Subject()
this.interval = null
this.connected = false
this.websocket = null
}
start() {
let { url, stompClient } = this
if (!url) {
return
}
if (!stompClient || !this.connected) {
this._connectWebsocket(url)
}
return this
}
_connectWebsocket(url) {
let socket = (this.websocket = new SockJS(url)),
stompClient = (this.stompClient = Stomp.over(socket))
stompClient.connect(
this.headers,
() => {
clearInterval(this.interval)
this.connected = true
this.interval = setInterval(() => {
stompClient.send('/app/region', {}, 'socketServer')
}, 6000)
},
error => {
this.close = true
this._output.error.call(this._output, error)
}
)
socket.onclose = () => {
//ubscribe here
}
}
_subscribe = (region, sourceType) => {
if (this.close) {
return this._output
}
return new Observable(subscriber => {
let topic = this._format(region, sourceType)
if (this.subscriptions.has(topic) && !this.close && this.connected) {
let subscribeTopic = this.stompClient.subscribe(topic, data => {
try {
let dataObj = JSON.parse(data.body)
subscriber.next(dataObj)
} catch (e) {
subscriber.error(e)
}
})
this.subscriptions.set(topic, this.subscriptions)
} else {
subscriber.next(this.stompClient.connected)
}
})
}
_unscribe(region) {
//
}
}