HTTP協議是不斷發送請求和答應來實現實時通信的,這種方式非常浪費貸款,又消耗服務器CPU的占用。
而使用Socket(套接字)技術,則可以避免很多無用的請求,客戶端跟服務器建立橋梁后就,服務器就可以簡單發送信息給客戶端,大幅降低了利用HTTP技術時的消耗。
Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,是一組接口,所以它並不是一個協議。在設計模式中,Socket是一個門面模式,它把復雜的TCP/IP完全的隱藏了,對用戶來說,只要運用這個接口就能完成開發所需。
Socket鏈接的一般過程有3個步驟:
1、服務器監聽:服務器端處於鏈接等待狀態,實時監控網絡並等待客戶端請求。
2、客戶端請求:客戶端的套接字提出鏈接請求(TCP第一次握手),要連接的目標是服務器端的套接字。客戶端的套接字必須首先描述它要鏈接的服務器的套接字,指出其地址和端口號,然后向服務器提出鏈接請求。
3、鏈接確認:當服務器套接字監聽到客戶端套接字的請求時,就會響應客戶端的請求,建立新線程並把服務器套接字描述發給客戶端(TCP第二次握手),在客戶端確認了描述后,雙方正式建立連接(TCP第三次握手),而服務器端繼續監聽其他套接字的請求。
基於傳輸層的差異,4種不同的Socket:
1*、基於TCP的流套接字:提供給應用層可靠的流式數據服務,使用的協議有BGP、HTTP、FTP、TELNET等。
2*、基於UDP的數據報式套接字:適用於數據傳輸可靠性要求不高的場合,使用協議有:RIP、SNMP、L2TP。
3、基於rawip的原始套接字:非連接,數據傳輸不可靠,但可以使應用層直接訪問網絡層。
4、基於鏈路層的鏈路層套接字:費鏈接,數據傳輸不可靠,為IS-IS協議提供的套接字接口,使協議可以直接訪問鏈路層。
更多關於Socket的介紹可以百度一下。
如何在Cocos2dx使用Socket:
為了使用Socket協議,我們首先要從了解SocketIO::SIODelegate類開始,它是一個代理類,他為下面的SIOClient類代理了5個處理事件的虛函數。
virtual void onConnect(cocos2d::network::SIOClient* client); //當打開socket連接時會調用這個函數
virtual void onMessage(cocos2d::network::SIOClient* client,const std::string& data); //當接收到數據時會調用這個函數
virtual void onClose(cocos2d::network::SIOClient* client); //當socket關閉時會調用這個函數
virtual void onError(cocos2d::network::SIOClient* client,const std::string&data); //當鏈接錯誤時會調用這個函數
virtual void fireEventToScript(cocos2d::network::SIOClient* client,const std::String& eventName,const std::string& data); //當SIOClient對象接收到發送事件信號時轉發到腳本層。
SIOClient client 是連接的SIOClient對象 data是傳送過來的信息 eventName是事件名稱
由於版本的更新,前三個函數已經被廢棄,三個事件在新版中會以"connect","message","close"時間觸發。
SIOClient類的方法 增加對其了解:
SIOClient(const std::string& host,int port,const std::string& path,SIOClientimpl* impl,SocketIO::SIODelegate* delegate) //SIOClient的構造函數,參數一是主機地址,參數二是端口號,參數三是終端路徑,參數四是SIOClientimpl對象。
SocketIO::SIODelegate* getDelegate() //的到客戶端的代理對象。
void send(const std::string& s) //發送一條消息到服務端。
void emit(const std::string& eventname,const std::string& args) //發送指定事件和參數給客戶端,參數一是事件名稱,參數二是事件參數。
void on(const std::string& eventName,SIOEvent e) //注冊一個套接字事件回調,回調函數通過CC_CALLBACK2使用。參數一是事件名,參數二是回調函數。
void setTag(const char* tag)給SIOClient設置標簽。
const char* getTag() //獲取標簽的get方法
開發實例解釋:
1、要使用套接字協議,首先要繼承SIODelegate,並且實現必要的虛函數:
class HelloWorld:public cocos2d::Layer,public cocos2d::network::SocketIO::SIODelegate{
......//必要東西
cocos2d::network::SIOClient * _sioClient; //封裝一個SIOClinet類
......//重寫上面提及到的必要函數
}
2、打開Socket鏈接
_sioClient = SocketIO::connect("localhost:8080",*this); //連接服務器
_sioClient->setTag("Test Client"); //設置標記請求
_sioClient->on("testeventt",CC_CALLBACK_2(HelloWorld::onTest,this)); //注冊回調事件,這就是上面提及到用"connect"事件觸發的方式。
3、向服務器發送消息的方法
_sioClient->send("sdfasdfdsafs"); //發送sdfasdfdsafs消息給服務器
4、向服務器發送給定的事件和參數
_sioClient->send("testevent","{\"name"}"); //發送事件testevent給服務器,參數是{\"name"}
5、關閉連接
_sioClient->disconnect() //關閉這個套接字