Silverlight+WCF 新手实例 象棋 房间状态更新(二十)

Silverlight+WCF 新手实例 象棋 房间状态更新(二十),第1张

概述在线演示地址: Silverlight+WCF 新手实例 象棋 在线演示   这节开始,标题里就去掉"回归WCF通讯应用"几字了。   上节我们成功实现了进入房间,服务端也收到用户进入房间的请求了,这节,我们服务端收到进入房间请求后,通知在房间大门外的人更新房间状态。 我们要增加一个回调方法,ICallBack接口那,忘记的人回去看看WCF通讯那几篇(十四到十七节)。 方法如下,以前说过了,回调的 在线演示地址: Silverlight+WCF 新手实例 象棋 在线演示

 

这节开始,标题里就去掉"回归WCF通讯应用"几字了。

 

上节我们成功实现了进入房间,服务端也收到用户进入房间的请求了,这节,我们服务端收到进入房间请求后,通知在房间大门外的人更新房间状态。

我们要增加一个回调方法,ICallBack接口那,忘记的人回去看看WCF通讯那几篇(十四到十七节)。

方法如下,以前说过了,回调的方法是给客户端实现的,服务端只管调就行了:

@H_419_20@ using  System.ServiceModel;

namespace  GameService
{
    
interface  ICallBack
    {
        [OperationContract(IsOneWay 
=   true )]
        
voID  NotifyRoomUpdate(Room room);
    }
}

 

那我们回到服务端进入房间的代码,只管调用一下了:

我们看下这段进入房间代码:

  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,代码如下:

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下]:

@H_419_20@ namespace  GameService
{
    
///   <summary>
    
///  通知 by 路过秋天
    
///   </summary>
     public   class  Notify
    {

    }
}

 

我们添加一个新方法,叫Room,我们把那foreach的方法copy过来,就是如下代码了:

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那了,我们要更新房间的状态的。

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方法来了。

  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方法,就两行代码了,大伙别急:

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运行看结果:

启动一个浏览器,登陆后我们不动,同时复制地址,新开一个浏览器,也登陆进去如下图:

好,我们点击第二个浏览器进去第一个红色房间:

看,第一个房间的状态变了。至此,我们顺利完成了房间状态的通知更新。

那退出房间哪去了?别急,Index页面还没东西呢。

总结

以上是内存溢出为你收集整理的Silverlight+WCF 新手实例 象棋 房间状态更新(二十)全部内容,希望文章能够帮你解决Silverlight+WCF 新手实例 象棋 房间状态更新(二十)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1009184.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存