2017-05-11 41 views
0

我使用redis來存儲位域數據,並在每個偏移量中設置一個u4值。
我需要在Nodejs服務器中獲取緩衝區。
for 0-7,redis返回正確的緩衝區。
但設置時8-15 value.It返回一個奇怪的緩衝區.Uint8Array視圖到緩衝區,它顯示[239,191,189]它代表亂碼。 這是複製到運行測試代碼。
btw問題與resoponse緩衝區。試圖獲得#0值是好的。爲什麼redis返回一個[239,191,189]響應緩衝區?

const http = require('http'); 
const url = require('url'); 
const fs = require('fs'); 
const redis = require('redis'), 
     RDS_PORT = 6379, 
     RDS_HOST = '139.199.33.69',//139.199.33.69 
     RDS_OPTS = {detect_buffers: true}, 
     client = redis.createClient(RDS_PORT, RDS_HOST, RDS_OPTS); 
console.log('redis ready') 
const canvas_name = 'canvas-bitfield'; 
client.del(canvas_name) 
client.send_command("bitfield",[canvas_name,'SET','u4','#0',10,'OVERFLOW','FAIL']) 

client.send_command('bitfield',[canvas_name,'GET','u4',0],redis.print) //reply:10 

client.get(canvas_name,function(err, reply){ 
    if(err){console.log(err)} 
    const buff = Buffer.from(reply.toString()); 
    const view8 = new Uint8Array(buff); 
    console.log(view8) //Uint8Array(3) [239, 191, 189] 
}) 
+0

這是無關的,但我會指出它:send_command是*異步*。所以你應該使用callback參數來確保在send_command真正完成之後執行任何後續命令:'client.send_command(command,args,callback)' –

回答

2

爲什麼redis的返回一個[239,191,189]響應緩衝器?

請注意,replyString而不是Buffer爲什麼?那麼你正在使用detect_buffers: true。從redis包的文檔中,將此選項設置爲true,reply的類型取決於傳遞給client.get()的第一個參數的類型。既然你通過它字符串canvas_name是一個字符串),答覆的價值也是字符串

client.get(canvas_name,function(err, reply){ 
    console.log(typeof reply) // => String 
    // ... 

對於這項工作,在redisinternally使得函數調用:Buffer.toString()到將<Buffer a0>的緩衝區轉換爲字符串,然後將該字符串傳遞給回調函數;綁定到reply。問題是沒有任何參數傳遞的Buffer.toString()將嘗試使用UTF-8解碼緩衝區,但<Buffer a0>不是有效的UTF-8字符串! Node.js在這種情況下爲silently fails並返回U + FFFD替換字符。因此reply是包含字符串U + FFFD的一個字符或65533.

client.get(canvas_name,function(err, reply){ 
    console.log(reply.length); // 1 
    console.log(reply.charCodeAt(0)) // => 65533 
    // ... 

這個數字(65533)來自Redis的(Node.js的)未解析您的緩衝區爲UTF-8字符串!從那裏,你把65533到緩衝區中,並創建一個Uint8Array的[239, 191, 189]

console.log(Buffer.from("\uFFFD")) // => <Buffer ef bf bd> 
console.log(new Uint8Array(Buffer.from("\uFFFD"))); // => Uint8Array(3) [239, 191, 189] 

迅速解決你的問題,你需要告訴redis包不轉換 緩衝區爲String 。而是直接將緩存:

client.get(new Buffer(canvas_name), function(err, reply) { 
    console.log(typeof reply) // => Buffer 
    console.log(reply) // => <Buffer a0> 
    if(err){console.log(err)} 
    const view8 = new Uint8Array(reply); 
    console.log(view8) // => Uint8Array(3) [160] 
}); 

注:在0-7範圍內十進制值將成功地被解碼爲UTF-8字符串這就是爲什麼你巧合得到了正確的緩衝區的緩衝區。

+0

謝謝!我終於用{return_buffers:true}選項解決了這個問題。 – Natsu

+0

太棒了!如果您發現它有用,請接受此答案。 –

相關問題