//路径执行到下一个节点 private static string PathNextRequest(string plugin, string controller, string method, string jsondata, HeaderParameter para) { string retJson = null; try { para.NodePath.NextStep(); //节点路径下一步 if (para.NodePath.IsEndMNode) //到达终节点 { //执行本地数据请求 retJson = LocalDataRequest(plugin, controller, method, jsondata, para); } else if (para.NodePath.nextMNodeDirection == "<up>")//向上 { ClientLink clientlink = SuperClient.CreateDataClient(); using (var scope = new OperationContextScope(clientlink.ClientObj.WcfService.InnerDuplexChannel as IContextChannel)) { HeaderOperater.AddMessageHeader(OperationContext.Current.OutgoingMessageHeaders, para); retJson = clientlink.ClientObj.WcfService.ProcessRequest(clientlink.ClientObj.ClientID, plugin, controller, method, jsondata); } } else if (para.NodePath.nextMNodeDirection == "<down>")//向下 { IDataReply dataReply = SuperClient.CreateDataReply(para.NodePath.nextMNode); retJson = dataReply.ReplyProcessRequest(para, plugin, controller, method, jsondata); } return(retJson); } catch (Exception err) { throw err; } }
public string ProcessHttpRequest(RequestArgs requestArgs) { MiddlewareLogHelper.WriterLog(LogType.MidLog, true, Color.Blue, "接受Http请求:" + requestArgs.ToString()); //获取的池子索引 int? index = null; ClientLink clientlink = null; ClientLinkPool pool = fromPoolGetClientLink(requestArgs.plugin, out clientlink, out index); ServiceResponseData retData = new ServiceResponseData(); try { //绑定LoginRight Action <ClientRequestData> _requestAction = ((ClientRequestData request) => { request.LoginRight = requestArgs.sysright; request.SetJsonData(requestArgs.jsondata); }); retData = clientlink.Request(requestArgs.controller, requestArgs.method, _requestAction); } catch (Exception ex) { throw ex; } finally { if (index != null) { pool.ReturnPool(requestArgs.plugin, (int)index); } } return(retData.GetJsonData()); }
//下载升级包 public static void DownLoadUpgrade(string updatexml, string updatezip, ClientLink _clientLink) { try { //1.查询本地的update.xml配置文件 //2.如果不存在则直接下载 //3.如果存在则下载中心update.xml配置文件 //4.比对两个版本的大小 //5.如果本地版本小则直接下载,大则放弃下载 FileInfo finfo = new FileInfo(rootpath + updatexml); if (finfo.Exists == false)//本地不存在,直接下载 { File.Delete(updatexml); File.Delete(updatezip); downloadRemoteFile(updatexml, updatezip, _clientLink); } else//本地存在升级包文件 { Version localver = readLocalUpdateXml(updatexml); Version remotever = getRemoteUpdateXml(updatexml, _clientLink); int tm = localver.CompareTo(remotever); if (tm < 0)//本地版本小 { File.Delete(updatexml); File.Delete(updatezip); downloadRemoteFile(updatexml, updatezip, _clientLink); } } } catch (Exception err) { CoreFrame.Common.MiddlewareLogHelper.WriterLog(err.Message + err.StackTrace); } }
/// <summary> /// 启动连接 /// </summary> /// <returns></returns> public static bool Start() { try { ClientDispatcher.SetLoger(new ServerLinkLoger()); DictServerLinkGame.Clear(); DictServerLinkLogin.Clear(); foreach (var conf in Conf.SysServerList.Values) { if (conf.ServerType == (int)EServerType.游戏) { var client = new ClientLink(); client.Setup(ConstsBase.Ip本机, conf.Id, conf.ServerType, conf.Desc); DictServerLinkGame.Add(client.LinkId, client); } else if (conf.ServerType == (int)EServerType.登陆) { var client = new ClientLink(); client.Setup(ConstsBase.Ip本机, conf.Id, conf.ServerType, conf.Desc); DictServerLinkLogin.Add(client.LinkId, client); } } AutoCheckLink(); } catch { return(false); } return(true); }
public ServiceResponseData InvokeWcfService(string wcfpluginname, string wcfcontroller, string wcfmethod, Action <ClientRequestData> requestAction) { ClientLink wcfClientLink = ClientLinkManage.CreateConnection(wcfpluginname); ServiceResponseData retData = wcfClientLink.Request(wcfcontroller, wcfmethod, requestAction); return(retData); }
/// <summary> /// 创建数据处理客户端连接,向上级节点请求数据 /// </summary> /// <returns></returns> public static ClientLink CreateDataClient() { //获取的池子索引 int? index = null; ClientLink clientlink = null; ClientLinkPool pool = fromPoolGetClientLink("DataPlugin", out clientlink, out index); bool IsValid = true;//是否有效 if (clientlink.ClientObj == null) { IsValid = false; } if (clientlink.ClientObj.WcfService.State == CommunicationState.Opening || clientlink.ClientObj.ClientID == null)//解决并发问题 { IsValid = false; } if (clientlink.ClientObj.WcfService.State == CommunicationState.Closed || clientlink.ClientObj.WcfService.State == CommunicationState.Faulted) { IsValid = false; } if (IsValid == false) { pool.RemovePoolAt("DataPlugin", index); Thread.Sleep(400); return(CreateDataClient()); } clientlink.BeginIdentify = WcfGlobal.Identify; return(clientlink); }
public bool Start() { Log.LogInfo("Starting Server...", LogType.Application_Work); TcpListener tcpL = new TcpListener(System.Net.IPAddress.Parse(ServerParameter.ipAddress), ServerParameter.port); tcpL.Start(); Log.LogInfo("Server Started", LogType.Application_Work); //star the cleaner to purge disconnected clientlinks CleaningSemaphore = new Semaphore(1, 1); DatabaseAccessSemaphore = new Semaphore(1, 1); TopicManagerAccessSemaphore = new Semaphore(1, 1); PrivateMessageManagerAccessSemaphore = new Semaphore(1, 1); new Thread(ConnectionCleaner).Start(); while (true) { TcpClient comm = tcpL.AcceptTcpClient(); Log.LogInfo(comm.ToString() + " Connecting...", LogType.Connection_To_Client); //little exchange of message to ensure communication is properly functionnal, then procede with init if (Communication.rcvMsg(comm.GetStream()).MessageType == MessageType.Connection_Test) { Log.LogInfo(MessageType.Connection_Test.ToString(), LogType.Comm_Input); Communication.sendMsg(comm.GetStream(), new Message(MessageType.Connection_Success)); Log.LogInfo(MessageType.Connection_Test.ToString(), LogType.Comm_Output); } Console.WriteLine("Connection established @" + comm); Log.LogInfo(comm.ToString() + " Connected.", LogType.Connection_To_Client); ClientLink clientLink = new ClientLink(comm, ServerParameter, InternalTopicManager, InternalPrivateMessageManager); new Thread(() => clientLink.Work(ConnectedUsers, DatabaseAccessSemaphore, TopicManagerAccessSemaphore, PrivateMessageManagerAccessSemaphore)).Start(); //add client link to list without stopping process new Thread(() => AddLinkToList(clientLink)).Start(); } }
void HandleRealmData(byte[] data) { using (var reader = new PacketReader(data, false)) { ClientLink cmd = (ClientLink)reader.Read <byte>(); switch (cmd) { case ClientLink.CMD_AUTH_LOGON_CHALLENGE: case ClientLink.CMD_AUTH_RECONNECT_CHALLENGE: HandleAuthLogonChallenge(reader); break; case ClientLink.CMD_AUTH_LOGON_PROOF: case ClientLink.CMD_AUTH_RECONNECT_PROOF: HandleAuthLogonProof(reader); break; case ClientLink.CMD_REALM_LIST: HandleRealmList(reader); break; default: Log.Message(LogType.Normal, "Received unknown ClientLink: {0}", cmd); break; } } }
void RemoveExistingClient(ClientLink client) { clients.Remove(client); if (ClientRemoved != null) { ClientRemoved(client); } }
void AddNewClient(ClientLink client) { clients.Add(client); if (ClientUpdated != null) { ClientUpdated(client); } }
static void TestWebClient() { //创建对象 //ReplyClientCallBack callback = new ReplyClientCallBack(); ClientLink clientlink = new ClientLink("TestWcfPerformance", "Books.Service"); begintime(); //2.创建连接 clientlink.CreateConnection(); Console.WriteLine("2.创建连接时间(毫秒):" + endtime()); //Console.WriteLine("输入请求数据条数:"); //string num = Console.ReadLine(); string num = "100"; begintime(); //Action<ClientRequestData> requestAction = ((ClientRequestData request) => //{ // //request.Iscompressjson = false; // //request.Isencryptionjson = false; // //request.Serializetype = WcfFrame.SDMessageHeader.SerializeType.Newtonsoft; // request.AddData(num); //}); ////3.同步请求数据 //clientlink.Request("Books.Service@bookWcfController", "Test191", requestAction); //Console.WriteLine("3.请求数据时间(毫秒):" + endtime()); //begintime(); ////3.同步请求数据 //clientlink.Request("Books.Service@bookWcfController", "Test191", requestAction); //Console.WriteLine("3.请求数据时间(毫秒):" + endtime()); Console.Read(); string s; begintime(); s = clientlink.UpLoadFile(@"D:\DCWriter.rar", (delegate(int _num) { Console.WriteLine("4.文件上传进度:%" + _num); })); Console.WriteLine("4.文件上传时间(毫秒):" + endtime() + "|" + s); begintime(); s = clientlink.DownLoadFile("DCWriter.rar", (delegate(int _num) { Console.WriteLine("5.文件下载进度:%" + _num); })); Console.WriteLine("5.文件下载时间(毫秒):" + endtime() + "|" + s); begintime(); //5.关闭连接 clientlink.UnConnection(); Console.WriteLine("6.关闭连接时间(毫秒):" + endtime()); Console.ReadLine(); }
/// <summary> /// 客户端执行订阅服务 /// </summary> /// <param name="_clientLink"></param> public static void ProcessPublishService(string publishServiceName, ClientLink _clientLink) { switch (publishServiceName) { case "DistributedCache": //分布式缓存服务 List <CacheIdentify> ciList = DistributedCacheClient.GetCacheIdentifyList(); List <CacheObject> coList = _clientLink.GetDistributedCacheData(ciList); if (coList.Count > 0) { DistributedCacheClient.SetCacheObjectList(coList); } break; case "RemotePlugin": //远程插件服务 LocalPlugin localPlugin = RemotePluginClient.GetLocalPlugin(); if (localPlugin.PluginDic.Count > 0) { _clientLink.RegisterRemotePlugin(WcfGlobal.Identify, localPlugin.PluginDic.Keys.ToArray()); } break; case "UpgradeClient": //客户端升级 ClientUpgradeManager.DownLoadUpgrade(); break; case "UpgradeServer": //中间件升级 break; case "MongodbSync": //同步Mongodb数据 break; case "MiddlewareMonitor": //中间件集群监控服务 break; case "MiddlewareCmd": //中间件命令服务 break; default: PublishServiceObject pso = psoList.Find(x => x.publishServiceName == publishServiceName); MiddlewareLogHelper.WriterLog(LogType.MidLog, true, System.Drawing.Color.Blue, string.Format("正在执行服务{0}/{1}/{2}/{3}", pso.pluginname, pso.controller, pso.method, pso.argument)); ServiceResponseData retjson = InvokeWcfService( pso.pluginname , pso.controller , pso.method , (ClientRequestData request) => { request.SetJsonData(pso.argument); }); string txtResult = retjson.GetJsonData(); MiddlewareLogHelper.WriterLog(LogType.MidLog, true, System.Drawing.Color.Blue, string.Format("服务执行完成,返回结果:{0}", txtResult)); break; } ShowHostMsg(Color.Blue, DateTime.Now, "执行“" + publishServiceName + "”订阅服务成功!"); }
public string CreateDataClient() { ClientLink cl = SuperClient.CreateDataClient(); while (cl.ClientObj.ClientID == null)//解决并发问题,因为创建连接是一个异步过程,等创建成功后再返回ClientID { Thread.Sleep(400); } return(cl.ClientObj.ClientID); }
private ServiceResponseData InvokeWcfService(string wcfpluginname, string wcfcontroller, string wcfmethod, Action<ClientRequestData> requestAction) { ClientLink wcfClientLink = ClientLinkManage.CreateConnection("localendpoint", wcfpluginname); //绑定LoginRight Action<ClientRequestData> _requestAction = ((ClientRequestData request) => { request.LoginRight = new EFWCoreLib.CoreFrame.Business.SysLoginRight(); if (requestAction != null) requestAction(request); }); ServiceResponseData retData = wcfClientLink.Request(wcfcontroller, wcfmethod, _requestAction); return retData; }
private static void CreateSuperClient() { //就算上级中间件重启了,下级中间件创建链接的时候会重新注册本地插件 superClientLink = new ClientLink(WcfGlobal.HostName, "SuperPlugin", null, WcfGlobal.Identify, null); try { superClientLink.CreateConnection(); } catch (Exception e) { MiddlewareLogHelper.WriterLog(LogType.MidLog, true, Color.Red, "连接上级中间件失败!" + e.Message); } }
public void OnClientRemoved(ClientLink client) { this.Invoke(new MethodInvoker(() => { if (listBox_Clients.Items.Contains(client)) { if (client == listBox_Clients.SelectedItem) { listBox_Clients.SelectedItem = null; } listBox_Clients.Items.Remove(client); } })); }
public void Stop() { if (clientCancellationToken.CanBeCanceled) { clientCancellationTokenSource.Cancel(); } if (link != null) { link.Close(); } Thread.Sleep(100); link = null; }
public IAsyncResult InvokeWcfServiceAsync(string wcfpluginname, string wcfcontroller, string wcfmethod, Action <ClientRequestData> requestAction, Action <ServiceResponseData> responseAction) { ClientLink wcfClientLink = ClientLinkManage.CreateConnection(wcfpluginname); //绑定LoginRight Action <ClientRequestData> _requestAction = ((ClientRequestData request) => { request.LoginRight = LoginUserInfo; if (requestAction != null) { requestAction(request); } }); return(wcfClientLink.RequestAsync(wcfcontroller, wcfmethod, _requestAction, responseAction)); }
public string TestRemoteService(string identify, string plugin, string controller, string method, string para) { Action <ClientRequestData> requestAction = ((ClientRequestData request) => { request.Iscompressjson = false; request.Isencryptionjson = false; request.Serializetype = SerializeType.Newtonsoft; request.LoginRight = new SysLoginRight(1); request.SetJsonData(para); }); ClientLink link = new ClientLink(null, plugin, null, null, null, identify); link.CreateConnection(); ServiceResponseData response = link.Request(controller, method, requestAction); return(response.GetJsonData()); }
public static ServiceResponseData InvokeWcfService(string wcfpluginname, string wcfcontroller, string wcfmethod, Action <ClientRequestData> requestAction) { ClientLink wcfClientLink = ClientLinkManage.CreateConnection(wcfpluginname); //绑定LoginRight Action <ClientRequestData> _requestAction = ((ClientRequestData request) => { request.LoginRight = new EFWCoreLib.CoreFrame.Business.SysLoginRight(); request.LoginRight.WorkId = _WorkId; if (requestAction != null) { requestAction(request); } }); ServiceResponseData retData = wcfClientLink.Request(wcfcontroller, wcfmethod, _requestAction); return(retData); }
public void OnClientUpdated(ClientLink client) { this.Invoke(new MethodInvoker(() => { if (listBox_Clients.Items.Contains(client)) { if (client == listBox_Clients.SelectedItem) { SetClientInfo(client); } } else { listBox_Clients.Items.Add(client); } })); }
static void CallService() { ClientLink clientlink = new ClientLink("Books.Service"); clientlink.CreateConnection(); Action <ClientRequestData> _requestAction = ((ClientRequestData request) => { request.LoginRight = new EFWCoreLib.CoreFrame.Business.SysLoginRight(1); }); ServiceResponseData retData = clientlink.Request("bookWcfController", "GetBooks", _requestAction); string data = retData.GetJsonData(); clientlink.UnConnection(); Console.WriteLine(data); }
/// <summary> /// 客户端接收通知 /// </summary> /// <param name="publishServiceName">订阅服务名称</param> /// <param name="_clientLink">客户端连接</param> public static void ReceiveNotify(string publishServiceName, ClientLink _clientLink) { ShowHostMsg(Color.Blue, DateTime.Now, "收到订阅的“" + publishServiceName + "”服务通知!"); if (ssoList.FindIndex(x => x.publishServiceName == publishServiceName) == -1) { return; } //执行订阅服务 SubscribeServiceObject ssObject = ssoList.Find(x => x.publishServiceName == publishServiceName); if (ssObject.ProcessService != null) { new Action(delegate() { //异步执行 ssObject.ProcessService(_clientLink); }).BeginInvoke(null, null); } }
public static ClientLink superclient;//连接上级中间件超级客户端 public static void CreateSuperClient() { //就算上级中间件重启了,下级中间件创建链接的时候会重新注册本地插件 superclient = new ClientLink(WcfGlobal.HostName, null); try { superclient.CreateConnection((() => { //以后可以做成配置方式 //foreach (var item in PublishServiceManage.serviceDic.Keys) //{ // superclient.Subscribe(item);//订阅服务? //} }), null); } catch (Exception e) { MiddlewareLogHelper.WriterLog(LogType.MidLog, true, Color.Red, "连接上级中间件失败!" + e.Message); } }
static void TestConcurrency() { try { ClientLink clientlink = new ClientLink("TestWcfPerformance", "Books.Service"); clientlink.CreateConnection(); int num = 100; while (num > 0) { //num -= 1; clientlink.Request("bookWcfController", "GetDiseaseData", null); Thread.Sleep(time); } clientlink.Dispose(); } catch (Exception err) { Console.WriteLine(err.Message); } }
private void SetClientInfo(ClientLink cl) { bool isConnected = false; string name = ""; string state = ""; string type = ""; if (cl != null) { isConnected = cl.IsConnected; name = cl.AccountInfo.Name; state = cl.State.ToString(); type = cl.AccountInfo.Type.ToString(); } checkBox_ClientConnected.Checked = isConnected; label_ClientName.Text = name; label_ClientState.Text = state; label_ClientAccountType.Text = type; }
public ActionResult Login(FormCollection form, bool rememberMe = false) { String email = form["Email address"].ToString(); String password = form["Password"].ToString(); ClientLink rList = new ClientLink(); List <Representative> myRep = new List <Representative>(); rList.Representative = db.Representatives.ToList(); myRep = db.Representatives.ToList(); List <Employee> myEmp = new List <Employee>(); rList.Employee = db.Employees.ToList(); myEmp = db.Employees.ToList(); for (int iCount = 0; iCount < myRep.Count; iCount++) { if (((string.Equals(email, myRep[iCount].repEmail)) && (string.Equals(password, myRep[iCount].repPasswordHash))) | ((string.Equals(email, myRep[iCount].repUserName)) && (string.Equals(password, myRep[iCount].repPasswordHash)))) { FormsAuthentication.SetAuthCookie(email, rememberMe); return(RedirectToAction("repHome", "Representatives", new { id = myRep[iCount].repID })); } } for (int iCount = 0; iCount < myEmp.Count; iCount++) { if ((string.Equals(email, myEmp[iCount].empEmail)) && (string.Equals(password, myEmp[iCount].empPassword))) { FormsAuthentication.SetAuthCookie(email, rememberMe); return(RedirectToAction("empHome", "Employees", new { id = myEmp[iCount].empID })); } } return(View()); }
public ServiceResponseData InvokeWcfService(string wcfpluginname, string wcfcontroller, string wcfmethod, Action <ClientRequestData> requestAction) { //获取的池子索引 int? index = null; ClientLink clientlink = null; ClientLinkPool pool = fromPoolGetClientLink(wcfpluginname, out clientlink, out index); ServiceResponseData retData = new ServiceResponseData(); try { //绑定LoginRight Action <ClientRequestData> _requestAction = ((ClientRequestData request) => { if (Request.Properties.ContainsKey("__user_token__")) { request.LoginRight = new SysLoginRight(1); SSO.UserInfo user = (SSO.UserInfo)Request.Properties["__user_token__"]; //? if (user.Tag != null) { request.LoginRight = user.Tag as SysLoginRight; } } if (requestAction != null) { requestAction(request); } }); retData = clientlink.Request(wcfcontroller, wcfmethod, _requestAction); } catch (Exception ex) { throw ex; } finally { if (index != null) { pool.ReturnPool(wcfpluginname, (int)index); } } return(retData); }
private void GetNewClients() { ClientAcceptor.AuthorizedLoginAttempt newAuthorizedClient = null; while ((newAuthorizedClient = clientAcceptor.GetAuthorizedLoginAttempt()) != null) { //See if client already exists. ClientLink foundClient = clients.FirstOrDefault((cl) => { return(cl.AccountInfo.Name.CompareTo(newAuthorizedClient.Info.Name) == 0); }); //If found, then it is an already existing client on server. if (foundClient != null) { if (foundClient.IsConnected) { newAuthorizedClient.Connection.Dispose(); Log.Log("Client denied login; already connected: " + newAuthorizedClient.Info.Name); } else { foundClient.SetConnection(newAuthorizedClient.Connection); if (ClientUpdated != null) { ClientUpdated(foundClient); } foundClient.Send_CharacterList(); Log.Log("Client reconnected: " + newAuthorizedClient.Info.Name); } } else //If not found, then it is a newly connecting client. { ClientLink newLink = new ClientLink(clients_ActionDispersion, newAuthorizedClient.Info, newAuthorizedClient.Connection); newLink.Send_CharacterList(); AddNewClient(newLink); Log.Log("New client: " + newLink.AccountInfo.Name); } } }
//从根节点下载 private static void downloadRemotePlugin(string pluginzip, ClientLink _clientLink) { DownFile df = new DownFile(); df.clientId = Guid.NewGuid().ToString(); df.DownKey = Guid.NewGuid().ToString(); df.FileName = pluginzip; df.FileType = 0; FileStream fs = new FileStream(rootpath + pluginzip, FileMode.Create, FileAccess.Write); try { _clientLink.RootDownLoadFile(df, fs, (delegate(int _num) //从根节点下载 { MiddlewareLogHelper.WriterLog(LogType.MidLog, true, System.Drawing.Color.Black, "插件包下载进度:%" + _num); })); } catch (Exception err) { CoreFrame.Common.MiddlewareLogHelper.WriterLog(err.Message + err.StackTrace); } }
public async override Task RunAsync(AuthorizationData authorizationData) { try { OutputStatusMessage("You must edit the ManageClient.cs file to provide the ClientAccountId for " + "the client link."); OutputStatusMessage("When adding a client link, the client link's ManagingCustomerId is set to the CustomerId of the current " + "authenticated user, who must be a Super Admin of the agency."); OutputStatusMessage("Login as an agency Super Admin user to send a client link invitation, " + "or unlink an existing client link."); OutputStatusMessage("Login as a client Super Admin user to accept a client link invitation.\n"); Service = new ServiceClient<ICustomerManagementService>(authorizationData); UpdateClientLinksResponse updateClientLinksResponse = null; // Specify the client link search criteria var pageInfo = new Paging { Index = 0, // The first page Size = 100 // The first 100 client links for this page of results }; var ordering = new OrderBy { Field = OrderByField.Number, Order = SortOrder.Ascending }; var predicate = new Predicate { Field = "ClientAccountId", Operator = PredicateOperator.In, Value = ClientAccountId.ToString(CultureInfo.InvariantCulture) }; // Search for client links that match the specified criteria. var clientLinks = await SearchClientLinksAsync( new[] { ordering }, pageInfo, new[] { predicate }); // Determine whether the agency is already managing the specified client account. // If a link exists with status either Active, LinkInProgress, LinkPending, // UnlinkInProgress, or UnlinkPending, the agency may not initiate a duplicate client link. ClientLink clientLink; var newLinkRequired = true; if (clientLinks.Count > 0) { clientLink = clientLinks[0]; OutputStatusMessage(String.Format("Current ClientLink Status: {0}.\n", clientLink.Status)); switch (clientLink.Status) { // The agency may choose to initiate the unlink process, // which would terminate the existing relationship with the client. case ClientLinkStatus.Active: clientLink.Status = ClientLinkStatus.UnlinkRequested; updateClientLinksResponse = await UpdateClientLinksAsync(new[] { clientLink }); OutputStatusMessage("UpdateClientLinks : UnlinkRequested.\n"); newLinkRequired = false; break; // Waiting on a system status transition or waiting for the StartDate. case ClientLinkStatus.LinkAccepted: OutputStatusMessage("The status is transitioning towards LinkInProgress.\n"); newLinkRequired = false; break; // Waiting on a system status transition. case ClientLinkStatus.LinkInProgress: OutputStatusMessage("The status is transitioning towards Active.\n"); newLinkRequired = false; break; // When the status is LinkPending, either the agency or client may update the status. // The agency may choose to cancel the client link invitation; however, in this example // the client will accept the invitation. // If the client does not accept or decline the invitation within 30 days, and if the agency // does not update the status to LinkCanceled, the system updates the status to LinkExpired. case ClientLinkStatus.LinkPending: /* clientLink.Status = ClientLinkStatus.LinkCanceled; updateClientLinksResponse = UpdateClientLinks(new[] { clientLink }); WriteMessage(String.Format("The agency updated status: LinkCanceled.\n"); */ clientLink.Status = ClientLinkStatus.LinkAccepted; updateClientLinksResponse = await UpdateClientLinksAsync(new[] { clientLink }); OutputStatusMessage("UpdateClientLinks: LinkAccepted.\n"); newLinkRequired = false; break; // Waiting on a system status transition. case ClientLinkStatus.UnlinkInProgress: OutputStatusMessage("The status is transitioning towards Inactive.\n"); newLinkRequired = false; break; // Waiting on a system status transition. case ClientLinkStatus.UnlinkPending: OutputStatusMessage("The status is transitioning towards Inactive.\n"); newLinkRequired = false; break; // The link lifecycle has ended. default: OutputStatusMessage("A new client link invitation is required.\n"); break; } // Print errors if any occurred when updating the client link. if (updateClientLinksResponse != null) { PrintPartialErrors(updateClientLinksResponse.OperationErrors, updateClientLinksResponse.PartialErrors); } } // If no links exist between the agency and specified client account, or a link exists with status // either Inactive, LinkCanceled, LinkDeclined, LinkExpired, or LinkFailed, then the agency must // initiate a new client link. if (newLinkRequired) { clientLink = new ClientLink { ClientAccountId = ClientAccountId, ManagingCustomerId = authorizationData.CustomerId, IsBillToClient = true, Name = "My Client Link", StartDate = null, SuppressNotification = true }; var addClientLinksResponse = await AddClientLinksAsync(new[] { clientLink }); // Print errors if any occurred when adding the client link. PrintPartialErrors(addClientLinksResponse.OperationErrors.ToArray(), addClientLinksResponse.PartialErrors.ToArray()); OutputStatusMessage(string.Format("The user attempted to add a new ClientLink.\n")); OutputStatusMessage(string.Format("Login as the client Super Admin to accept the agency's request to manage AccountId {0}.\n", ClientAccountId)); } // Get and print the current client link clientLinks = await SearchClientLinksAsync( new[] { ordering }, pageInfo, new[] { predicate }); PrintClientLinks(clientLinks); } // Catch authentication exceptions catch (OAuthTokenRequestException ex) { OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description)); } // Catch Customer Management service exceptions catch (FaultException<Microsoft.BingAds.CustomerManagement.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException<Microsoft.BingAds.CustomerManagement.ApiFault> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } }