這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
因為工作的需要,接觸了websocket,開始的一些很簡單的代碼,都不知道該怎樣運行起來,所以,總是有一層神秘感,卻沒有太多的興趣去研究它。不過,還是免不了要瞭解一些才不至於對於後續的工作有影響。從塌下心來學習,到最後完成編碼測試,不超過一周,遇到了很多問題,萬幸,通過自己的思考和師傅們幫忙都解決了。
關於go與websocket編程,github上有很多開源的源碼,比如https://github.com/garyburd/go-websocket。我發現,現在網上流傳的關於go 的websocket編程基本上都是差不多的類型,當然,websocket也不過如此而已啦。再說說,對如此簡單的問題,我碰到的那些麻煩事吧。
1.當伺服器啟動起來之後,再怎麼運行?因為剛開始對websocket的認識都是一知半解的,連程式怎樣運行起來都不知道。開始是直接運行html檔案,只是靜態頁面,貌似根本就沒有跟伺服器進行互動一樣。想了想,直接在瀏覽器中輸入ip,竟然好了,這才明白伺服器中指定url的意義。
2.因為工作需要,我們的開發都是在虛擬機器內進行的,可是虛擬機器上不能連外網的。自己覺得還是脫離虛擬機器用起來更爽些,所以,不辭勞苦地每天早上早來把環境部署好,就是為了當天可以在外網環境中工作,這是多麼大無畏的精神啊,嘿嘿。言歸正傳,在外網運行好好的程式,遷移到內網的時候卻怎樣都運行不起來了。這個原因也是很容易找的,因為內網和外網只有一個區別,一個能上外網,一個不能。看了下代碼,是有src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",所以,這些js資源應該是在網上下載下來的,我把這個庫下載下來儲存到檔案,通過src將資源關聯進來,竟然還不行。同樣的操作,我在外網又弄了一遍,也是運行部起來。以前學過一些瀏覽器調試的方法,發現根本就找不到這些源檔案,目錄都是好好的,怎麼就是找不到呢?真是讓人鬱悶了。把師父叫過來,他說找不到資源,然後把websocket的原理又給我講了一遍,這些協議什麼的以前接觸太少了,好多時候不是一下子就能明白過來的。說在瀏覽器中輸入ip時,會從這個目錄下去找,當然找不到了。然後說開啟nginx什麼的,反正我沒聽懂。既然只能找到這個html檔案,我為何不能把這些js檔案內容都直接寫到html中呢?事實證明,這個想法還是不錯的,因為js代碼都比較集中,不會影響代碼的可讀性。
3.關於協議中資訊的傳輸,很重要的一點是,要統一兩端的資料格式。我的想法就是拿到原原本本從對端傳來的資料,根據自己的需要進行封裝。這樣兩邊都是以byte數組進行傳遞的。可是,server端接收到資料之後,為了驗證正確性,我把它轉換為字串列印出來,也奇了怪了,只要是一轉換,就只能列印出第一次接收的資料,後面的好像都被丟掉了一樣。如果不轉換,就可以一條不少地把資訊的二進位流列印出來。我把所有會出錯的地方都掃了一遍,並不覺得哪裡會有問題啊。我又把師父給叫來了。把我的情況描述了下,他給我的建議是,盡量使用websocket包已經封裝好的函數,這樣一方面效能上有保證,另一方面也可以減少出錯的幾率。我當時還是很糾結為什麼會出現這樣的結果,所以即使是將自己的函數替換為函數庫中的函數,總不忘去試一下會不會轉換時候還是有問題。為了調試方便,把所有的輸入到重新導向了檔案,然後通過文字編輯器看結果。這次,還是同樣的結果,這說明My Code可能不是導致出現問題的源頭。我把輸出盡量減少,在編譯器中直接運行,竟然看到了正確的結果,我確認,出問題的是文字編輯器,真是不靠譜啊,害得我花了一下午的時間來找問題。後來也碰到了類似的問題,所有的輸出在文字編輯器中竟然都成了一串串的數字,實用cat列印,內容是正常的。不自己冒出一句話,這開源的真是不靠譜啊。當然,現在不會再那麼依賴文字編輯器了,其實已經換了三個了,總會時不時出現惱人的bug。
4.關於代碼的組織圖方面,我覺得不太可能的事情都被師父一句話給解決了,真是佩服得我五體投地啊。有些時候,把一些功能封裝到一個函數中,再進行調用,可以使代碼看起來比較整潔,我就犯了這個毛病,總是想著把那些功能封裝起來,直接一調用,很方便。關於將函數嵌入到內部,倒是見過,自己從來都沒有用過,現在遇到問題,也不可能想到可以那樣解決啊。所以,這也算又是一個經驗吧。
5.中文亂碼問題。對於學java的人來說,中文亂碼好像是老生常談的問題,不管你怎麼小心翼翼,這個中文亂碼總是陰魂不散。以前,每次遇到亂碼,就會抱怨自己,怎麼就選擇了java了呢,這不是沒事找事嗎?現在好不容易脫離java了,竟然同樣遇到了中文亂碼。我竟然跟師傅討價還價,我們可以不支援中文啊,幹嘛非要花力氣去解決這個問題。他當時臉都綠了,說這個必須有啊。現在想想,自己真是挺搞笑的,怎麼這麼容易就退縮了呢。使用英文的時候,tcp和websocket互相通訊都是好的,唯有在websocket瀏覽器用戶端輸入中文時候就亂碼了。跟蹤了很久,發現從瀏覽器中發出,到從伺服器往外發送都是正確的中文,只有到瀏覽器接收到資料之後就成了亂碼了。我就把問題歸結為,js代碼中字元編碼是不是有問題呢?當時並沒有覺得自己的伺服器發送端是有問題的,因為即使是websocket間使用程式通訊,中文也是沒有問題的。找來以前的師父,他再三問我確認伺服器端發送時候是正常的嗎,開始我說確定,後來被他問蒙了,變成了應該沒問題吧。他就開始找前端的問題。說按理說前端代碼都是自適應的,不應該調整字元編碼,要不然使用者體驗就差了,誰因為訪問個網頁還去修改字元集啊。最後得出的結論是,瀏覽器收到訊息時候已經是亂碼了。這就不好玩了,這充分說明問題是出在發送端的,那為什麼不用瀏覽器就是好的呢?用原來的demo程式運行,發現中文是可以的,找了下,原來我發送的時候都是把訊息轉換成了byte數組,其實直接按照string格式的資料傳遞給函數就可以了。也許函數內部已經將這些資料進行了重新轉換了吧。
這幾個應該是糾纏我時間最長的問題,通過解決這些問題,自己也學會了很多東西。遇到問題能夠靜下心來分析了。