Silverlight+WCF 新手实例 象棋 房间状态更新(二十)
2014-06-05 00:00
627 查看
在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示
这节开始,标题里就去掉"回归WCF通讯应用"几字了。
上节我们成功实现了进入房间,服务端也收到用户进入房间的请求了,这节,我们服务端收到进入房间请求后,通知在房间大门外的人更新房间状态。
我们要增加一个回调方法,ICallBack接口那,忘记的人回去看看WCF通讯那几篇(十四到十七节)。
方法如下,以前说过了,回调的方法是给客户端实现的,服务端只管调就行了:
using
System.ServiceModel;
namespace
GameService
{
interface
ICallBack
{
[OperationContract(IsOneWay
=
true
)]
void
NotifyRoomUpdate(Room room);
}
}
那我们回到服务端进入房间的代码,只管调用一下了:
我们看下这段进入房间代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
public
bool
EnterRoom(Player player,
int
roomID)
{
bool
roomInDic
=
roomList.ContainsKey(roomID);
//
房间列表里有没有
Room room
=
roomInDic
?
roomList[roomID] :
new
Room();
//
有就直接拿了,没有就直接New一个新的
if
(
!
room.RedInChair)
//
房间的红色座位有没有人
{
room.RedInChair
=
player.ColorValue
==
1
;
}
if
(
!
room.BlackInChair)
//
房间的黑色座位有没有人
{
room.BlackInChair
=
player.ColorValue
==
2
;
}
if
(
!
roomInDic)
//
房间列表里没有,添加到房间列表中
{
room.ID
=
roomID;
roomList.Add(roomID, room);
}
ChangeRoom(player, roomID);
//
改变玩家的房间标记,待会实现
//
这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
foreach
(KeyValuePair
<
Guid,Player
>
item
in
playerList[
0
])
{
item.Value.CallBack.NotifyRoomUpdate(room);
}
return
true
;
}
foreach之前的代码是上节的了,这里我们只增加了一个foreach来循环0房间的用户,通知他们更新房间状态。
同样的,如果是退出房间,也要加一个foreach,代码如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
public
void
OutRoom(Player player,
int
roomID)
{
if
(roomID
>
0
)
{
Room room
=
roomList[roomID];
if
(player.ColorValue
==
1
)
//
如果退出玩家是红色座位
{
room.RedInChair
=
false
;
}
if
(player.ColorValue
==
2
)
//
如果退出玩家是红色黑色座位
{
room.BlackInChair
=
false
;
}
ChangeRoom(player,
0
);
//
改变玩家的房间标记,待会实现
//
这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
foreach
(KeyValuePair
<
Guid, Player
>
item
in
playerList[
0
])
{
item.Value.CallBack.NotifyRoomUpdate(room);
}
}
}
当我们看到同样的代码循环重复的出现的时候,我们会感到皮痒,我们得把它封装起来,弄成一个小函数调用。
于是,我新建了一个Notify通知类。用于把所有的通知都集成到这里来。
皮痒了,GameService项目里新建一个类[示例源代码里会放到一个文件夹Notify下]:
namespace
GameService
{
///
<summary>
///
通知 by 路过秋天
///
</summary>
public
class
Notify
{
}
}
我们添加一个新方法,叫Room, 我们把那foreach的方法Copy过来,就是如下代码了:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
namespace
GameService
{
///
<summary>
///
通知 by 路过秋天
///
</summary>
public
class
Notify
{
internal
static
void
Room(Dictionary
<
int
, Dictionary
<
Guid, Player
>>
playerList, Room room)
{
//
这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
foreach
(KeyValuePair
<
Guid, Player
>
item
in
playerList[
0
])
{
item.Value.CallBack.NotifyRoomUpdate(room);
}
}
}
}
有了这个,我们回去把房间进入的和退出的foreach都改成Notify.Room(playerList,room);就OK了。
大伙自己改了,这里不再贴代码出来了。
成了,服务端写完了,那客户端要实现回调的方法的,我们编绎一下GameService项目,不编绎是不行的,我们加了接口,
客户端得“更新服务引用”,
怎么更新?以前截过图的,回去看上一节:Silverlight+WCF 新手实例 象棋 回归WCF通讯应用-进入房间(十九)。
好了,回客户端了,回哪?当然回到Room.xmal那了,我们要更新房间的状态的。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
namespace
NewChessProject
{
public
partial
class
Room : UserControl
{
public
Room()
{
InitializeComponent();
Game game
=
new
Game();
game.CreateGameRoom(
30
);
game.DrawIn(LayoutRoot);
//
这里实现ICallBack的方法
App.client.NotifyRoomUpdateReceived
+=
new
EventHandler
<
GameService.NotifyRoomUpdateReceivedEventArgs
>
(client_NotifyRoomUpdateReceived);
}
void
client_NotifyRoomUpdateReceived(
object
sender, GameService.NotifyRoomUpdateReceivedEventArgs e)
{
//
看这里看这里,这里实现啦
}
}
}
这里等待服务端调用时,执行的方法了,现在实现了。
嘿嘿,皮又痒了,三行的代码,又封装出一个UpdateRoomState方法来了。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
void
client_NotifyRoomUpdateReceived(
object
sender, GameService.NotifyRoomUpdateReceivedEventArgs e)
{
//
这里实现啦
if
(game.GameRoomList
!=
null
&&
e.room
!=
null
)
{
UpdateRoomState(e.room, game.GameRoomList[e.room.ID
-
1
]);
}
}
void
UpdateRoomState(GameService.Room gsRoom, GameRoom room)
{
room.RedPlayerInChair
=
gsRoom.RedInChair;
room.BlackPlayerInChair
=
gsRoom.BlackInChair;
room.ReDraw();
}
最后还调用了room的ReDraw()方法。咦?room是没这个方法的,没有就加,咦什么咦。
回到GameRoom.cs里去,加个ReDraw方法,就两行代码了,大伙别急:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
public
void
ReDraw()
{
redChair.Fill
=
new
RadialGradientBrush(RedPlayerInChair
?
Colors.Blue : Colors.Red, Colors.Transparent);
blackChair.Fill
=
new
RadialGradientBrush(BlackPlayerInChair
?
Colors.Blue : Colors.Black, Colors.Transparent);
}
OK,客户端写完了,我们F5运行看结果:
启动一个浏览器,登陆后我们不动,同时复制地址,新开一个浏览器,也登陆进去如下图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/8be2cb0da9fb6cb5a010808580a7746e.jpg)
好,我们点击第二个浏览器进去第一个红色房间:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/4992815b46e9075dac6bd2b13ba608c8.jpg)
看,第一个房间的状态变了。至此,我们顺利完成了房间状态的通知更新。
那退出房间哪去了?别急,Index页面还没东西呢。
这节开始,标题里就去掉"回归WCF通讯应用"几字了。
上节我们成功实现了进入房间,服务端也收到用户进入房间的请求了,这节,我们服务端收到进入房间请求后,通知在房间大门外的人更新房间状态。
我们要增加一个回调方法,ICallBack接口那,忘记的人回去看看WCF通讯那几篇(十四到十七节)。
方法如下,以前说过了,回调的方法是给客户端实现的,服务端只管调就行了:
using
System.ServiceModel;
namespace
GameService
{
interface
ICallBack
{
[OperationContract(IsOneWay
=
true
)]
void
NotifyRoomUpdate(Room room);
}
}
那我们回到服务端进入房间的代码,只管调用一下了:
我们看下这段进入房间代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
public
bool
EnterRoom(Player player,
int
roomID)
{
bool
roomInDic
=
roomList.ContainsKey(roomID);
//
房间列表里有没有
Room room
=
roomInDic
?
roomList[roomID] :
new
Room();
//
有就直接拿了,没有就直接New一个新的
if
(
!
room.RedInChair)
//
房间的红色座位有没有人
{
room.RedInChair
=
player.ColorValue
==
1
;
}
if
(
!
room.BlackInChair)
//
房间的黑色座位有没有人
{
room.BlackInChair
=
player.ColorValue
==
2
;
}
if
(
!
roomInDic)
//
房间列表里没有,添加到房间列表中
{
room.ID
=
roomID;
roomList.Add(roomID, room);
}
ChangeRoom(player, roomID);
//
改变玩家的房间标记,待会实现
//
这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
foreach
(KeyValuePair
<
Guid,Player
>
item
in
playerList[
0
])
{
item.Value.CallBack.NotifyRoomUpdate(room);
}
return
true
;
}
foreach之前的代码是上节的了,这里我们只增加了一个foreach来循环0房间的用户,通知他们更新房间状态。
同样的,如果是退出房间,也要加一个foreach,代码如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
public
void
OutRoom(Player player,
int
roomID)
{
if
(roomID
>
0
)
{
Room room
=
roomList[roomID];
if
(player.ColorValue
==
1
)
//
如果退出玩家是红色座位
{
room.RedInChair
=
false
;
}
if
(player.ColorValue
==
2
)
//
如果退出玩家是红色黑色座位
{
room.BlackInChair
=
false
;
}
ChangeRoom(player,
0
);
//
改变玩家的房间标记,待会实现
//
这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
foreach
(KeyValuePair
<
Guid, Player
>
item
in
playerList[
0
])
{
item.Value.CallBack.NotifyRoomUpdate(room);
}
}
}
当我们看到同样的代码循环重复的出现的时候,我们会感到皮痒,我们得把它封装起来,弄成一个小函数调用。
于是,我新建了一个Notify通知类。用于把所有的通知都集成到这里来。
皮痒了,GameService项目里新建一个类[示例源代码里会放到一个文件夹Notify下]:
namespace
GameService
{
///
<summary>
///
通知 by 路过秋天
///
</summary>
public
class
Notify
{
}
}
我们添加一个新方法,叫Room, 我们把那foreach的方法Copy过来,就是如下代码了:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
namespace
GameService
{
///
<summary>
///
通知 by 路过秋天
///
</summary>
public
class
Notify
{
internal
static
void
Room(Dictionary
<
int
, Dictionary
<
Guid, Player
>>
playerList, Room room)
{
//
这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
foreach
(KeyValuePair
<
Guid, Player
>
item
in
playerList[
0
])
{
item.Value.CallBack.NotifyRoomUpdate(room);
}
}
}
}
有了这个,我们回去把房间进入的和退出的foreach都改成Notify.Room(playerList,room);就OK了。
大伙自己改了,这里不再贴代码出来了。
成了,服务端写完了,那客户端要实现回调的方法的,我们编绎一下GameService项目,不编绎是不行的,我们加了接口,
客户端得“更新服务引用”,
怎么更新?以前截过图的,回去看上一节:Silverlight+WCF 新手实例 象棋 回归WCF通讯应用-进入房间(十九)。
好了,回客户端了,回哪?当然回到Room.xmal那了,我们要更新房间的状态的。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
namespace
NewChessProject
{
public
partial
class
Room : UserControl
{
public
Room()
{
InitializeComponent();
Game game
=
new
Game();
game.CreateGameRoom(
30
);
game.DrawIn(LayoutRoot);
//
这里实现ICallBack的方法
App.client.NotifyRoomUpdateReceived
+=
new
EventHandler
<
GameService.NotifyRoomUpdateReceivedEventArgs
>
(client_NotifyRoomUpdateReceived);
}
void
client_NotifyRoomUpdateReceived(
object
sender, GameService.NotifyRoomUpdateReceivedEventArgs e)
{
//
看这里看这里,这里实现啦
}
}
}
这里等待服务端调用时,执行的方法了,现在实现了。
嘿嘿,皮又痒了,三行的代码,又封装出一个UpdateRoomState方法来了。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
void
client_NotifyRoomUpdateReceived(
object
sender, GameService.NotifyRoomUpdateReceivedEventArgs e)
{
//
这里实现啦
if
(game.GameRoomList
!=
null
&&
e.room
!=
null
)
{
UpdateRoomState(e.room, game.GameRoomList[e.room.ID
-
1
]);
}
}
void
UpdateRoomState(GameService.Room gsRoom, GameRoom room)
{
room.RedPlayerInChair
=
gsRoom.RedInChair;
room.BlackPlayerInChair
=
gsRoom.BlackInChair;
room.ReDraw();
}
最后还调用了room的ReDraw()方法。咦?room是没这个方法的,没有就加,咦什么咦。
回到GameRoom.cs里去,加个ReDraw方法,就两行代码了,大伙别急:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/1726979b8c91fd873926bf4c9d2d53b8.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/5a31eda0f0c962d7a836eb90780946da.gif)
public
void
ReDraw()
{
redChair.Fill
=
new
RadialGradientBrush(RedPlayerInChair
?
Colors.Blue : Colors.Red, Colors.Transparent);
blackChair.Fill
=
new
RadialGradientBrush(BlackPlayerInChair
?
Colors.Blue : Colors.Black, Colors.Transparent);
}
OK,客户端写完了,我们F5运行看结果:
启动一个浏览器,登陆后我们不动,同时复制地址,新开一个浏览器,也登陆进去如下图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/8be2cb0da9fb6cb5a010808580a7746e.jpg)
好,我们点击第二个浏览器进去第一个红色房间:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/09/4992815b46e9075dac6bd2b13ba608c8.jpg)
看,第一个房间的状态变了。至此,我们顺利完成了房间状态的通知更新。
那退出房间哪去了?别急,Index页面还没东西呢。
相关文章推荐
- Silverlight+WCF 新手实例 象棋 房间状态更新(二十)
- Silverlight+WCF 新手实例 象棋 房间状态更新(二十)
- Silverlight+WCF 新手实例 象棋 房间状态更新(二十)
- Silverlight+WCF 新手实例 象棋 获取房间状态列表更新(二十一)
- Silverlight+WCF 新手实例 象棋 获取房间状态列表更新(二十一)
- Silverlight+WCF 新手实例 象棋 获取房间状态列表更新(二十一)
- Silverlight+WCF 新手实例 象棋 获取房间状态列表更新(二十一)
- Silverlight+WCF 新手实例 象棋 主界面-状态重置(三十四)
- Silverlight+WCF 新手实例 象棋 游戏房间列表(十三)
- Silverlight+WCF 新手实例 象棋 主界面-状态重置(三十四)
- Silverlight+WCF 新手实例 象棋 回归WCF通讯应用-进入房间(十九)
- Silverlight+WCF 新手实例 象棋 主界面-状态重置(三十四)
- Silverlight+WCF 新手实例 象棋 游戏房间(十二)
- Silverlight+WCF 新手实例 象棋 游戏房间(十二)
- Silverlight+WCF 新手实例 象棋 回归WCF通讯应用-进入房间(十九)
- Silverlight+WCF 新手实例 象棋 回归WCF通讯应用-进入房间(十九)
- Silverlight+WCF 新手实例 象棋 主界面-状态重置(三十四)
- Silverlight+WCF 新手实例 象棋 回归WCF通讯应用-进入房间(十九)
- Silverlight+WCF 新手实例 象棋 游戏房间列表(十三)
- Silverlight+WCF 新手实例 象棋 游戏房间(十二)