}// end AnnounceToServer /// <summary> /// 客户端策略加载完毕将队伍名称通知给Server服务实例 /// </summary> /// <returns></returns> IEnumerator <ITask> AnnounceTeamNameToServer(string strTeamName) { // 使用Uri建立到Server服务实例主端口的Forwarder引用 server.Sim2DSvrOperations serverPort = ServiceForwarder <server.Sim2DSvrOperations>(_strServerUri); if (serverPort == null) { yield break; } // ClientAnnounceTeamName是Server服务主端口接受的一种消息类型 server.ClientAnnounceTeamName announce = new server.ClientAnnounceTeamName(); // 将队伍半场和队伍名字组成“队伍半场-队伍名字”的字符串,作为要发送到Server服务实例的信息 // 便于Server收到消息后判断该队伍名字是A队发来的还是B队发来的 //announce.Body = new server.ClientAnnounceTeamNameRequest(ServiceInfo.Service, _halfCourt + "-" + strTeamName); announce.Body = new server.ClientAnnounceTeamNameRequest(AlternateContractServiceInfo[0].Service, _teamId, strTeamName); serverPort.Post(announce); // 不关心消息发出后的结果,但最好等待一下消息发送后响应端口的返回信息 DefaultUpdateResponseType announceRsp = null; yield return(Arbiter.Choice(announce.ResponsePort, delegate(DefaultUpdateResponseType rsp) { announceRsp = rsp; }, delegate(Fault f) { //LogError("Announce failed, continue announcing", f); Console.WriteLine("Announce failed, continue announcing team name"); //added 20110117 WinFormsServicePort.FormInvoke(delegate() { _clientControlBoard.DisplayCompetitionState(string.Format("Connection failed")); }); SpawnIterator <string>(_teamName, AnnounceTeamNameToServer); } )); if (announceRsp == null) { yield break; } }// end AnnounceToServer
}// end AnnounceToServer /// <summary> /// 当Client用户界面的Ready按钮按下之后,通知Server服务实例该队已经准备完毕。 /// </summary> /// <returns></returns> IEnumerator <ITask> AnnounceReadyToServer() { // 每次重新Ready的时候清除策略调用异常标志 LiYoubing 20110712 //_strategyExceptionFlag = false; // 使用Uri建立到Server服务实例主端口的Forwarder引用 server.Sim2DSvrOperations serverPort = ServiceForwarder <server.Sim2DSvrOperations>(_strServerUri); if (serverPort == null) { yield break; } _isReady = true; // ClientAnnounceReady是Server服务主端口接受的一种消息类型 server.ClientAnnounceReady announce = new server.ClientAnnounceReady(); announce.Body = new server.ClientAnnounceReadyRequest(_teamId); serverPort.Post(announce); // 不关心消息发出后的结果,但最好等待一下消息发送后响应端口的返回信息 DefaultUpdateResponseType announceRsp = null; yield return(Arbiter.Choice(announce.ResponsePort, delegate(DefaultUpdateResponseType rsp) { announceRsp = rsp; }, delegate(Fault f) { //LogError("Announce failed, continue announcing", f); Console.WriteLine("Announce failed, continue announcing ready"); SpawnIterator(AnnounceReadyToServer); } )); if (announceRsp == null) { yield break; } }// end AnnounceReadyToServer
// LiYoubing 20110712 加入策略调用异常处理 /// <summary> /// 指示是否已经发生过策略调用异常true是false否 /// 20110820废弃 策略代码中存在条件性除零/数组越界等异常时 不必要直接结束掉策略运行 /// </summary> //bool _strategyExceptionFlag = false; //20101229 /// <summary> /// 向Server服务实例发送决策计算结果 /// 决策算法的调用过程在此 /// </summary> /// <param name="announce">包含仿真使命Mission对象的消息</param> /// <returns></returns> IEnumerator <ITask> AnnounceDecisionToServer(server.MissionPara announce) { if (_clientControlBoard.StragegyInterface == null /*|| _strategyExceptionFlag == true*/) {// 加上null检查确保程序不会异常 LiYoubing 20110511 yield break; } // ClientAnnounceDecision是Server服务主端口接受的一种消息类型 client.ClientAnnounceDecision announcedec = new client.ClientAnnounceDecision(); Decision[] decisions = null; try { // 交换半场后交换队伍id处理 LiYoubing 20110712 // 交换半场后TeamsRef[0]/[1]代表交换前右/左半场的队伍因此teamId应该分别变为1/0 //int strategyId = announce.Body.CurMission.CommonPara.IsExchangedHalfCourt ? (_teamId + 1) % 2 : _teamId; int strategyId = _teamId; if (announce.Body.CurMission.CommonPara.TeamCount == 2) {// 跟踪有且仅有两支队伍参与的仿真使命的半场状态 LiYoubing 20120520 strategyId = announce.Body.CurMission.CommonPara.IsExchangedHalfCourt ? (_teamId + 1) % 2 : _teamId; bool rdoLeftChecked = (announce.Body.CurMission.TeamsRef[strategyId].Para.MyHalfCourt == HalfCourt.LEFT) ? true : false; WinFormsServicePort.FormInvoke(delegate() { _clientControlBoard.SetRadioTeamState(rdoLeftChecked, !rdoLeftChecked, announce.Body.CurMission.TeamsRef[strategyId].Fishes[0].ColorFish); }); } decisions = _clientControlBoard.StragegyInterface.GetDecision(announce.Body.CurMission, strategyId); //decisions = _clientControlBoard.StragegyInterface.GetDecision(announce.Body.CurMission, _teamId); } catch { //_strategyExceptionFlag = true; MessageBox.Show("Remoting object timeout.\nThe instance of class Strategy has been released.\n" + "Your simulated robofish will not be controlled.", "Confirming", MessageBoxButtons.OK, MessageBoxIcon.Warning); } if (decisions == null) { yield break; } announcedec.Body = new client.ClientAnnounceDecisionRequest(decisions, _teamId); // 使用Uri建立到Server服务实例附加端口的Forwarder引用 client.ClientBaseOperations alternateServerPort = ServiceForwarder <client.ClientBaseOperations>(_alternateServerPortUri); if (alternateServerPort != null) { alternateServerPort.Post(announcedec); DefaultUpdateResponseType announceRsp = null; yield return(Arbiter.Choice(announce.ResponsePort, delegate(DefaultUpdateResponseType rsp) { announceRsp = rsp; }, delegate(Fault f) { WinFormsServicePort.FormInvoke(delegate() { _clientControlBoard.DisplayCompetitionState(string.Format("Connection failed")); }); })); } yield break; }
/// <summary> /// Writes a binary file from a stream to the mount service /// </summary> /// <param name="filename">Filename and path where the file shall be store on the mount service</param> /// <param name="fileStream">Stream containing the file data</param> /// <param name="responsePort">File writer response port</param> /// <returns></returns> private IEnumerator <ITask> WriteFileToMountService( string filename, Stream fileStream, SuccessFailurePort responsePort) { // Stream needs to support seeking, otherwise we will never know when the end // is reached if (!fileStream.CanSeek) { throw new ArgumentException("File stream needs to support seeking"); } // Construct URI to file string fileUri = "http://localhost" + ServicePaths.MountPoint; if (!filename.StartsWith("/")) { fileUri += "/"; } fileUri += filename; // Establish channel with mount service mnt.MountServiceOperations mountPort = ServiceForwarder <mnt.MountServiceOperations>(fileUri); // Set up byte update message mnt.UpdateBytesRequest updateBytesRequest = new mnt.UpdateBytesRequest(); mnt.UpdateBytes updateBytes = new mnt.UpdateBytes(updateBytesRequest); updateBytesRequest.Offset = 0; updateBytesRequest.Truncate = false; // Write file in blocks to mount service updateBytesRequest.Data = new byte[MountServiceWriteBlockSize]; fileStream.Position = 0; int writeOffset = 0; while (fileStream.Position < fileStream.Length) { // Fill buffer int offset = 0; while (offset < MountServiceWriteBlockSize && fileStream.Position < fileStream.Length) { int bytesRead = fileStream.Read( updateBytesRequest.Data, offset, MountServiceWriteBlockSize - offset ); offset += bytesRead; } if (offset < MountServiceWriteBlockSize) { // Last message will most probably not contain a completely filled buffer Array.Resize <byte>(ref updateBytesRequest.Data, offset); } if (fileStream.Position >= fileStream.Length) { // End of stream reached, truncate file on mount service // to current position updateBytesRequest.Truncate = true; } updateBytesRequest.Offset = writeOffset; // Send message to mount service mountPort.Post(updateBytes); yield return((Choice)updateBytes.ResponsePort); Fault fault = (Fault)updateBytes.ResponsePort; if (fault != null) { Exception exception = fault.ToException(); LogWarning(exception); responsePort.Post(exception); yield break; } // Clear response port DefaultUpdateResponseType success = (DefaultUpdateResponseType)updateBytes.ResponsePort; writeOffset += updateBytesRequest.Data.Length; } responsePort.Post(SuccessResult.Instance); }