How Node.js stream stream solves string encoding problem

In the past few days, I have been developing P2P and using LibP2P as a class library. I have encountered some problems in the communication process between peers. The json string transmitted from one peer to another cannot be fully JSON.parse.

After thinking hard for a long time, it turns out that the concept of convection has not been learned well. LipP2P communication uses the method of streaming to interact, so the input string may be damaged, especially Chinese, especially Chinese! It must be emphasized that there was no problem when I tested the English transmission for the first time, until I entered the word "Hello", and the "unexpected token error" of JSON.parse appeared.

The solution is very simple, that is to use encoding to encode this string (whether it is a normal string or in json format). There are many types of encodings. The Buffer object in node provides us with the following encodings:
Buffer encoding method
In fact, you should choose any one, but you can choose base64. After all, base is a more common encoding method for the web. I have not done others. Test it, everyone test it by themselves.

After selecting base64, it is the encode and decode of the streams of the two peers for communication, one is the dial end (sending) and the other is the handle end (receiving end). The codes are as follows:

Receiving end:

function handle(action: string, callback: MessageCallback): void {
    
    
    this.node.handle(action, async ({
    
     stream }) => {
    
    
        const msg = await pipe(stream, concat)
        const str = Buffer.from(msg.toString(), 'base64').toString('utf8')
        callback($.msgParse(str))
    })
}

sender:

async function send(action: string, msg: Message, peer: Peer[] = []): Promise<void> {
    
    
    if (!peer.length) peer = await this.getPeer()
    // send my peer to the p2p network(every one)
    for (const item of peer) {
    
    
        // skip myself
        if (this.isMyPeer(item.address)) continue
        this.node
            .dialProtocol(`${
      
      item.address}/p2p/${
      
      item.id}`, action)
            .then(({
    
     stream }) => pipe(Buffer.from($.msgStringify(msg)).toString('base64'), stream))
            .catch(e => {
    
    
                console.log(e)
                console.log('Disconnect', item.address)
                this.killPeer(item)
            })
    }
}

In fact, streams in java and C++ also have this character type problem. I won’t introduce it here. To sum it up, when using streams, it’s best to do encode and decode operations, especially unicode-based encodings, which also contain some emoji expressions.

Guess you like

Origin blog.csdn.net/u014466109/article/details/115393238