李君鋒
摘要:本文設(shè)計(jì)并實(shí)現(xiàn)了一個(gè)基于Bonjour和Stream的網(wǎng)絡(luò)游戲通信系統(tǒng),實(shí)現(xiàn)了iPhone/iPad之間通過局域網(wǎng)進(jìn)行發(fā)布游戲服務(wù)、手機(jī)間連接及互相通信等功能。系統(tǒng)采用了Foundation框架、NSStream協(xié)議和Bonjour協(xié)議進(jìn)行系統(tǒng)的開發(fā),解決了自定義界面、服務(wù)發(fā)現(xiàn)、互相通信等問題。
關(guān)鍵詞:IOS; Bonjour;Stream;局域網(wǎng)通信框架
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2016)20-0036-02
在當(dāng)代移動(dòng)設(shè)備的普及下,越來越多人熱衷于手機(jī)游戲,而現(xiàn)在多數(shù)游戲都是基于廣域網(wǎng)的,所以開發(fā)一套玩家通過局域網(wǎng)進(jìn)行相互交互的游戲通信框架成為可能。在局域網(wǎng)無線通信中,信息數(shù)據(jù)通過電磁波的傳輸,到達(dá)指定接收的網(wǎng)絡(luò)計(jì)算機(jī)中,不受到任何電路的范圍限制,同時(shí)在使用過程中,不僅方便快捷,而且在對(duì)無線網(wǎng)絡(luò)操作的過程中,還具有操作簡(jiǎn)單等優(yōu)點(diǎn)[1]。通過此框架,用戶能夠方便地建立移動(dòng)設(shè)備之間的通信,搭建局域網(wǎng)游戲世界,使得用戶聚焦于游戲本生而非數(shù)據(jù)如何傳遞。一般的通信使用Socket通信,連接時(shí)需要通過輸入服務(wù)器的IP地址和端口信息才能建立連接,這在局域網(wǎng)游戲中是非常不方便的。本文擬開發(fā)一套基于Bonjour和Stream的游戲通信框架,讓玩家能夠方便創(chuàng)建局域網(wǎng)游戲,讓用戶也能更方便的開發(fā)局域網(wǎng)游戲。
1 程序架構(gòu)設(shè)計(jì)
1.1 系統(tǒng)模塊劃分
系統(tǒng)整體可以劃分為監(jiān)聽服務(wù)端、服務(wù)端和客戶端三大部分。其中監(jiān)聽服務(wù)端實(shí)現(xiàn)了NSNetServiceBrowserDelegate協(xié)議,主要用于實(shí)現(xiàn)發(fā)現(xiàn)服務(wù)、查找服務(wù)、獲取通信的數(shù)據(jù)細(xì)節(jié)等功能,其中包含的模塊有,監(jiān)聽服務(wù)模塊、管理服務(wù)模塊;服務(wù)端實(shí)現(xiàn)的主要功能有,設(shè)置服務(wù)器、管理服務(wù)、收到連接、發(fā)送服務(wù)端消息、管理客戶端,其中包含的模塊有管理服務(wù)模塊、消息處理模塊、客戶端管理模塊;而客戶端實(shí)現(xiàn)的主要功能有連接服務(wù)器、消息處理、創(chuàng)建客戶端,其中包含的模塊有消息處理模塊、服務(wù)連接模塊。
圖1描述了監(jiān)聽服務(wù)端的功能分布圖。其中監(jiān)聽服務(wù)模塊通過- (void) serverDidEnableBonjour:(TCPServer *)server withName:(NSString *)string方法對(duì)網(wǎng)絡(luò)上已發(fā)布的服務(wù)進(jìn)行監(jiān)聽,而管理服務(wù)模塊則是通過實(shí)現(xiàn)NSNetServiceBrowserDelegate協(xié)議的方法對(duì)服務(wù)進(jìn)行管理,并且把服務(wù)添加進(jìn)服務(wù)集合里,方便用戶對(duì)服務(wù)的管理。
圖2描述了服務(wù)端的功能分布圖。其中管理服務(wù)模塊中實(shí)現(xiàn)套接字接收新連接事件callbackSocketConnectionAcceptedCallBack,并把連接了的服務(wù)建立成客戶端存進(jìn)于客戶端集合中,方便用戶進(jìn)行管理;而消息處理模塊中實(shí)現(xiàn)了NSStreamDelegate協(xié)議的- (void)stream: handleEvent:方法,把輸入流數(shù)據(jù)轉(zhuǎn)換成NSData,然后再通過NSSelectorFromString轉(zhuǎn)換成回調(diào)函數(shù),方便用戶在外部對(duì)不同類型的消息進(jìn)行處理。
圖3描述了客戶端的功能分布圖。服務(wù)連接模塊通過Bonjour已經(jīng)解析的服務(wù)器地址或服務(wù)器地址進(jìn)行連接服務(wù)器,使用CFStreamCreatePairWithSocketToHost方法創(chuàng)建了一個(gè)到服務(wù)器的TCP/IP連接,以及一對(duì)輸入輸出流。然后將它們轉(zhuǎn)換為等價(jià)的OC對(duì)象——NSInputStream和NSOutputStream。
1.2 技術(shù)架構(gòu)
圖4描述了此框架的架構(gòu)。首先用戶需要在自定義游戲房間界面通過單例類BonjourKit創(chuàng)建監(jiān)聽服務(wù)createBrowserInClass,并把當(dāng)前類設(shè)置代理類用于有新服務(wù)時(shí)通過[BonjourKit sharedBonjourKit].pServiceBrowser.pArrServices獲取服務(wù)集合更新列表,若是創(chuàng)建游戲房間則作為服務(wù)器端。[[BonjourKitsharedBonjourKit] createServerName:];若加入游戲房間,則作為客戶端[[BonjourKit sharedBonjourKit] createClientIndex: Name:];然后在主要的游戲?qū)永镌O(shè)置當(dāng)前類為代理類,用于實(shí)現(xiàn)各類通信消息的處理。
2 核心功能設(shè)計(jì)
1)利用Bonjour建立通信。Bonjour是一種能夠自動(dòng)查詢接入網(wǎng)絡(luò)中的設(shè)備或應(yīng)用程序的協(xié)議,也稱為零配置聯(lián)網(wǎng),能自動(dòng)發(fā)現(xiàn)IP網(wǎng)絡(luò)上的電腦、設(shè)備和服務(wù)。Bonjour 使用工業(yè)標(biāo)準(zhǔn)的 IP 協(xié)議來允許設(shè)備自動(dòng)發(fā)現(xiàn)彼此,而不需輸入IP 地址或配置DNS 服務(wù)器。Bonjour 抽象掉 ip 和 port 的概念,讓我們聚焦于更容易理解的 service。通過 Bonjour,一個(gè)應(yīng)用程序 publish 一個(gè)網(wǎng)絡(luò)服務(wù) service,然后網(wǎng)絡(luò)中的其他程序就能自動(dòng)發(fā)現(xiàn)這個(gè) service,從而可以向這個(gè) service 查詢其 ip 和 port,然后通過獲得的 ip 和 port 建立 socket 連接進(jìn)行通信[2]。通常通過 NSNetService (建立與發(fā)布 service)和 NSNetServiceBrowser (監(jiān)聽查詢網(wǎng)絡(luò)上的 service)來使用 Bonjour[3]。
2)實(shí)現(xiàn)網(wǎng)絡(luò)消息通信封裝了兩個(gè)NSStream,NSInputStream用于從socket讀取數(shù)據(jù),NSOutputStream用于寫入數(shù)據(jù),因?yàn)镾tream是單向的,所以每一個(gè)socket都需要建立兩個(gè)NSStream。NSStreamEvent是一個(gè)流事件枚舉,在-(void)stream:handleEvent: 函數(shù)使用switch語句來判別NSStreamEvent常量[4]。
3)通過Bonjour協(xié)議,創(chuàng)建NSNetService對(duì)象發(fā)布服務(wù)到網(wǎng)絡(luò)中,而這時(shí)需要定義一個(gè)唯一的服務(wù)類型名,此處服務(wù)類型名設(shè)置為"_mygame._tcp."[5]。當(dāng)網(wǎng)絡(luò)中發(fā)現(xiàn)有服務(wù)被添加或者移除時(shí)候,NSNetServiceBrowser的委托方法會(huì)被調(diào)用,在其中進(jìn)行需要的邏輯處理,并且加入到服務(wù)集合中,方便更新服務(wù)列表。
4)若玩家作為客戶端,選擇其中一個(gè)服務(wù)加入其中時(shí),會(huì)向選中的服務(wù)發(fā)送resolveWithTimeout:方法驗(yàn)證服務(wù)是可用的和準(zhǔn)備您的應(yīng)用程序,同時(shí)設(shè)定NSNetService來回調(diào)事件;若玩家作為服務(wù)端,創(chuàng)建了一個(gè)服務(wù)并且被某個(gè)客戶端連接時(shí),會(huì)觸發(fā)SocketConnectionAcceptedCallBack方法得到新接受連接的套接字并創(chuàng)建readstream和writestream,并以此創(chuàng)建一個(gè)Client對(duì)象并存入客戶端集合中。
5)服務(wù)端或者客戶端在接受NSData數(shù)據(jù)后,根據(jù)消息頭調(diào)用對(duì)應(yīng)的消息處理函數(shù)并把消息以鍵-值的詞典方式傳遞過去,而在代理類中應(yīng)實(shí)現(xiàn)需要的消息處理函數(shù)。
3 結(jié)論
本文介紹了如何使用Bonjour和Stream發(fā)布網(wǎng)絡(luò)服務(wù)和互相通信。用戶只需要編寫好游戲間的通信類型以及處理,就能快速地進(jìn)行局域網(wǎng)游戲的開發(fā)。并且Bonjour的使用并不局限于iPhone與iPad,通過Bonjour探測(cè)可以發(fā)布Bonjour服務(wù)的任何類型的設(shè)備。
在框架的開發(fā)過程中,利用Bonjour建立的局域網(wǎng)連接是相較穩(wěn)定的,但網(wǎng)絡(luò)環(huán)境錯(cuò)綜復(fù)雜,所以這是一種相對(duì)穩(wěn)定,在某些情況下仍可能導(dǎo)致網(wǎng)絡(luò)的延遲。本框架只加入了有限的功能性,但已形成了基本框架。但要實(shí)現(xiàn)更為穩(wěn)定的網(wǎng)絡(luò)通信更復(fù)雜的功能,仍有待開發(fā)與拓展。
參考文獻(xiàn):
[1] 王明炯. 關(guān)于局域網(wǎng)無線通信系統(tǒng)的探討[J].中國新技術(shù)新產(chǎn)品,2012(16):23-24.
[2] Lee J,Doerner R,Luderschmidt J,et al.Collaboration between tabletop and mobile device[C]//Ubiquitous Virtual Reality (ISUVR),2011 International Symposium on. IEEE,2011:29-32.
[3] Jonathan Levin. Mac OS X and iOS Internals[M].London:Wrox Press,2012.
[4] (美)Jack Cox.iOS網(wǎng)絡(luò)高級(jí)編程:iPhone和iPad的企業(yè)應(yīng)用開發(fā)[M].張龍.北京:清華大學(xué)出版社.2014:176-180,267-301.
[5] 耿建平,姚瑛.關(guān)于Bonjour技術(shù)的研究[J].國外電子測(cè)量技術(shù),2011(4):73-75.