青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

eXile 的專欄

[T] ICE實例學習:Let's Chat! (2) 實現(xiàn)服務器


服務器實現(xiàn):

       服務器使用C++。注意它的結構:類 ChatRoom 實現(xiàn)了大部分的應用邏輯。為了支持推模型與拉模型,服務器實現(xiàn)了類ChatSession 和類 PollingChatSession。 ChatRoom 調用 ChatRoomCallbackAdapter 對象的 send 函數(shù)來傳遞客戶消息,該對象隱藏了兩種模型之間的差異。

ChatRoom 實現(xiàn):

      ChatRoom是一個普通的C++對象,而不是一個Servant.
// C++ 
class ChatRoomCallbackAdapter { /*  */ }; 
typedef IceUtil::Handle
<ChatRoomCallbackAdapter> ChatRoomCallbackAdapterPtr; 
 
class ChatRoom : public IceUtil::Shared 

public
    
void reserve(const string&); 
    
void unreserve(const string&); 
    
void join(const string&const ChatRoomCallbackAdapterPtr&); 
    
void leave(const string&); 
    Ice::Long send(
const string&const string&); 
 
private
    typedef map
<string, ChatRoomCallbackAdapterPtr> ChatRoomCallbackMap; 
 
    ChatRoomCallbackMap _members; 
    
set<string> _reserved; 
    IceUtil::Mutex _mutex; 
}; 
typedef IceUtil::Handle
<ChatRoom> ChatRoomPtr;

      成員_reserverd是一個字符串集合,它存儲已經建立回話,但是還沒有加入聊天室的客戶名。_members存儲當前聊天室的所有用戶(已經調用過join函數(shù)的用戶)。

     成員函數(shù) reserve 和 unreserve 維護 _reserved 集合。

// C++ 
void 
ChatRoom::reserve(
const string& name) 

    IceUtil::Mutex::Lock sync(_mutex); 
    
if(_reserved.find(name) != _reserved.end() || _members.find(name) != _members.end()) 
    { 
        
throw string("The name " + name + " is already in use."); 
    } 
    _reserved.insert(name); 

 
void 
ChatRoom::unreserve(
const string& name) 

    IceUtil::Mutex::Lock sync(_mutex); 
    _reserved.erase(name); 
}


     join操作添加用戶到聊天室。

// C++ 
void 
ChatRoom::join(
const string& name, const ChatRoomCallbackAdapterPtr& callback) 

    IceUtil::Mutex::Lock sync(_mutex); 
    IceUtil::Int64 timestamp 
= IceUtil::Time::now().toMilliSeconds(); 
    _reserved.erase(name); 
 
    Ice::StringSeq names; 
    ChatRoomCallbackMap::const_iterator q; 
    
for(q = _members.begin(); q != _members.end(); ++q) 
    { 
        names.push_back((
*q).first); 
    } 
 
    callback
->init(names); 
 
    _members[name] 
= callback; 
 
    UserJoinedEventPtr e 
= new UserJoinedEvent(timestamp, name); 
    
for(q = _members.begin(); q != _members.end(); ++q) 
    { 
        q
->second->join(e); 
    } 
}


      send實現(xiàn),同join實現(xiàn)非常類似:

// C++ 
Ice::Long 
ChatRoom::send(
const string& name, const string& message) 

    IceUtil::Mutex::Lock sync(_mutex); 
    IceUtil::Int64 timestamp 
= IceUtil::Time::now().toMilliSeconds(); 
 
    MessageEventPtr e 
= new MessageEvent(timestamp, name, message); 
    
for(ChatRoomCallbackMap::iterator q = _members.begin(); q != _members.end(); ++q) 
    { 
        q
->second->send(e); 
    } 
    
return timestamp; 
}

 

 類 ChatRoomCallbackAdapter

// C++ 
class ChatRoomCallbackAdapter : public IceUtil::Shared 

public
    
virtual void init(const Ice::StringSeq&= 0
    
virtual void join(const UserJoinedEventPtr&= 0
    
virtual void leave(const UserLeftEventPtr&= 0
    
virtual void send(const MessageEventPtr&= 0
};

推模式 CallbackAdapter 實現(xiàn):
class SessionCallbackAdapter : public ChatRoomCallbackAdapter 

public
    SessionCallbackAdapter(
const ChatRoomCallbackPrx& callback, const ChatSessionPrx& session)    : _callback(callback), _session(session) 
    { 
    } 
 
    
void init(const Ice::StringSeq& users) 
    { 
        _callback
->init_async(new AMICallback<AMI_ChatRoomCallback_init>(_session), users); 
    } 
 
    
void join(const UserJoinedEventPtr& e) 
    { 
        _callback
->join_async(new AMICallback<AMI_ChatRoomCallback_join>(_session), 
                              e
->timestamp, 
                              e
->name); 
    } 
 
    
void leave(const UserLeftEventPtr& e) 
    { 
        _callback
->leave_async(new AMICallback<AMI_ChatRoomCallback_leave>(_session), 
                               e
->timestamp, 
                               e
->name); 
    } 
 
    
void send(const MessageEventPtr& e) 
    { 
        _callback
->send_async(new AMICallback<AMI_ChatRoomCallback_send>(_session), 
                              e
->timestamp, 
                              e
->name, 
                              e
->message); 
    } 
 
private
    
const ChatRoomCallbackPrx _callback; 
    
const ChatSessionPrx _session; 
};

      看一下SessionCallbackAdapter的四個成員函數(shù),當異步調用完成時,都使用類AMICallback來接收通知。它的定義如下:
template<class T> class AMICallback : public T 

public
    AMICallback(
const ChatSessionPrx& session) : _session(session) 
    { 
    }
    
virtual void ice_response() 
    { 
    } 
 
    
virtual void ice_exception(const Ice::Exception&
    { 
        
try 
        { 
            _session
->destroy(); // Collocated 
        } 
        
catch(const Ice::LocalException&
        { 
        } 
    } 
 
private
    
const ChatSessionPrx _session; 
};
       當用戶回調操作拋出異常,服務器立即銷毀客戶會話,即把該用戶趕出聊天室。這是因為,一旦客戶的回調對象出現(xiàn)了一次異常,它以后也就不可能再正常。


推模式會話創(chuàng)建

     現(xiàn)在來看一下會話創(chuàng)建。推模式的客戶使用Glacier2,所以要使用Glacier2的會話創(chuàng)建機制。Glacier2 允許用戶通過提供一個Glacier2::SessionManager對象的代理來自定義會話創(chuàng)建機制。通過設置Glacier2.SessionManager屬性來配置Gloacier2,就可以使用自己的會話管理器。會話管理器除了一個trivial構造函數(shù)(設置聊天室指針),只有一個操作,create,Glacier2調用它來代理應用的會話創(chuàng)建。 create 操作必須返回一個會話代理(類型為Glacier2::Session*)。實現(xiàn)如下:
Glacier2::SessionPrx 
ChatSessionManagerI::create(
const string& name,
                            
const Glacier2::SessionControlPrx&
                            
const Ice::Current& c) 

    
string vname; 
    
try 
    { 
        vname 
= validateName(name); 
        _chatRoom
->reserve(vname); 
    } 
    
catch(const string& reason) 
    { 
       
throw CannotCreateSessionException(reason); 
    } 
 
    Glacier2::SessionPrx proxy; 
    
try 
    { 
        ChatSessionIPtr session 
= new ChatSessionI(_chatRoom, vname); 
        proxy 
= SessionPrx::uncheckedCast(c.adapter->addWithUUID(session)); 
 
        Ice::IdentitySeq ids; 
        ids.push_back(proxy
->ice_getIdentity()); 
        sessionControl
->identities()->add(ids); 
    } 
    
catch(const Ice::LocalException&
    { 
        
if(proxy) 
        { 
            proxy
->destroy(); 
        } 
        
throw CannotCreateSessionException("Internal server error"); 
    } 
    
return proxy; 
}

     首先調用一個簡單的幫助函數(shù) validateName, 來檢查傳遞的用戶名是否包含非法字符,并把它轉為大寫,然后調用 reserver函數(shù)把它加到聊天室的_reserved集合中。我們要監(jiān)視這些操作拋出的消息,并把它轉化為Glacide2::CannotCreateSessionException異常,即在create操作的異常規(guī)范聲明的異常。
     接著實例化一個ChatSessionI對象(見下面)來創(chuàng)建會話。注意這個會話使用UUID作為對象標識,所以保證標識符唯一。
    最后,添加這個新創(chuàng)建的會話標識,Gllacier2只通過它來轉發(fā)經過這個會話的請求。實際上,“只轉發(fā)經過這個會話的并且只到這個會話的請求”,這是一種安全的辦法:如果有惡意客戶能猜出另一個客戶會話的標識,它也不能向別的對象發(fā)送請求(可能在除了聊天服務器之外的服務器上)。如果出錯,就銷毀剛創(chuàng)建的會話對象,這樣避免了資源泄露。
       這就是利用Glacier2創(chuàng)建會話的全部。如果你希望使用Glacier2的認證機制,可以設置屬性Glacier2.PermissionsVerifier為執(zhí)行認證的對象代理。(Glacier2提供一個內置的權限驗證器,NullPermissionsVerifier,可以檢查用戶名和密碼)。
       圖:會話創(chuàng)建交互圖(略)

       ChatSessionI類實現(xiàn)了ChatSession接口。
class ChatSessionI : public ChatSession 

public
    ChatSessionI(
const ChatRoomPtr&const string&); 
 
    
virtual void setCallback(const ChatRoomCallbackPrx&const Ice::Current&); 
    
virtual Ice::Long send(const string&const Ice::Current&); 
    
virtual void destroy(const Ice::Current&); 
 
private
    
const ChatRoomPtr _chatRoom; 
    
const string _name; 
    ChatRoomCallbackAdapterPtr _callback; 
    
bool _destroy; 
    IceUtil::Mutex _mutex; 
}; 
typedef IceUtil::Handle
<ChatSessionI> ChatSessionIPtr;
         構造函數(shù)設置聊天室和用戶名,并把_destroy設置為False.
      
        由于Glacier2::create操作不允許傳遞代理,必須把創(chuàng)建會話和設置回調分成兩步。這是setCallback的實現(xiàn);
void 
ChatSessionI::setCallback(
const ChatRoomCallbackPrx& callback, const Ice::Current& c) 

    IceUtil::Mutex::Lock sync(_mutex); 
    
if(_destroy) 
    { 
        
throw Ice::ObjectNotExistException(__FILE__, __LINE__); 
    } 
 
    
if(_callback || !callback) 
    { 
        
return
    } 
 
    Ice::Context ctx; 
    ctx[
"_fwd"= "o"
    _callback 
= new SessionCallbackAdapter(callback->ice_context(ctx), 
                                           ChatSessionPrx::uncheckedCast( 
                                               c.adapter
->createProxy(c.id))); 
    _chatRoom
->join(_name, _callback); 
}

      注意,在使用join傳遞代理之前,向客戶代理添加了一個值為 "o" 的_fwd上下文。它提示Glacier使用單向調用來轉發(fā)客戶回調。這樣比雙向調用更加有效。因為所有的回調操作均為void返回值,所以可以單向調用。
     服務器的回調為普通的雙向調用。這樣當出錯時可以通知服務器。當客戶端出錯時,這個對結束客戶會話很有用。

     一旦客戶調用了setCallback,就可以接收聊天室的各種行為通知。下為send實現(xiàn):

Ice::Long 
ChatSessionI::send(
const string& message, const Ice::Current&

    IceUtil::Mutex::Lock sync(_mutex); 
    
if(_destroy) 
    { 
        
throw Ice::ObjectNotExistException(__FILE__, __LINE__); 
    } 
    
if(!_callback) 
    { 
        
throw InvalidMessageException("You cannot send messages until you joined the chat."); 
    } 
    
string
    
try 
    { 
        msg 
= validateMessage(message); 
    } 
    
catch(const string& reason) 
    { 
        
throw InvalidMessageException(reason); 
    } 
    
return _chatRoom->send(_name, msg); 
}

 
    客戶要離開聊天室,只要調用 destory.

void 
ChatSessionI::destroy(
const Ice::Current& c) 

    IceUtil::Mutex::Lock sync(_mutex); 
    
if(_destroy) 
    { 
        
throw Ice::ObjectNotExistException(__FILE__, __LINE__); 
    } 
    
try 
    { 
        c.adapter
->remove(c.id);
        
if(_callback == 0
        { 
            _chatRoom
->unreserve(_name); 
        } 
        
else 
        { 
            _chatRoom
->leave(_name); 
        } 
    } 
    
catch(const Ice::ObjectAdapterDeactivatedException&
    { 
        
// No need to clean up, the server is shutting down. 
    } 
    _destroy 
= true
}

 

 

posted on 2009-03-26 00:54 eXile 閱讀(3218) 評論(0)  編輯 收藏 引用 所屬分類: 網絡開發(fā)ICE

導航

<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

統(tǒng)計

常用鏈接

留言簿(18)

隨筆分類

隨筆檔案

服務器編程

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲女人小视频在线观看| 免费成人性网站| 国产精品成人观看视频国产奇米| 亚洲经典在线| 久久久久久久久久久一区| 欧美粗暴jizz性欧美20| 亚洲一区二区高清| 精品999网站| 欧美性大战久久久久| 久久不见久久见免费视频1| 欧美国产亚洲精品久久久8v| 亚洲视频网站在线观看| 亚洲国产欧美在线| 国产精品视频不卡| 欧美日韩精品免费观看视一区二区| 欧美一级黄色网| 日韩网站免费观看| 欧美激情网站在线观看| 亚洲伦伦在线| 欧美成人性网| 在线视频欧美日韩精品| 亚洲黄色性网站| 国产精品99久久99久久久二8| 亚洲一区二区在线免费观看视频| 亚洲精品乱码久久久久久久久| 久久久人人人| 欧美专区18| 午夜视频在线观看一区| 99一区二区| 美女精品在线| 亚洲第一综合天堂另类专| 国产精品久久午夜夜伦鲁鲁| 亚洲国内高清视频| 久久尤物视频| 久久狠狠久久综合桃花| 午夜精品久久久久久久99樱桃| 久久久国产一区二区三区| 欧美一区二区三区婷婷月色| 亚洲一区免费网站| 亚洲午夜影视影院在线观看| 久久福利影视| 夜夜嗨一区二区三区| 在线综合亚洲欧美在线视频| 久久精品首页| 免费在线观看成人av| 男女激情久久| 国产免费一区二区三区香蕉精| 国产女主播一区二区| 国产欧美一区二区三区久久人妖| 最新国产乱人伦偷精品免费网站 | 亚洲国产高清一区二区三区| 黄色成人在线观看| 亚洲国产精品第一区二区| 欧美亚洲综合另类| 欧美成人精品激情在线观看| 欧美二区不卡| 久久国产一区| 国产一区二区三区高清在线观看| 一色屋精品视频免费看| 亚洲免费观看高清完整版在线观看| 亚洲视频精品| 亚洲欧洲日产国产综合网| 久久精品一二三区| 在线观看一区视频| 蜜臀久久99精品久久久画质超高清| 亚洲人成欧美中文字幕| 欧美福利一区二区三区| 国产精品欧美久久| 亚洲综合日本| 亚洲综合99| 欧美国产日产韩国视频| 亚洲区中文字幕| 亚洲国产一成人久久精品| 欧美精品久久久久a| 韩国一区电影| 欧美成人一区二区| 欧美精品18+| 午夜视频在线观看一区二区三区| 亚洲欧美文学| 欧美婷婷六月丁香综合色| 国产农村妇女毛片精品久久莱园子| 亚洲综合日韩在线| 久久精品123| 亚洲视频在线二区| 欧美韩国日本综合| 欧美激情一区二区三区高清视频| 亚洲精品乱码久久久久久| 亚洲综合99| 亚洲免费在线视频| 在线观看一区二区精品视频| 亚洲激情欧美| 国产欧美一区二区三区在线老狼 | 亚洲国产精品福利| 亚洲人被黑人高潮完整版| 国产精品久久久久影院色老大| 欧美一区二区三区四区高清| 美女黄毛**国产精品啪啪| 午夜国产精品视频| 久久亚洲精品视频| 国产综合色产在线精品| 亚洲免费伊人电影在线观看av| 亚洲欧美日韩在线一区| 亚洲人成在线播放| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 欧美三级在线播放| 欧美jizzhd精品欧美喷水| 欧美色网一区二区| 免费日韩av电影| 国产精品人人做人人爽| 亚洲国产精品va在线看黑人动漫| 国产精品二区在线| 欧美激情精品久久久久| 国产偷自视频区视频一区二区| 欧美一级久久久久久久大片| 噜噜噜在线观看免费视频日韩| 亚洲欧美伊人| 欧美日韩mp4| 欧美国产成人在线| 国产日韩欧美精品在线| 一本色道久久88精品综合| 欧美体内谢she精2性欧美| 欧美成人dvd在线视频| 国产欧美一区二区白浆黑人| 中国成人亚色综合网站| 亚洲毛片在线看| 美女黄网久久| 欧美激情一区| 亚洲国产一区在线| 久久免费高清视频| 久久久久一区二区| 韩日欧美一区二区三区| 午夜日韩电影| 亚洲日本视频| 久久视频这里只有精品| 久久免费精品视频| 国内成人在线| 久久精品伊人| 美国成人直播| 欧美日韩美女在线观看| 在线视频中文亚洲| 国内精品美女在线观看| 亚洲午夜av| 亚洲国产精品一区二区尤物区| 亚洲一区二区三区在线播放| 亚洲一区二区毛片| 国产精品欧美日韩久久| 亚洲综合色激情五月| 香蕉成人伊视频在线观看| 国产精品日韩高清| 亚洲欧美国产制服动漫| 久久精品国产一区二区三| 国产一区美女| 久久免费国产| 亚洲精品影院在线观看| 亚洲自拍偷拍视频| 国产午夜精品美女毛片视频| 久久av老司机精品网站导航| 亚洲免费观看高清完整版在线观看熊| 久久理论片午夜琪琪电影网| 欧美成人免费va影院高清| 亚洲精品免费电影| 国产精品白丝av嫩草影院| 欧美一区二区三区四区高清| 免费在线观看成人av| aaa亚洲精品一二三区| 国产精品欧美日韩久久| 久久久欧美精品sm网站| 亚洲国产精品久久精品怡红院| 中文一区二区在线观看| 国产欧美日韩综合| 欧美jjzz| 亚洲欧美日韩精品久久奇米色影视 | 99v久久综合狠狠综合久久| 亚洲一区二区三区四区中文| 国产一区二区高清视频| 欧美电影在线观看| 欧美第十八页| 亚洲一区二区精品在线观看| 黄色亚洲免费| 欧美日韩调教| 噜噜噜在线观看免费视频日韩| 一区二区三区四区五区在线| 另类激情亚洲| 午夜一区二区三区在线观看| 91久久国产综合久久| 国产精品乱码| 欧美高清视频免费观看| 香蕉成人久久| 日韩小视频在线观看专区| 欧美一区二区日韩一区二区| 亚洲精品少妇30p| 国语自产精品视频在线看8查询8| 欧美日韩三级视频| 欧美成人精品1314www| 久久成人免费网| 亚洲欧美日本视频在线观看| 亚洲毛片在线看| 亚洲国产日韩欧美在线99| 乱人伦精品视频在线观看| 羞羞色国产精品|