本文介绍了如何利用WCF和callback机制开发一个简单的多人在线游戏模型。
运行过程如下:
当game service 启动之后,若干个客户端便会自动连接到服务器。当某个客户端点击join game时,所有客户端同时更新。
运行screenshot如下图所示:
WCF service screenshot

client1 screenshot:

client2 screenshot:

WCF service主要代码如下:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.ServiceModel;
namespace
GameService
{
public
class
PlayerEventAgrs : EventArgs
{
public
Player player;
public
GameDesk desk;
}
[ServiceBehavior(InstanceContextMode
=
InstanceContextMode.PerSession)]
class
GameService:IGameService
{
static
List
<
Player
>
Players
=
new
List
<
Player
>
();
public
delegate
void
PlayerEventHandler(
object
sender, PlayerEventAgrs e);
public
static
event
PlayerEventHandler OnJoinGame;
public
static
event
PlayerEventHandler OnStartGame;
public
IPlayerCallBack callback;
public
GameService()
{
callback
=
System.ServiceModel.OperationContext.Current.GetCallbackChannel
<
IPlayerCallBack
>
();
OnJoinGame
+=
new
PlayerEventHandler(GameService_OnJoinGame);
OnStartGame
+=
new
PlayerEventHandler(GameService_OnStartGame);
}
public
List
<
Player
>
GetPlayerList()
{
System.Threading.Thread.Sleep(
4000
);
return
Players;
}
void
GameService_OnJoinGame(
object
sender, PlayerEventAgrs e)
{
Console.WriteLine(
"
{0} is joining the game on desk NO {1}
"
, e.player.PlayerName, e.desk.DeskNo);
callback.OnJoin(e.player,e.desk);
}
void
GameService_OnStartGame(
object
sender, PlayerEventAgrs e)
{
callback.OnStart(e.player);
}
public
void
BroadGameEvent(PlayerEventAgrs e, PlayerEventHandler temp)
{
if
(OnJoinGame
!=
null
)
{
foreach
(PlayerEventHandler handler
in
temp.GetInvocationList())
{
handler.BeginInvoke(
this
, e,
null
,
null
);
}
}
}
public
void
JoinToGame(Player player,GameDesk desk)
{
Players.Add(player);
PlayerEventAgrs e
=
new
PlayerEventAgrs();
e.player
=
player;
e.player.PositionNO
=
desk;
e.desk
=
desk;
BroadGameEvent(e, OnJoinGame);
}
public
void
StartGame(Player player)
{
PlayerEventAgrs e
=
new
PlayerEventAgrs();
e.player
=
player;
BroadGameEvent(e, OnStartGame);
}
}
}
callback interface如下:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.ServiceModel;
using
System.Runtime.Serialization;
namespace
GameService
{
[ServiceContract]
public
interface
IPlayerCallBack
{
[OperationContract(IsOneWay
=
true
)]
void
OnJoin(Player player,GameDesk gamedesk);
[OperationContract(IsOneWay
=
true
)]
void
OnStart(Player player);
}
}
客户端callback implementation如下:
#region
CallBack Implementation
public
void
OnJoin(GameService.Player player, GameService.GameDesk desk)
{
int
deskNo
=
desk.DeskNo;
StringBuilder show
=
new
StringBuilder();;
show.AppendFormat(
"
Player Information\n
"
);
show.AppendFormat(
"
Player Name:{0}\n
"
, player.PlayerName);
show.AppendFormat(
"
Player Status: {0}\n
"
,player.Action);
show.AppendFormat(
"
Player Role: {0}\n
"
, player.Role);
img_Desktop.Image
=
new
System.Drawing.Bitmap(System.Drawing.Image.FromFile(
@"
image\active-desktop.bmp
"
));
switch
(deskNo)
{
case
1
:
lb_PlayerInfo1.Text
=
show.ToString();
lb_PlayerInfo1.Refresh();
pic_Player1.Image
=
new
System.Drawing.Bitmap(System.Drawing.Image.FromFile(
@"
image\acvite-icon.bmp
"
));
break
;
case
2
:
lb_PlayerInfo2.Text
=
show.ToString();
pic_Player2.Image
=
new
System.Drawing.Bitmap(System.Drawing.Image.FromFile(
@"
image\acvite-icon.bmp
"
));
break
;
case
3
:
lb_PlayerInfo3.Text
=
show.ToString();
pic_Player3.Image
=
new
System.Drawing.Bitmap(System.Drawing.Image.FromFile(
@"
image\acvite-icon.bmp
"
));
break
;
}
}
public
void
OnStart(GameService.Player player)
{
}
#endregion
有关本文完整源代码,请点击此处下载