socket.io还有mongdb在发送数据时是统一转换成字符串发送还是字节流发送?
发布于 10 天前 作者 jinkankakushoujo 447 次浏览 来自 问答

比如一个字节数组,socket.io还有mongdb在发送时是会先转到字符串还是以字节流方式直接发送? 如果转成字符串再发送的话,那么发字节数组可能还没发DataUrl小。 还有就是数值和布尔值,如果都转成字符串发送,那么比起用布尔值,不如直接就0和1更小。

15 回复

socket.io 會使用buffer發送,取決於你的data格式,你可以看看 ffmpeg->socket.io->jsmpeg(canvas) 的串流應用


mongodb的I/O 我想應該是沒有這種顧慮,你可以參考一般DB的blob IO做法,其實大同小異 例如簡單的Image2Blob的問題,轉成binary後DB讀了直接stream出去 要考慮的是你要儲存的究竟是什麼格式,把他宣告成合理的格式就行了


最後的問題牽扯到一些格式在不同平台會有不同解讀及嚴謹度問題 例如有可能code這麼寫 if(isExsit === True){...},那麼出錯就是一定的了 如果真要計較,把欄位名改成a1,b2這種格式遠比0, false有意義 {"name":"Tom","lastname":"Chen","report":[{"subject":"Math","score":80},{"subject":"English","score":90}]} {"nm":"Tom","ln":"Chen","rpt":[{"sj":"Math","s":80},{"sj":"English","s":90}]}


個人想法提供參考

@worl2160 简单的说,socket.io还有mongdb都是按字节流发送不转换成字符串比如JSON后才发送,接收时也不用解析JSON而是直接用某种方式分离出参数,对吧?如果是的话,那我可以考虑优化把DataUrl改成直接发字节数组。至于数值到底是按8字节传递,还是字符串,如果是按字节流照理说每个数字需要8个字节,所以还是先自己转成字符串再传递比较小的数值时更小?

轉buffer,這樣的確1比true短

@worl2160 buffer类型我没怎么用过不太清楚,不过既然你说 的確1比true短,那么说明true先被转成字符串,然后再被转成buffer的吧?

在傳遞資料時,格式一般都是string,你想傳遞mix狀態的資料,json stringify 是必經的過程。

@worl2160 主要是websocket本身是支持发送字节流,而如果放在C++上写传输,肯定会选择尽可能优化,比如用1个字节表示类型,然后后面放数据,这样根据这个字节指明的类型就能得出后面的数据要怎么分离提取。如果是布尔型则固定的一个字节,如果是字符串则可以用NULL一类的来确定长度,数组则可以在数据前多附带一个4字节的长度。 如果按照C++的这种优化方式,就算不用json stringify也可以提取出所有参数,肯定比json要小,解析速度也理论上更快。只不过在js上编程,确实会很喜欢偷懒用现成的,虽然效率不是最高,但是能快速开发。只不过既然是第三方库的话,优化效率可能也是开发方向。

不过我想了下,JS的数组也是对象,JS的数组每个成员可以是不同类型,所以要按C++那套,则需要对对象和数组的每个成员都以这种方式标记。

你這方式我有想到,但是自己寫decoder、encoder太累,所以我不敢去想 基本上傳buffer定義MIME後就是讓browser去調用decoder,所以以此類推,只要規定好編碼方式,壓縮效率自然是最理想… 不過合乎成本嗎?我覺得要看你的使用情境,單純web或聊天也太過於計較那一點浪費。

@worl2160 正因为自己写比较麻烦,所以才想第三方库会不会做这方面优化,不过最关键是知道有没有这优化,从而判断到底用哪种方式更小。很显然,如果以转字符串的方式,那么直接发字节数组会远远大于发DataUrl或base64,所以不会考虑直接发字节数组了,宁可自己转成DataUrl或base64后再发。

你可能誤會我意思了 在我的想法裡,http協議預期都是要傳輸string(字符串),過程是以buffer(字节数组)過去,所以接收端都會默認轉成string形式,但事實上可以不這麼做,這時候用特殊decoder把buffer parse過去,就會是你預期想要的東西了。

例如圖片傳輸: img -> buffer -> network stream -> buffer -> img decoder

<img src="path/to/img">

img -> base64(string) -> buffer -> network stream -> buffer -> base64(string) -> img decoder

<img src="" onload="getB64Img(this, 'path/to/img')">

我認知的 json 格式資料,其實就只是希望還原時有特殊解法能解形態問題 mix object -> json(string) -> buffer -> network stream -> buffer -> json(string) -> mix object

我覺得這是一個很好的學習機會,這東西接觸到底層了,我也不保證我說的是對的…

@worl2160 socket.io是websocket,好像和HTTP没什么关系吧

websocket本來就是為了解決http keep connect的想法而衍生出來的協議,問題不在這裡。 看code吧… 我知道你的問題是「buffer是不是還用string傳輸」,當然不是… 我上面說了,buffer已經很接近傳輸資料時的raw data了…為什麼還要往上進行decode變成string…封包並不是傳送string阿

@worl2160 因为一个socket.io的消息不一定只有一个参数啊,所以才要根据是否变string而判断实际传输的字节长度,如果你用websocket自己写个类似socket.io的库的话就能用C++那套方案来实现,不过socket.io是第三方库,我在问之前不知道他对参数做了什么。

我问的不是「buffer是不是還用string傳輸」,我问的是 socket.io的参数们实际传输时的字节长度,如果布尔值转字符串后自然比布尔值本来的字节长度大,问题的核心不在于是否变字符串,而在于实际传输时的优化问题。

@worl2160 举个例子就是,如果一个布尔值如果按buffer传输,那么字节长度应该为1个字节,但是你说 的確1比true短,这就说明了这个布尔值先被socket.io转成字符串然后才被转成buffer,如果没被转成字符串直接转成buffer,为什么你会说 的確1比true短?1是数值类型,本身占用8个字节大小,照理说应该比布尔值的字节长度大。

我的假設是為了要傳送一個含有bool, string, int的object,所以我是以JSON string來看待這件事情 我想socket io並沒有脫離太遠去優化傳送的東西,當然他還增加了一些其他支援例如binary 原code 而後所以才有下面這種東西 custom parser

回到顶部