Socket.io 是一個基於WebSocket協議的Socket組件。經過這個組件咱們能夠很容易實現基於Socket鏈接的功能,例如實時聊天,彈幕等等。git
同時Socket.io也支持多平臺,在iOS上爲Swift編寫。github
在Socket.io中分別有兩個方法,提交和監聽。 這兩個方法在socket通訊中對應的就是一來一回的數據傳輸。監聽來自服務器的消息,以及提交本地客戶端的操做到服務器。swift
func emit(_ event: String, _ items: SocketData...)
func on(_ event: String, callback: @escaping NormalCallback) -> UUID
經過監聽特定事件來獲取服務器的消息,以及提交特定事件來提交數據至服務器。值得一提的是提交數據支持二進制數據data
、String
甚至是字典,支持的範圍十分普遍。api
SocketIOClientOption
枚舉中。/// Not so type safe way to create a SocketIOClient, meant for Objective-C compatiblity.
/// If using Swift it's recommended to use `init(socketURL: NSURL, options: Set<SocketIOClientOption>)`
///
/// - parameter socketURL: The url of the socket.io server.
/// - parameter config: The config for this socket.
public convenience init(socketURL: NSURL, config: NSDictionary?) {
self.init(socketURL: socketURL as URL, config: config?.toSocketConfiguration() ?? [])
}
//例如:
SocketIOClient* socket = [[SocketIOClient alloc] initWithSocketURL:url config:@{@"log": @YES, @"compress": @YES}];
複製代碼
假如服務器設置了namespace
,在初始化參數中爲nsp
,而且value必須以/
開頭。如:@"nsp":@"/chatroom"
。服務器
在與服務器的受權驗證中,若是使用了明文的token,即將受權token看成參數提交至服務器,應該設置connectParams
。cookie
若是受權驗證在Cookies中或者Header中,能夠設置相應的extraHeaders
和cookies
。socket
服務器URL不須要帶上Socket.io後綴,在組件內部會自動補全。直接設置爲服務器地址便可。測試
設置監聽事件必須在調用connect
方法以前監聽完畢,而後才能調用connect
方法。this
一開始初始化並鏈接服務器,發現始終沒法鏈接成功,初步認定有多是受權不成功,遂與服務器調試,發現服務器在關閉受權的方法以後終於可以鏈接成功,但並沒有法收到消息。進一步調試發現並未進入服務器設置的Namespace中,最終肯定Namespace的設置有問題,通過排查發現Namespace參數拼寫並沒有問題。最後只能閱讀源碼,發現iOS平臺上的組件鏈接的時候並未使用nsp參數,直接致使沒法進入指定的Namespace,這也直接證實一開始的問題所在,因爲服務器的受權驗證放置在指定的Namespace中,鏈接一開始,並未進入指定的Namespace,直接致使受權沒法經過,沒法鏈接成功。url
解決的辦法就是隻能改寫源碼:
open func engineDidOpen(reason: String) {
//插入
if reason == "Connect" {
joinNamespace(nsp)
}
//
DefaultSocketLogger.Logger.log(reason, type: SocketIOClient.logType)
}
複製代碼
雖然改動並不大,可是從頭至尾閱讀源碼並解析着實費了一番功夫。
第一,不少時候咱們要用到別人造的輪子,在以往我會關注做者代碼的質量,以及組件的完善程度,和自身項目是否合適,這裏的合適包括多個方面的考量,組件可維護性,對項目的入侵性,耦合性,等等。可是從未考慮過一個點就是這個輪子是否是存在先天的缺陷。先入爲主的思想影響着我天然而然的認爲既然做爲官方組件確定是沒有問題的通過妥善測試的。 這讓我在之後對於組件的挑選更須要慎重認真瞭解,以及警戒性。
第二,解決問題的過程當中屢次僵持,一度想要放棄換用其餘基於一樣通信協議下的組件。 不少時候情緒會影響咱們寫代碼和調試,遇到問題應該冷靜,從新審視邏輯流程等等。切不可被情緒影響慌了手腳。 暫時性的放下手上的工做,休息幾分鐘深呼吸等等每每有奇效。
第三,不少時候問題每每藏在最不容易發覺的地方,特別是這次官方的源代碼出了問題。不該該抱着僥倖的想法。