当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

C++远程调用类操作支持Callback Interface(2)

    至此客户端就完成了。下面是服务器端所有代码,最后附上截图。这个截图是我的电脑上运行服务器和一个客户端,然后叫了另一个人在其他地方打开我的客户端,链接我的服务器,最后我这边显示的内容:

    服务器端RoaTalk.h是服务的声明:

  1 #ifndef VCZH_ROATALK_SERVICE_PROVIDER
  2 #define VCZH_ROATALK_SERVICE_PROVIDER
  3 
  4 #include "..\..\..\..\VL++\Library\Data\Inspector\VL_ObjectServer.h"
  5 
  6 using namespace vl;
  7 using namespace vl::inspector;
  8 
  9 class RoaTalkUser;
 10 class RoaTalkCallback;
 11 class RoaTalkService;
 12 
 13 /*********************************************************************************************************
 14 服务
 15 *********************************************************************************************************/
 16 
 17 class RoaTalkUser : public VL_Base
 18 {
 19 public:
 20     typedef VL_AutoPtr<RoaTalkUser>                    Ptr;
 21     typedef VL_List<Ptr , false , RoaTalkUser*>        List;
 22     typedef VL_ListedMap<VUnicodeString , Ptr>        StringMap;
 23 
 24     VUnicodeString                    Name;
 25     RoaTalkService*                    Owner;
 26 };
 27 
 28 class RoaTalkCallback : public VL_ObjectCallback
 29 {
 30 public:
 31     virtual void                    Say(RoaTalkUser::Ptr User , VUnicodeString Message);
 32     virtual void                    Login(RoaTalkUser::Ptr User);
 33     virtual void                    Logout(RoaTalkUser::Ptr User);
 34     virtual void                    Rename(VUnicodeString OldName , RoaTalkUser::Ptr User);
 35 };
 36 
 37 class RoaTalkService : public VL_ObjectService
 38 {
 39 protected:
 40     VUnicodeString                    FName;
 41     RoaTalkCallback*                FCallback;
 42 
 43     void                            Initialize();
 44 public:
 45     typedef VL_List<RoaTalkService* , true>            List;
 46 
 47     RoaTalkService();
 48     ~RoaTalkService();
 49 
 50     RoaTalkCallback*                GetCallback();
 51 
 52     VUnicodeString                    GetCurrentName();
 53     VBool                            SetCurrentName(VUnicodeString Name);
 54     void                            Say(VUnicodeString Message);
 55     VL_AutoPtr<RoaTalkUser::List>    GetUsers();
 56 };
 57 
 58 class RoaTalkServer : public VL_Base
 59 {
 60 protected:
 61     RoaTalkUser::StringMap            FUsers;
 62     VL_SynCriticalSection            FServerLock;
 63 public:
 64     RoaTalkServer();
 65     ~RoaTalkServer();
 66 
 67     VBool                            CreateUser(VUnicodeString Name , RoaTalkService* Service);
 68     VBool                            DestroyUser(VUnicodeString Name);
 69     VBool                            RenameUser(VUnicodeString OldName , VUnicodeString NewName);
 70     VL_AutoPtr<RoaTalkUser::List>    GetUsers();
 71     VBool                            Say(VUnicodeString Name , VUnicodeString Message);
 72 };
 73 
 74 extern void                            CreateRoaTalkServer();
 75 extern void                            DestroyRoaTalkServer();
 76 extern RoaTalkServer*                GetRoaTalkServer();
 77 
 78 /*********************************************************************************************************
 79 注册
 80 *********************************************************************************************************/
 81 
 82 VL_BEGIN_INSPECTOR_DECLARATION
 83 
 84     VL_BEGIN_BASE_CLASS(RoaTalkUser)
 85         VL_ADD_CLASS_MEMBER(Name)
 86     VL_END_CLASS(RoaTalkUser)
 87 
 88     VL_BEGIN_CALLBACK(RoaTalkCallback)
 89         VL_ADD_CLASS_METHOD(Say)
 90         VL_METHOD_PARAMETER(User)
 91         VL_METHOD_PARAMETER(Message)
 92 
 93         VL_ADD_CLASS_METHOD(Login)
 94         VL_METHOD_PARAMETER(User)
 95 
 96         VL_ADD_CLASS_METHOD(Logout)
 97         VL_METHOD_PARAMETER(User)
 98 
 99         VL_ADD_CLASS_METHOD(Rename)
100         VL_METHOD_PARAMETER(OldName)
101         VL_METHOD_PARAMETER(User)
102     VL_END_CLASS(RoaTalkCallback)
103 
104     VL_BEGIN_DUAL_SERVICE(RoaTalkService,RoaTalkCallback)
105         VL_ADD_CLASS_METHOD(GetCurrentName)
106 
107         VL_ADD_CLASS_METHOD(SetCurrentName)
108         VL_METHOD_PARAMETER(Name)
109 
110         VL_ADD_CLASS_METHOD(Say)
111         VL_METHOD_PARAMETER(Message)
112 
113         VL_ADD_CLASS_METHOD(GetUsers)
114     VL_END_CLASS(RoaTalkService)
115 
116     VL_EXTERN_INSPECTOR_MANAGER(RoaTalk)
117 
118 VL_END_INSPECTOR_DECLARATION
119 
120 #endif

    然后是它的实现:

  1 #include "RoaTalk.h"
  2 #include "RoaTalk_Callback.h"
  3 
  4 extern void PrintNotify(VUnicodeString Message);
  5 
  6 /*********************************************************************************************************
  7 RoaTalkCallback
  8 *********************************************************************************************************/
  9 
 10 void RoaTalkCallback::Say(RoaTalkUser::Ptr User , VUnicodeString Message)
 11 {
 12 }
 13 
 14 void RoaTalkCallback::Login(RoaTalkUser::Ptr User)
 15 {
 16 }
 17 
 18 void RoaTalkCallback::Logout(RoaTalkUser::Ptr User)
 19 {
 20 }
 21 
 22 void RoaTalkCallback::Rename(VUnicodeString OldName , RoaTalkUser::Ptr User)
 23 {
 24 }
 25 
 26 /*********************************************************************************************************
 27 RoaTalkService
 28 *********************************************************************************************************/
 29 
 30 void RoaTalkService::Initialize()
 31 {
 32     FCallback=CreateCallbackObject<RoaTalkCallbackProxy>();
 33 }
 34 
 35 RoaTalkService::RoaTalkService()
 36 {
 37     FCallback=0;
 38     VInt i=1;
 39     while(true)
 40     {
 41         VUnicodeString Name=L"Guest "+VUnicodeString(i++);
 42         if(GetRoaTalkServer()->CreateUser(Name,this))
 43         {
 44             FName=Name;
 45             break;
 46         }
 47     }
 48 }
 49 
 50 RoaTalkService::~RoaTalkService()
 51 {
 52     GetRoaTalkServer()->DestroyUser(FName);
 53     delete FCallback;
 54 }
 55 
 56 RoaTalkCallback* RoaTalkService::GetCallback()
 57 {
 58     return FCallback;
 59 }
 60 
 61 VUnicodeString RoaTalkService::GetCurrentName()
 62 {
 63     return FName;
 64 }
 65 
 66 VBool RoaTalkService::SetCurrentName(VUnicodeString Name)
 67 {
 68     if(GetRoaTalkServer()->RenameUser(FName,Name))
 69     {
 70         FName=Name;
 71         return true;
 72     }
 73     else
 74     {
 75         return false;
 76     }
 77 }
 78 
 79 void RoaTalkService::Say(VUnicodeString Message)
 80 {
 81     GetRoaTalkServer()->Say(FName,Message);
 82 }
 83 
 84 VL_AutoPtr<RoaTalkUser::List> RoaTalkService::GetUsers()
 85 {
 86     return GetRoaTalkServer()->GetUsers();
 87 }
 88 
 89 /*********************************************************************************************************
 90 RoaTalkServer
 91 *********************************************************************************************************/
 92 
 93 RoaTalkServer::RoaTalkServer()
 94 {
 95 }
 96 
 97 RoaTalkServer::~RoaTalkServer()
 98 {
 99 }
100 
101 VBool RoaTalkServer::CreateUser(VUnicodeString Name , RoaTalkService* Service)
102 {
103     VBool Result=false;
104     FServerLock.Enter();
105     if(!FUsers.Exists(Name))
106     {
107         VL_AutoPtr<RoaTalkUser> Talker=new RoaTalkUser;
108         Talker->Name=Name;
109         Talker->Owner=Service;
110         FUsers.Add(Name,Talker);
111         Result=true;
112 
113         for(VInt i=0;i<FUsers.KeyCount();i++)
114         {
115             if(FUsers.KeyOfIndex(i)!=Name)
116             {
117                 try
118                 {
119                     FUsers.ValueOfIndex(i)->Owner->GetCallback()->Login(Talker);
120                 }
121                 catch()
122                 {
123                 }
124             }
125         }
126 
127         PrintNotify(Name+L" logged in.");
128     }
129     FServerLock.Leave();
130     return Result;
131 }
132 
133 VBool RoaTalkServer::DestroyUser(VUnicodeString Name)
134 {
135     VBool Result=false;
136     FServerLock.Enter();
137     if(FUsers.Exists(Name))
138     {
139         RoaTalkUser::Ptr Talker=FUsers[Name];
140         FUsers.Delete(Name);
141         Result=true;
142 
143         for(VInt i=0;i<FUsers.KeyCount();i++)
144         {
145             try
146             {
147                 FUsers.ValueOfIndex(i)->Owner->GetCallback()->Logout(Talker);
148             }
149             catch()
150             {
151             }
152         }
153 
154         PrintNotify(Name+L" logged out.");
155     }
156     FServerLock.Leave();
157     return Result;
158 }
159 
160 VBool RoaTalkServer::RenameUser(VUnicodeString OldName , VUnicodeString NewName)
161 {
162     VBool Result=false;
163     FServerLock.Enter();
164     if(FUsers.Exists(OldName) && !FUsers.Exists(NewName))
165     {
166         RoaTalkUser::Ptr Talker=FUsers[OldName];
167         FUsers.Delete(OldName);
168         Talker->Name=NewName;
169         FUsers.Add(NewName,Talker);
170         Result=true;
171 
172         for(VInt i=0;i<FUsers.KeyCount();i++)
173         {
174             if(FUsers.KeyOfIndex(i)!=NewName)
175             {
176                 try
177                 {
178                     FUsers.ValueOfIndex(i)->Owner->GetCallback()->Rename(OldName,Talker);
179                 }
180                 catch()
181                 {
182                 }
183             }
184         }
185 
186         PrintNotify(OldName+L" renamed to "+NewName+L".");
187     }
188     FServerLock.Leave();
189     return Result;
190 }
191 
192 VL_AutoPtr<RoaTalkUser::List> RoaTalkServer::GetUsers()
193 {
194     RoaTalkUser::List* Result=new RoaTalkUser::List();
195     FServerLock.Enter();
196     for(VInt i=0;i<FUsers.KeyCount();i++)
197     {
198         Result->Add(FUsers.ValueOfIndex(i));
199     }
200     FServerLock.Leave();
201     return Result;
202 }
203 
204 VBool RoaTalkServer::Say(VUnicodeString Name , VUnicodeString Message)
205 {
206     VBool Result=false;
207     FServerLock.Enter();
208     if(FUsers.Exists(Name))
209     {
210         RoaTalkUser::Ptr Talker=FUsers[Name];
211         Result=true;
212 
213         for(VInt i=0;i<FUsers.KeyCount();i++)
214         {
215             if(FUsers.KeyOfIndex(i)!=Name)
216             {
217                 try
218                 {
219                     FUsers.ValueOfIndex(i)->Owner->GetCallback()->Say(Talker,Message);
220                 }
221                 catch()
222                 {
223                 }
224             }
225         }
226 
227         PrintNotify(Name+L" says \""+Message+L"\".");
228     }
229     FServerLock.Leave();
230     return Result;
231 }
232 
233 /*********************************************************************************************************
234 工具函数
235 *********************************************************************************************************/
236 
237 RoaTalkServer* GlobalServer=0;
238 
239 void CreateRoaTalkServer()
240 {
241     GlobalServer=new RoaTalkServer;
242 }
243 
244 void DestroyRoaTalkServer()
245 {
246     delete GlobalServer;
247     GlobalServer=0;
248 }
249 
250 RoaTalkServer* GetRoaTalkServer()
251 {
252     return GlobalServer;
253 }
254 
255 /*********************************************************************************************************
256 注册
257 *********************************************************************************************************/
258 
259 VL_BEGIN_INSPECTOR_DECLARATION
260 
261     VL_BEGIN_INSPECTOR_MANAGER(RoaTalk)
262         VL_REGISTER_SERVICE_CLASSES
263 
264         VL_BIND_INSPECTOR(RoaTalkUser)
265         VL_BIND_INSPECTOR(RoaTalkCallback)
266         VL_BIND_INSPECTOR(RoaTalkService)
267     VL_END_INSPECTOR_MANAGER
268 
269 VL_END_INSPECTOR_DECLARATION

    接下来就剩下花边Feature了。使用这个东西可以开发一些C/S模式的程序,然后只需要将服务器和客户端看成同一个程序,将客户端认为是很多个线程就行了。服务器端提供一些类给客户端创建并使用,当这些服务类要求回调的时候,客户端只需要按照回调的接口实现回调,然后将指针提供给服务类就行了。剩下来的链接啊调度啊网络传输的问题就全部不用管了,非常方便。

相关内容
赞助商链接