想象一下,我们有使用websocket的聊天服务。我们正在使用属性request_id
作为JSON发送消息。服务器捕获我们的消息,将其保存到数据库中,并通过将传递的id
发送回客户端另一个数据来返回消息的request_id
。客户必须找出此“响应”与“请求”确切相关,并将数据保存到本地数据库。
例如:
{
"request_id": "1st",
"content": "first message"
}
{
"request_id": "1st",
"message_id": 123242139857814
}
与Alammofire(使用闭包)不同,Starscream lib不提供这种机制。我正在寻找与CoreData和RxSwift兼容的解决方案。如何在不丢失“请求”上下文的情况下处理服务器的“响应”?
答案 0 :(得分:0)
有很多方法。例如,您可以使用下一个代码
class Mapping<T: Hashable, U: Hashable> {
typealias ForwardKey = T
typealias ForwardValue = U
typealias ReverseKey = ForwardValue
typealias ReverseValue = ForwardKey
typealias KeyPair = (ForwardKey, ReverseKey?)
typealias ValuePair = (ForwardValue, ReverseValue)
private var forward: [AnyHashable: AnyHashable]
private var reverse: [AnyHashable: AnyHashable]
private let emptyHashable = AnyHashable("")
init() {
forward = [:]
reverse = [:]
}
func insert(pair: KeyPair) {
if let base = pair.1 {
forward[pair.0] = base
reverse[base] = pair.0
} else {
forward[pair.0] = emptyHashable
}
}
func update(pair: KeyPair) {
insert(pair: pair)
}
subscript(forward key: ForwardKey) -> ForwardValue? {
return forward.first(where: { $0.key.hashValue == key.hashValue })?.value as? ForwardValue
}
subscript(reverse key: ReverseKey) -> ReverseValue? {
if let result = reverse.first(where: { $0.key.hashValue == key.hashValue })?.value as? ReverseValue {
return result
}
return forward.first(where: { $0.key.hashValue == key.hashValue })?.key as? ReverseValue
}
}
struct Request: Hashable {
let requestID: String
let content: String
func hash(into hasher: inout Hasher) {
hasher.combine(requestID)
}
}
struct Response: Hashable {
let requestID: String
let messageID: String
func hash(into hasher: inout Hasher) {
hasher.combine(requestID)
}
}
class WebSocket {
private var callback: ((Request, Response) -> ())?
private let mapping = Mapping<Request, Response>()
func request(_ request: Request, callback: @escaping (Request, Response) -> ()) {
mapping.insert(pair: (request, nil))
self.callback = callback
// Send webSocket message
}
// WebSocketDelegate
// Since you are using Starscream
func websocketDidReceiveMessage(/*socket: WebSocketClient,*/ text: String) {
// Parse text to Response
let response = Response(requestID: "1", messageID: "2")
if let req = mapping[reverse: response] {
mapping.update(pair: (req, response))
callback?(req, response)
}
}
}
let webSocket = WebSocket()
webSocket.request(Request(requestID: "1", content: "A")) { request, response in
print(request) // Request(requestID: "1", content: "A")
print(response) // Response(requestID: "1", messageID: "2")
}
webSocket.websocketDidReceiveMessage(text: "")