用ICE实现一个简单的聊天室
聊天室是一种典型的网络应用,这个程序演示了ICE框架的基本结构。
1)定义SLICE接口。
module Chat {
interface
MessageReceiver {
void
onMessage(
string
sender,
string
msg);
};
dictionary
<
string
, MessageReceiver
*>
UserList;
interface
Room {
bool
login(
string
user, MessageReceiver
*
receiver);
void
logout(
string
user);
void
sendMessage(
string
user,
string
message);
};
};
定义两个接口,Room用于服务器端实现,MessageReceiver用于客户端实现。
使用slice2cpp生成C++文件: chat.h, chat.cpp.
2)服务器端实现。
#include
<
iostream
>
#include
<
Ice
/
Ice.h
>
#include
"
chat.h
"
using
std::
string
;
class
ChatRoomI :
public
Chat::Room {
public
:
virtual
bool
login(
const
string
&
,
const
Chat::MessageReceiverPrx
&
,
const
Ice::Current
&
);
virtual
void
logout(
const
string
&
,
const
Ice::Current
&
);
virtual
void
sendMessage(
const
string
&
,
const
string
&
,
const
Ice::Current
&
);
private
:
void
broadcast(
const
string
&
user,
const
string
&
message);
bool
notify(
const
Chat::MessageReceiverPrx
&
receiver,
const
string
&
sender,
const
string
&
message);
Chat::UserList users_;
};
bool
ChatRoomI::login(
const
string
&
user,
const
Chat::MessageReceiverPrx
&
receiver,
const
Ice::Current
&
) {
if
(users_.find(user)
!=
users_.end()) {
return
false
;
}
users_.insert(Chat::UserList::value_type(user, receiver));
broadcast(user,
"
---login---
"
);
return
true
;
}
void
ChatRoomI::logout(
const
string
&
user,
const
Ice::Current
&
) {
users_.erase(user);
broadcast(user,
"
===logout===
"
);
}
void
ChatRoomI::sendMessage(
const
string
&
user,
const
string
&
message,
const
Ice::Current
&
) {
broadcast(user, message);
}
void
ChatRoomI::broadcast(
const
string
&
user,
const
string
&
message) {
Chat::UserList::iterator it
=
users_.begin(), end
=
users_.end();
while
(it
!=
end) {
if
(user
!=
it
->
first
&&
!
notify(it
->
second, it
->
first, message))
users_.erase(it
++
);
else
++
it;
}
}
bool
ChatRoomI::notify(
const
Chat::MessageReceiverPrx
&
receiver,
const
string
&
sender,
const
string
&
message) {
bool
ret
=
true
;
try
{
receiver
->
onMessage(sender, message);
}
catch
(
const
std::exception
&
ex) {
ret
=
false
;
}
return
ret;
}
class
Server :
public
Ice::Application {
public
:
virtual
int
run(
int
argc,
char
*
argv[]) {
Ice::ObjectAdapterPtr adapter
=
communicator()
->
createObjectAdapterWithEndpoints(
"
Chat.RoomAdapter
"
,
"
default -p 10000
"
);
Chat::RoomPtr room
=
new
ChatRoomI;
adapter
->
add(room, communicator()
->
stringToIdentity(
"
Chat.Room
"
));
adapter
->
activate();
communicator()
->
waitForShutdown();
return
0
;
}
};
int
main(
int
argc,
char
*
argv[]) {
Server app;
return
app.main(argc, argv);
}
3)客户端实现。
#include <iostream>
#include <Ice/Ice.h>
#include "chat.h"
using std::string;
class ChatUserI : public Chat::MessageReceiver {
public:
virtual void onMessage(const string& user, const string& message, const Ice::Current&) {
std::cout << user << " : " << message << std::endl;
}
};
class Client : public Ice::Application {
public:
virtual int run(int argc, char* argv[]) {
Chat::RoomPrx chatRoom = Chat::RoomPrx::checkedCast(
communicator()->stringToProxy("Chat.Room:default -p 10000"));
if (!chatRoom) {
std::cout << "Proxy not existed!\n";
return -1;
}
Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapterWithEndpoints(
"Chat.UserAdapter", "default");
Chat::MessageReceiverPtr user = new ChatUserI;
adapter->add(user, communicator()->stringToIdentity("Chat.User"));
adapter->activate();
Chat::MessageReceiverPrx userPrx = Chat::MessageReceiverPrx::uncheckedCast(
adapter->createProxy(communicator()->stringToIdentity("Chat.User")));
string name;
std::cout << "Please input user name: ";
std::cin >> name;
if (!chatRoom->login(name, userPrx)) {
std::cout << "login error: User Name already exist!\n";
return 0;
}
std::cout << "login OK!" << std::endl;
string message;
while (std::getline(std::cin, message) && message != "quit") {
chatRoom->sendMessage(name, message);
}
chatRoom->logout(name);
return 0;
}
};
int main(int argc, char* argv[]) {
Client app;
return app.main(argc, argv);
}