我是一個剛學go語言的菜鳥,還沒有資格談論什麼技術分享,隻是為了展示fooking的實際應用,同時把我用go寫的聊天室代碼貼出來供大家消遣,如果有入不了各位法眼的代碼,望輕噴。該聊天室基于fooking,而業務代碼是采用go + fastcgi。
聊天伺服器的入口main函數裡有3個ip和端口配置,分别是chat伺服器、router伺服器和redis伺服器。
chat伺服器就是實作主要的聊天邏輯,router伺服器是用于轉發消息,redis用來存儲使用者資訊。上面我講過這個聊天室是基于fooking,是以用戶端不是直接與go通信,而是透過fooking來通路的。我們使用go内置的fastcgi子產品來建立一個服務,然後處理請求即可,這跟http伺服器非常像,隻是協定規範不同而已,看下面的代碼就你知道建立一個fastcgi伺服器有多簡單了。
代碼中的sessionid就是目前發送請求的用戶端id,當我們要做一些uid與用戶端id映射或者是要發消息給指定使用者的時候就可以使用這個id。event就是目前請求的事件類型(0-表示請求,1-新連接配接,2-關閉連接配接),而聊天室隻需要關心用戶端請求和斷開事件。請求可能是登陸、發消息或者是加入頻道,而斷開事件我們就需要把使用者資訊删除,并且把他的退出資訊廣播給所有在聊天室的人。代碼如下:
在上面的消息處理部分,有兩句rep.header().add和rep.write,這表示如果需要傳回資料給目前發請求的用戶端,可以添加content-length頭(表示要傳回給用戶端的資料長度),然後調用rep.write發送資料(類似http的request對應一個response)。
代碼裡面的消息廣播、使用者分頻道都是在router部分實作,他是fooking消息轉發與使用者資料維持的中間件。
其實開發一個聊天室可以很簡單,可以直接使用websocket協定,讓用戶端跟伺服器直接通信,簡單友善,通信代價低。并且做socket服務也不受協定限制,完全可以自定義或者是使用其它輕量級的協定,比如mqtt什麼的。然而為什麼要使用fastcgi呢?主要是他的協定實作簡單,并且擴充性也非常強,目前世界上最強大的語言php的fpm就是使用該協定與nginx進行通信,如果你的服務使用fastcgi協定開發,那麼你可以完美的使用nginx與你的服務進行通信,這樣做的好處是寫socket服務能像寫web服務一樣調試,開發完一個功能你隻需要簡單的執行如下指令即可(當然你可能需要添加少量的代碼來判斷來源是從nginx還是你自己的用戶端)。
網關與邏輯分離另一個好處是,當業務邏輯代碼需要更新,用戶端毫無察覺的,真正做到無痛更新。另外fastcgi協定本身已經支援多路複用(當然這個需要服務端的支援),這個功能可是大名鼎鼎的http到2.0才支援的喲。
文章開篇已經說了,我是一個go語言的初學者,到這裡來不是為了秀go技,而是為了展示fooking與各語言的銜接。那麼為什麼要使用fooking?我相信很多人都知道網關這個東西(可能在遊戲領域應用的更廣泛一些),他其主要的目的是用于承載用戶端的連接配接,把消息轉發與業務邏輯分開,後端開發人員隻需要專心寫邏輯即可。這就好比我們寫web的時候,從來不需要自己去實作http server。那麼fooking也是這樣一個開源軟體,他将socket服務變的更簡單。更多的特性如下:
1 動态網關添加.
2 每個用戶端唯一sessionid.
3 多點傳播(類似redis的pub/sub).
4 伺服器狀态監控.
5 用戶端事件通知(如:新連接配接、關閉連接配接).
6 後端無語言限制(php, python, go, nodejs, etc...).
7 自定義消息協定.
8 後端長連接配接維持.