使用socket.io-client-swift遇到傳送不了資料的問題

weixin_34292287發表於2017-06-28

sockiet.io-client-swift


  • 前言
    問題 最近在做一個新專案時為了效能考慮,在獲取一些變化比較頻繁時使用websocket的方式進行訂閱推送,在上一個專案時也使用了websocket,當時是直接使用了Facebook開源的SocketRocket,但在這次選型時不知道是什麼原因,後臺伺服器選用了websocket的一個變種,socket.io,於是問題因此而產生,Android那邊在網上使用了一個庫後和伺服器正常通訊能收發資料,可是到我們iOS時,我們選用的是socket.io-client-swift,可是由於這個開源庫的demo非常簡單,導致我們在使用後和伺服器建立連線後就一直相互收不了資料,一個同事很形象的比喻了下

雙方用手機打電話,明明手機都通了,可是就是雙方都說聽不見對方

這一問題折磨了我那負責這一塊的同事好多天後他都沒解決,然後就嘗試著讓我解決,我接受後看了一個晚上也沒什麼進展,最後通過在同事的幫組下使用tcp-flowtcp-flow抓包傳送的資料,發現ping的心跳包能正常傳送,但一旦傳送請求的業務資料就只是在log區裡顯示傳送成功,但實際攔截的資料卻是隻傳送了一個狀態碼4,看到這裡,我當時冒出了想法,既然能傳送狀態碼,我固定傳送些其他資訊看看能不能傳送,經過一番艱辛的努力,發現自己寫的固定內容是能傳送的,而一旦換成這個庫自己生成的內容後就又只有狀態碼了,然後在寫固定傳送內容時後端的同事告訴我傳送的內容還差一個namespace,再跟據這個情況最後發現了是這個庫如果使用者沒有手動設定namespace就會有一個預設的空namespace,然後由於相容做的不好,導致傳送的資料在解析成data時就解析沒了,問題找到,然後按下面方式把問題解決

NSURL *url = [NSURL URLWithString:@"http://192.168.99.221:8000/socket.io/"];
SocketIOClient *socket = [[SocketIOClient alloc] initWithSocketURL:url config:@{@"log": @YES,@"forcePolling":@YES,@"forceWebsockets":@YES}];
socket.nsp = @"/socket.io/" 
[socket connect];
[socket on:@"connect" callback:^(NSArray* data, SocketAckEmitter* ack) {
        NSLog(@"socket connected");
        [socket emit:@"sub" with:@[@"業務資料"]];
}];
[socket on:@"sub" callback:^(NSArray* data, SocketAckEmitter* ack) {
id obj = data.firstObject;
            NSData *jsonData = [obj dataUsingEncoding:NSUTF8StringEncoding];
            NSError *err;
            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                                options:NSJSONReadingMutableContainers
                                                                error:&err];
            NSLog(@"%@",dic);
 }];

這次解決問題的收穫蠻多,

  • 首先是瞭解並使用了tcp-flowtcp-flow這個抓包神器,
  • 另外就是認識到就是在使用第三方庫時的風險所在,由於這個庫的說明實在太簡單,都沒告訴要設定namespace的事,另外由於相容實在做的有問題,在沒有設定namespace時既不提示,還在傳送資料時直接資料解析出差,業務資料傳送不出去,只能有一個狀態碼傳送出來,這個一會兒要去提一個issue
  • 解決問題很多情況下靠思路,有了思路問題總能一步步解決,當然有時候運氣也是很重要的,在同事看到我寫的固定資料差一個namespace後我查詢的範圍也大大縮小了
  • 對於技術選型,儘量不要太追新趕潮,穩定的能提高效率的才是最好的
  • 由於對之前使用的SocketRocket和現在使用的socket.io都只是一知半解的一般使用,沒有具體研究,現在立下一個flag,要把這兩個庫仔細研究一下然後反應成Objective-C

相關文章