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);
}