【问题标题】:How Do I Send a Dictionary to a Client using Vapor Websockets如何使用 Vapor Websockets 向客户端发送字典
【发布时间】:2021-05-05 08:38:27
【问题描述】:

我有continued this question here,因为焦点已经改变,但是是相关的。

Vapor 正在服务器和 iOS 客户端之间进行通信。只需设置代码,用于学习目的。

现在,我想使用 JSON 通过已建立的连接发送值字典。我陷入了演示代码无法解释的逻辑中,但这就是我的位置,在我的蒸汽路线中:

    app.webSocket("respond") { req, ws in
        ws.onText { ws, text in
            print(text)
        
            let msgDict = "{'name' = 'bobby'}"
            let encoder = JSONEncoder()
            let data = try encoder.encode(msgDict)
                
            ws.send(data)
        }
    }

这不会编译: Invalid conversion from throwing function of type '(WebSocket, String) throws -> ()' to non-throwing function type '(WebSocket, String) -> ()'

虽然我通常理解这个错误,但取决于我如何处理它,它会有所不同。

我通常寻找的是一种简单的模式来获取内部字典值,将它们编码为 JSON,然后发送它们。我做错了什么,或者做得不对?

【问题讨论】:

    标签: json swift websocket vapor


    【解决方案1】:

    我发现该代码存在两个问题。

    第一个,由编译错误解释,它实际上告诉它不会处理任何抛出的错误。当您执行encoder.encode(msgDict) 时,此代码可能会引发Error,并且您不会在任何地方处理此可能的错误。如果您处理该可能的错误,您在该闭包中编写的代码将具有预期的类型。您有几种选择:

    • 将代码包裹在 do-catch 块周围
    do {
        let data = try encoder.encode(msgDict)
        ws.send(data)
    } catch let error {
        // Handle error
    }
    
    • 使用try?,表示如果发生错误,您不处理错误,但会得到nil
    if let data = try? encoder.encode(msgDict) {
        ws.send(data)
    }
    
    • 使用try!,意味着你强制解包结果(不建议,但你可以尝试,如果你100%确定的话)
    let data = try! encoder.encode(msgDict)
    ws.send(data)
    

    第二个问题是您如何编写响应 - "{'name' = 'bobby'}"。这是一个无效的 JSON,您应该使用双引号:

    let msgDict = "{\"name\" = \"bobby\"}"
    

    你也可以使用Dictionary,只要内容是Encodable类型:

    let msgDict = ["name": "bobby"]
    

    您还可以使用JSONEncoder 对符合Encodable 的类的任何实例进行编码。

    所以整件事,我会这样写:

    app.webSocket("respond") { req, ws in
        ws.onText { ws, text in
            print(text)
        
            let msgDict = ["name": "bobby"]
            let encoder = JSONEncoder()
            do {
                let data = try encoder.encode(msgDict)
                ws.send(data)
            }
            catch let error {
                print("An error occurred: \(error)")
            }
        }
    }
    

    【讨论】:

    • 很好——谢谢。尽管它抱怨错误本身,但错误已被清除。我现在遇到的是一个非常特定于 Vapor 的错误,即我没有处理 ws.send() 中的未来/承诺结构。我想我知道在哪里可以解决这个问题......
    • @DanDonaldson 我更新了我的答案,我在发现错误时写错了一些东西,我更正了它。
    • @DanDonaldson 如果这解决了您最初的问题,如果您将其标记为答案,我将不胜感激。
    • 确定@Jobert。我不确定你住在哪里,但我在东南亚。你的答案是在我工作日结束时收到的,现在我开始一个新的。试着记住这个世界比你的后院大:) 我已经标记了它,但我认为它没有被完全证明。在我回到这个问题之前,我必须先解决其他问题。
    • @DanDonaldson 我只是觉得我参与其中并为此付出了一些努力并需要一些反馈(有时你在这里没有得到它,这非常令人沮丧)。感谢您的回复,祝您工作顺利! :)
    【解决方案2】:

    错误告诉您缺少do - catch

    do {
        let encoder = JSONEncoder()
        let data = try encoder.encode(msgDict)
        ws.send(data)
    } catch { print(error) }
    

    但是,您创建 JSON 的方法不起作用,因为 msgDict 既不是有效的 JSON 也不是 Swift 字典。

    要使用JSONEncoder 对字典进行编码,它必须是 Swift 字典

    let msgDict = ["name":"bobby"]
    

    但是JSONEncoder 太过分了。更简单的方法是逐字创建 JSON 字典

    app.webSocket("respond") { req, ws in
        ws.onText { ws, text in
            print(text)
        
            let msgDict = #"{"name":"bobby"}"#
            ws.send(Data(msgDict.utf8))
        }
    }
    
                
            
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-03
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      • 1970-01-01
      • 2022-07-01
      相关资源
      最近更新 更多