StompClientLib - 取消订阅socketclient

时间:2018-01-27 04:03:17

标签: ios swift activemq swift4 stomp

我在项目中添加了StompClientLib,在取消订阅目标主题时我遇到了问题。

  

取消订阅目的地会产生以下错误:   " org.apache.activemq.transport.stomp.ProtocolException:没有匹配的订阅。\ r \ ttt org.apache.activemq.transport.stomp.ProtocolConverter.onStompUnsubscribe(ProtocolConverter.java:734)\ r \ ttot org。 apache.activemq.transport.stomp.ProtocolConverter.onStompCommand(ProtocolConverter.java:262)[r \ tat org.apache.activemq.transport.ws.AbstractStompSocket.processStompFrame(AbstractStompSocket.java:151)\ r \ tt org.apache。 activemq.transport.ws.jetty9.StompSocket.onWebSocketText(StompSocket.java:96)\ r \ ttr org.eclipse.jetty.websocket.common.events.JettyListenerEventDriver.onTextMessage(PettyListenerEventDriver.java:128) \ r \ ttot org。 eclipse.jetty.websocket.common.message.SimpleTextMessage.messageComplete(SimpleTextMessage.java:69)\ r \ tat org.eclipse.jetty.websocket.common.events.AbstractEventDriver.appendMessage(AbstractEventDriver.java:64)\ r \ ntat org.eclipse.jetty.websocket.common.events.JettyListenerEventDriver.onTextFrame(JettyListenerEventDriver.java:122)\ r \ ttr org.eclipse.jetty.websocket.common .events.AbstractEventDriver.incomingFrame(AbstractEventDriver.java:160)\ r \ ttr org.eclipse.jetty.websocket.common.WebSocketSession.incomingFrame(WebSocketSession.java:309)\ r \ ttot org.eclipse.jetty.websocket.common .extensions.ExtensionStack.incomingFrame(ExtensionStack.java:214)\ r \ tt org.eclipse.jetty.websocket.common.Parser.notifyFrame(Parser.java:220)\ r \ tt org.eclipse.jetty.websocket.common .Parser.parse(Parser.java:258)\ r \ tt org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.readParse(AbstractWebSocketConnection.java:628) \ r \ ttr org.eclipse.jetty.websocket.common .io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:476)\ r \ tt org.eclipse.jetty.io.AbstractConnection $ 2.run(AbstractConnection.java:540)\ r \ ttt org.eclipse.jetty.util.thread。 QueuedThreadPool.runJob(QueuedThreadPool.java:635) \ r \ ttr org.eclipse.jetty.util.thread.QueuedThreadPool $ 3.run(QueuedThreadPool.java:555) \ r \ _dat.java.lang.Thread.run(Unknown Source) \ R&#34)

是的,这是订阅名称的问题,但它不接受我用来订阅特定频道的相同字符串字符串。

例如:

```
// destination
let destinationChannelTopic = "/topic/channel_1234"

// subscribe successful
socketClient?.subscribe(destination: destinationChannelTopic)

// unsubscribe not successful with same destination
socketClient?.unsubscribe(destination: destinationChannelTopic)
```

这里取消订阅会回复我一个错误:没有订阅匹配
谁能帮我理解,有什么不对?我做错了什么?

正如我从Subscribe and receive messages分析的那样,订阅(订阅方法)从服务器返回一个字符串(订阅频道ID),我们需要存储在客户端(在我们的项目/代码中)的某个地方,我们需要使用相同的字符串取消订阅。

这是javcScript(不是iOS - swift)代码,此链接中提供的示例(Subscribe and receive messages),我们在Web应用程序中实现了类似的方式:

```
// subscribe
var subscription = client.subscribe("/queue/test", callback);
```
  

subscribe()方法返回一个JavaScript对象,该对象具有1个属性id,对应于客户端订阅ID和一个方法unsubscribe(),可以在以后使用该方法从该目的地取消订阅客户端。

```
// unsubscribe
subscription.unsubscribe();
```

所以,这只是方法/可能的方式,对于订阅和取消订阅。如果是,那么我们没有任何值可以返回subscribe(...)我可以用来取消订阅。我没有从订阅socketClient?.subscribe(destination: destinationChannelTopic)方法

获取任何值(目标订阅ID)

作为此问题的替代解决方案,我将客户端与服务器断开连接并再次重新连接+再次订阅所有其他目标。这不是一个正确的处理方法,但我现在只有这个解决方案。

请帮助找出解决此问题的方法。

以下是有关问题的参考链接:unsubscribe socketclient #14

2 个答案:

答案 0 :(得分:4)

订阅和取消订阅的订阅方法非常不同。

订阅使用唯一目标(id)与服务器作为目标连接,但是引用subscription-id链接并记住它,并使用subscription-id在取消订阅时在服务器上标识自己。

这是代码,您正在寻找。试试吧。

let destination = "/topic/channel_1234"
let ack = "ack_\(destination)" // It can be any unique string
let subsId = "subscription_\(destination)" // It can be any unique string
let header = ["destination": destination, "ack": ack, "id": subsId]

// subscribe
socketClient?.subscribeWithHeader(destination: destination, withHeader: header)

// unsubscribe
socketClient?.unsubscribe(destination: subsId)

答案 1 :(得分:3)

此StompClientLib库中的subscribe func未返回服务器将生成并返回给客户端的订阅ID。你可以在这里看到代码:

https://github.com/WrathChaos/StompClientLib/blob/master/StompClientLib/Classes/StompClientLib.swift#L356

因此,您必须使用库中的其他func指定订阅ID,并提供包含您选择的订阅ID的stomp标头:

public func subscribeWithHeader(destination: String, withHeader header: [String: String])

例如:

var destination = "mytopic"
var ack = StompCommands.ackAuto
var subsId = "12345"
let header = [StompCommands.commandHeaderDestination: destination, StompCommands.commandHeaderAck: ack, StompCommands.commandHeaderDestinationId: subsId]
socketClient?.subscribeWithHeader(destination, header)
...
socketClient?.unsubscribe(subsId)