消息很大,您可能需要考虑较小的消息。节点 IPC 和 swift (OSX)

Messages are large, You may want to consider smaller messages. node-ipc and swift (OSX)

我有一个节点应用程序正在尝试使用 unix 套接字与 swift 应用程序通信。 我使用以下代码和 node-ipc 每 3 秒广播一次消息:

const ipc = require('node-ipc').default;       

// Run IPC server for testing
const first = "FIRST";
const second = "SECOND";
const ipcSocketPath = `/tmp/${ipcAppId}`;

async function setupCoreCommunicationIpc() {
    await new Promise((resolve) => {
        ipc.serve(ipcSocketPath, () => {
            ipc.server.on('ping', (data, socket) => {
                ipc.server.emit(socket, 'pong');
            });

            return resolve(true);
        });
        ipc.server.start();
    });
}


function sendMessage(message, payload = {}) {
    ipc.server.broadcast(message, { ...payload, "valueOne": first, "valueTwo": seconds });
}


(async () => {
    try {
        await setupCoreCommunicationIpc()
    } catch (e) {
        // Deal with the fact the chain failed
    }
    // `text` is not available here
})();

setInterval(async () => {
    await sendMessage("first:message", {core_id: ipcAppId, app_id: ipcAppId, message_id: 5})
}, 3000);

swift 上的代码有点复杂。但我能够连接到 unix 套接字并接收消息。问题是 AckMessage 的发送。我尝试了不同的方法来发送消息,但它不起作用。这是 swift 中的代码:

func startSocketStack(valueOne: String, valueTwo: String){
    let MTU = 65536
    let path = "/tmp/\(valueTwo)"
    print("starting socket at: %\(path)%")
    
    let client = socket(AF_UNIX, SOCK_STREAM, 0)
    var address = sockaddr_un()
    //address.sun_family = UInt8(AF_UNIX)
    address.sun_family = sa_family_t(AF_UNIX)
    //address.sun_len = UInt8(MemoryLayout<sockaddr_un>.size)
    address.sun_len = UInt8(MemoryLayout<UInt8>.size + MemoryLayout<sa_family_t>.size + path.utf8.count + 1)
    strlcpy(&address.sun_path.0, path, MemoryLayout.size(ofValue: address.sun_path))
    
    var adressUnwrap = address
    withUnsafePointer(to: &adressUnwrap) {
        [=13=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
            let connection = connect(client, [=13=], socklen_t(address.sun_len))
            if (connection != 0) {
                print("startSocket: could not connect to socket at \(path)")
            }
        }
    }
    
    var buffer = UnsafeMutableRawPointer.allocate(byteCount: MTU,alignment: MemoryLayout<CChar>.size)
    while(true) {
        let readResult = read(client, &buffer, MTU)
        if (readResult == 0) {
            break;  // end of file
        } else if (readResult == -1) {
            print("Error reading form client\(client) - \(errno)")
            break;  // error
        } else {
            let strResult = withUnsafePointer(to: &buffer) {
                [=13=].withMemoryRebound(to: CChar.self, capacity: MemoryLayout.size(ofValue: readResult)) {
                    String(cString: [=13=])
                }
            }
            print("Received form client(\(client)): §\(strResult)§")
            print("§\(strResult)§")
            let trimmedString = strResult.components(separatedBy: .whitespacesAndNewlines).joined()
            print("§\(trimmedString)§")

          
            struct Message: Decodable {
                let type: String
                let data: MessageData
                
                struct MessageData: Decodable {
                    var valueOne: String
                    var valueTwo: String
                    var message_id: String
                }
            }
            
            struct AckMessage: Encodable {
                let type: String
                let data: Bool
            }
            
            do {
                let jsonMessage = trimmedString.components(separatedBy: "}")[0] + "}" + "}"
                let jsonData = jsonMessage.trimmingCharacters(in: CharacterSet.newlines).data(using: .utf8)!
                let receivedMessage: Message = try JSONDecoder().decode(Message.self, from: jsonData)
                let messageId = receivedMessage.data.message_id
                let ackMessage = AckMessage(type: messageId, data: true)
                let jsonAckMessage = try JSONEncoder().encode(ackMessage)
                let delimiter = #"\f"#.bytes
                let jsonAckMessageWithDelimiter = jsonAckMessage + delimiter
                print("jsonAckMessageWithDelimiter")
                print(jsonAckMessageWithDelimiter)

                
                
                // first attempt
                do {
                    try jsonAckMessageWithDelimiter.withUnsafeBytes() { [unowned self] (buffer: UnsafeRawBufferPointer) throws -> Int in
                        let buffer = buffer.baseAddress!
                        print(buffer)
                        let bufSize = jsonAckMessageWithDelimiter.count
                        print(bufSize)
                        
                        var sent = 0
                        var sendFlags: Int32 = 0
                        while sent < bufSize {

                            var s = 0
                            s = send(client, buffer.advanced(by: sent), Int(bufSize - sent), sendFlags)
                            if s <= 0 {

                                if errno == EAGAIN{

                                    // We have written out as much as we can...
                                    return sent
                                }
                            }
                            sent += s
                        }
                        return sent
                    }
                } catch {
                    print(error)
                }
                
                
                // second attempt
                jsonAckMessageWithDelimiter.withUnsafeBytes {
                    guard let pointer = [=13=].baseAddress?.assumingMemoryBound(to: UInt8.self) else {
                      return
                    }
                    write(client, pointer, jsonAckMessageWithDelimiter.count)
                }
            } catch {
                print("Error on received message \(error)")
            }
        }
    }
}

在我的节点应用程序中,我无法收到 AckMessage,因为我收到以下错误:

Messages are large, You may want to consider smaller messages.

根据我在 Windows 和 Linux 的经验,我知道 \f 是应该指示消息结尾的分隔符。我在 json 的末尾发送它,但不知何故无法识别。

可能是什么问题?分隔符错误吗?缓冲区大小有问题吗?

在记录我发送的内容时,它说它已按预期发送了所有 61 个字节。

对于遇到此问题的任何人,使用 "\u{000C}" 而不是 "\f" 是解决方案。