public bool SvCommand(FnSvCmd fnSvCmd, string[] cmds, uint cmdidx, string prompt, ref f9sv.ReportHandler handler) { handler.UserData_ = IntPtr.Add(handler.UserData_, 1); if (cmdidx >= cmds.Length) { Console.WriteLine($"{prompt}: require 'treePath'"); return(false); } f9sv.SeedName seedName = new f9sv.SeedName(); seedName.TreePath_ = cmds[cmdidx++]; if (cmdidx >= cmds.Length) { Console.WriteLine($"{prompt}: require 'key'"); return(false); } seedName.SeedKey_ = cmds[cmdidx++]; if (seedName.SeedKey_ == "\\t") { seedName.SeedKey_ = "\t"; } if (cmdidx < cmds.Length) { seedName.TabName_ = cmds[cmdidx]; } f9sv.ResultCode res = fnSvCmd(this, ref seedName, handler); Console.WriteLine($"---------- {prompt}: UserData={handler.UserData_}, return={SvResultCodeStr(res)}"); Console.WriteLine($"treePath=[{seedName.TreePath_}], seedKey=[{seedName.SeedKey_}], tab=[{seedName.TabName_}]"); Console.WriteLine("--------------------"); return(true); }
static void Main(string[] args) { Console.InputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8; Console.WriteLine($"f9omsrcapi library version info: {f9oms.Api.VersionInfo()}"); // ------------------------------------------------------------------ ClientHandler cli = new ClientHandler(); // 設定 rc client session 所需的參數. f9rc.ClientSessionParams rcArgs = new f9rc.ClientSessionParams(); rcArgs.RcFlags_ = f9rc.RcFlag.NoChecksum; // 告知 rc protocol 不須使用 check sum; 需自行負擔風險. rcArgs.FnOnLinkEv_ = cli.OnRcLinkEv; rcArgs.LogFlags_ = f9rc.ClientLogFlag.All; // 設定 SeedVisitor(可用於查詢) 所需的參數. f9sv.ClientSessionParams svArgs = new f9sv.ClientSessionParams(); svArgs.FnOnConfig_ = cli.OnSvConfig; // 設定 f9oms rc api 所需的參數. f9oms.ClientSessionParams omsRcParams = new f9oms.ClientSessionParams(); omsRcParams.FnOnConfig_ = cli.OnOmsClientConfig; omsRcParams.FnOnReport_ = cli.OnOmsClientReport; omsRcParams.FnOnFlowControl_ = cli.OnOmsClientFcReq; // ------------------------------------------------------------------ fon9.IoSessionParams ioParams = new fon9.IoSessionParams(); string f9rcIosv = string.Empty; string logFileFmt = null; // ------------------------------------------------------------------ for (int L = 0; L < args.Length; ++L) { string str = args[L]; if (string.IsNullOrEmpty(str)) { continue; } char chlead = str[0]; if ((chlead == '-' || chlead == '/') && str.Length == 2) { if (++L >= args.Length) { Console.WriteLine($"Lost argument value: {str}"); return; } string val = args[L]; switch (str[1]) { case 'l': logFileFmt = val; continue; case 'u': rcArgs.UserId_ = val; continue; case 'p': rcArgs.Password_ = val; continue; case 'n': rcArgs.DevName_ = val; continue; case 'a': rcArgs.DevParams_ = val; continue; case 'f': try { rcArgs.LogFlags_ = (f9rc.ClientLogFlag)UInt32.Parse(val, System.Globalization.NumberStyles.HexNumber); } catch (SystemException) { Console.WriteLine($"parse LogFlag error: {str} {val}"); return; } continue; case 't': f9oms.Api.FreeOmsErrMsgTx(omsRcParams.ErrCodeTx_); omsRcParams.ErrCodeTx_ = f9oms.Api.LoadOmsErrMsgTx1(val); continue; case '?': PrintUsage(); return; case 'R': f9rcIosv = val; continue; case 'N': ioParams.DevName_ = val; continue; } } Console.WriteLine($"Unknown argument: {str}"); PrintUsage(); return; } if (string.IsNullOrEmpty(rcArgs.UserId_)) { Console.WriteLine("Require: -u UserId"); PrintUsage(); return; } if (string.IsNullOrEmpty(rcArgs.DevParams_)) { Console.WriteLine("Require: -a DevArguments"); return; } if (string.IsNullOrEmpty(rcArgs.DevName_)) { rcArgs.DevName_ = "TcpClient"; } if (string.IsNullOrEmpty(rcArgs.Password_)) { rcArgs.Password_ = fon9.Api.getpass("Password: "******"> "); Console.Out.Flush(); string cmdln = Console.ReadLine(); if (cmdln == null) { break; } cmdln.Trim(); if (string.IsNullOrEmpty(cmdln)) { continue; } if (cmdln == "quit") { break; } char[] splitter = { ' ', '\t' }; string[] cmds = cmdln.Split(splitter, StringSplitOptions.RemoveEmptyEntries); if (cmds[0] == "wc") { // wait connect. default=5 secs. 0 = 1 secs; Console.WriteLine("Waiting for connection..."); UInt32 secs = 0; if (cmds.Length >= 2) { UInt32.TryParse(cmds[1], out secs); } if (secs <= 0) { secs = 5; } while (!cli.IsConnected) { System.Threading.Thread.Sleep(1000); if (secs <= 0) { break; } Console.Write($"{secs--} \r"); Console.Out.Flush(); } Console.WriteLine(cli.IsConnected ? "\rConnection ready." : "\rWait connection timeout."); } else if (cmds[0] == "sleep") { UInt32 secs = 0; if (cmds.Length >= 2) { UInt32.TryParse(cmds[1], out secs); } for (;;) { Console.Write($"\r{secs} "); Console.Out.Flush(); System.Threading.Thread.Sleep(1000); if (secs <= 0) { break; } --secs; } Console.Write("\r"); } else if (cmds[0] == "lf") { if (cmds.Length >= 2) { UInt32 lf; if (UInt32.TryParse(cmds[1], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.CurrentCulture, out lf)) { cli.LogFlags = (f9rc.ClientLogFlag)lf; } } Console.WriteLine($"LogFlags = {cli.LogFlags:X}\n"); if (cmds.Length >= 3) { fon9.Api.Initialize(cmds[2]); fon9.Api.Finalize(); } } else if (cmds[0] == "q") { // query: q treePath key tabName svCmdHandler.FnOnReport_ = cli.OnSvQueryReport; if (cli.SvCommand(f9sv.Api.Query, cmds, 1, "q:query", ref svCmdHandler)) { // 等候查詢結果, 或一小段時間(沒結果則放棄等候). for (uint L = 0; L < 100; ++L) { if (cli.LastQueryReportedUserData_ == svCmdHandler.UserData_) { break; } System.Threading.Thread.Sleep(10); } } } else if (cmds[0] == "s") { // subscribe: s treePath key tabName svCmdHandler.FnOnReport_ = cli.OnSvSubscribeReport; cli.SvCommand(f9sv.Api.Subscribe, cmds, 1, "s:subr", ref svCmdHandler); } else if (cmds[0] == "u") { // unsubscribe: u treePath key tabName svCmdHandler.FnOnReport_ = cli.OnSvUnsubscribeReport; cli.SvCommand(f9sv.Api.Unsubscribe, cmds, 1, "s:subr", ref svCmdHandler); } else if (cmds[0] == "cfg") { cli.PrintConfig(); } else if (cmds[0] == "set") { cli.SetRequest(cmds, 1); } else if (cmds[0] == "send") { cli.SendRequest(cmds, 1); } else if (cmds[0] == "?" || cmds[0] == "help") { Console.WriteLine(@"Commands: ? or help This info. quit Quit program. wc secs wait connect. sleep secs cfg List configs. lf LogFlags(hex) [LogFileFmt] q treePath key tabName set ReqId(or ReqName) FieldId(or FieldName)=value|fld2=val2|fld3=val3 send ReqId(or ReqName) times "); } else { Console.WriteLine($"Unknown command: {cmdln}"); } } // ------------------------------------------------------------------ // 關閉連線, 並等候資源釋放完畢後返回. cli.Dispose(); // 系統結束, 清理 fon9 函式庫所用到的資源. fon9.Api.Finalize(); // 避免因最佳化造成 rcArgs 被回收, 使得 rcArgs.FnOnLinkEv_ 無效, 可能造成 crash. // 所以必須讓 rcArgs 保持存活! GC.KeepAlive(rcArgs); GC.KeepAlive(svArgs); GC.KeepAlive(omsRcParams); GC.KeepAlive(ctrlHandler); if (!string.IsNullOrEmpty(fon9.Tools.CtrlMessage_)) { Console.WriteLine($"Quit: {fon9.Tools.CtrlMessage_}"); } f9oms.Api.FreeOmsErrMsgTx(omsRcParams.ErrCodeTx_); }