StompClientLib - 取消订阅 socketclient

StompClientLib - unsubscribe socketclient

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

Unsubscription of destination gives following error: "org.apache.activemq.transport.stomp.ProtocolException: No subscription matched.\r\tat org.apache.activemq.transport.stomp.ProtocolConverter.onStompUnsubscribe(ProtocolConverter.java:734)\r\tat org.apache.activemq.transport.stomp.ProtocolConverter.onStompCommand(ProtocolConverter.java:262)\r\tat org.apache.activemq.transport.ws.AbstractStompSocket.processStompFrame(AbstractStompSocket.java:151)\r\tat org.apache.activemq.transport.ws.jetty9.StompSocket.onWebSocketText(StompSocket.java:96)\r\tat org.eclipse.jetty.websocket.common.events.JettyListenerEventDriver.onTextMessage(JettyListenerEventDriver.java:128)\r\tat 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\tat org.eclipse.jetty.websocket.common.events.JettyListenerEventDriver.onTextFrame(JettyListenerEventDriver.java:122)\r\tat org.eclipse.jetty.websocket.common.events.AbstractEventDriver.incomingFrame(AbstractEventDriver.java:160)\r\tat org.eclipse.jetty.websocket.common.WebSocketSession.incomingFrame(WebSocketSession.java:309)\r\tat org.eclipse.jetty.websocket.common.extensions.ExtensionStack.incomingFrame(ExtensionStack.java:214)\r\tat org.eclipse.jetty.websocket.common.Parser.notifyFrame(Parser.java:220)\r\tat org.eclipse.jetty.websocket.common.Parser.parse(Parser.java:258)\r\tat org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.readParse(AbstractWebSocketConnection.java:628)\r\tat org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:476)\r\tat org.eclipse.jetty.io.AbstractConnection.run(AbstractConnection.java:540)\r\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)\r\tat org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:555)\r\tat java.lang.Thread.run(Unknown Source)\r")

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

例如:

```
// 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 分析的那样,订阅(一种订阅方法)returns 来自服务器的字符串(订阅频道 ID),我们需要将其存储在客户端的某处(在我们的 project/code) 我们需要使用相同的字符串来取消订阅。

这是 javcScript(不是 iOS - swift)代码,是此 link (Subscribe and receive messages) 中可用的示例,我们在网络应用程序:

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

The subscribe() methods return a JavaScript object with 1 attribute, id, that correspond to the client subscription ID and one method unsubscribe() that can be used later on to unsubscribe the client from this destination.

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

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

中获得任何值(目标订阅 ID)

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

请帮忙找出解决这个问题的方法。

这里是关于这个问题的参考 link:unsubscribe socketclient #14

此 StompClientLib 库中的订阅功能未 return 发送服务器将生成的订阅 ID 并 return 给客户端。您可以在此处查看代码:

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

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

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)

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

订阅使用唯一目的地 (id) 作为目的地与服务器连接,但通过引用订阅 ID 链接并记住它,并在取消订阅时使用订阅 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)