Пример #1
0
        private void btnLogin_Click(object sender, EventArgs e)
        {
            if (cbxIsAnonymous.Checked)
            {
                ClearLoginCache();
                this.Close();
                return;
            }

            if (tbxPassword.Text == "" || tbxUser.Text == "")
            {
                MessageBox.Show("请将用户名和密码输入完整", "提示",
                                MessageBoxButtons.OK
                                , MessageBoxIcon.Warning);
                return;
            }


            string baseEndPoint = null;

            if (clientRouter == null)
            {
                var providerAddr = parentForm.tbxProviderAddr.Text;
                if (string.IsNullOrEmpty(providerAddr))
                {
                    MessageBox.Show("请先在主窗体设置“服务器地址”");
                }

                baseEndPoint = $"{providerAddr}:{DEFAULT_WEB_PORT}";
            }
            else
            {
                var config = clientRouter.ConnectionManager.ClientConfig;
                baseEndPoint = $"{config.ProviderAddress}:{config.ProviderWebPort}";
            }

            btnLogin.Enabled = false;
            NSPDispatcher dispatcher   = new NSPDispatcher(baseEndPoint);
            var           connectAsync = dispatcher.LoginFromClient(tbxUser.Text, tbxPassword.Text);
            var           delayDispose = Task.Delay(TimeSpan.FromSeconds(5000));
            var           comletedTask = Task.WhenAny(delayDispose, connectAsync).Result;

            if (!connectAsync.IsCompleted) //超时
            {
                MessageBox.Show("连接超时");
            }
            else if (connectAsync.IsFaulted)//出错
            {
                MessageBox.Show(connectAsync.Exception.ToString());
            }
            else
            {
                MessageBox.Show("登录成功");

                CreateLoginCache(connectAsync.Result.Data.Token);
                Success = true;
                this.Close();
            }
            btnLogin.Enabled = true;
        }
Пример #2
0
        private async Task <ValueTuple <string, int> > Login()
        {
            string        arrangedToken;
            int           clientId;
            NSPDispatcher disp   = new NSPDispatcher($"{ClientConfig.ProviderAddress}:{ClientConfig.ProviderWebPort}");
            var           result = await disp.LoginFromClient(CurrentLoginInfo.UserName ?? "", CurrentLoginInfo.UserPwd ?? "");

            if (result.State == 1)
            {
                Router.Logger.Debug("登陆成功");
                var data = result.Data;
                arrangedToken = data.Token;
                Router.Logger.Debug($"服务端版本号:{data.Version},当前适配版本号{Global.NSmartProxyServerName}");
                clientId = int.Parse(data.Userid);
                File.WriteAllText(NSMART_CLIENT_CACHE_PATH, arrangedToken);
            }
            else
            {
                StatusChanged(ClientStatus.LoginError, null);
                throw new Exception("登陆失败,服务端返回错误如下:" + result.Msg);
            }

            return(arrangedToken, clientId);
        }
Пример #3
0
 public Router SetConfiguration(NSPClientConfig config)//start之前一定要执行该方法,否则出错
 {
     ClientConfig     = config;
     ClientDispatcher = new NSPDispatcher($"{ClientConfig.ProviderAddress}:{ClientConfig.ProviderWebPort}");
     return(this);
 }
Пример #4
0
        /// <summary>
        /// 重要:连接服务端,一般做为入口方法
        /// 该方法主要操作一些配置和心跳
        /// AlwaysReconnect:始终重试,开启此选项,无论何时,一旦程序在连接不上时都会进行重试,否则只在连接成功后的断线时才重试。
        /// </summary>
        /// <returns></returns>
        public async Task Start(bool AlwaysReconnect = false)
        {
            if (AlwaysReconnect)
            {
                IsStarted = true;
            }
            var oneLiveToken = ONE_LIVE_TOKEN_SRC.Token;
            //登陆功能
            string arrangedToken = Global.NO_TOKEN_STRING;

            while (!oneLiveToken.IsCancellationRequested)
            {
                CANCEL_TOKEN_SRC      = new CancellationTokenSource();
                TRANSFERING_TOKEN_SRC = new CancellationTokenSource();
                HEARTBEAT_TOKEN_SRC   = new CancellationTokenSource();
                _waiter = new TaskCompletionSource <object>();
                var appIdIpPortConfig = ClientConfig.Clients;
                int clientId          = 0;

                //0.5 如果有文件,取出缓存中的clientid
                try
                {
                    //登陆缓存
                    if (File.Exists(NSMART_CLIENT_CACHE_PATH))
                    {
                        using (var stream = File.OpenRead(NSMART_CLIENT_CACHE_PATH))
                        {
                            byte[] bytes = new byte[2];
                            stream.Read(bytes, 0, bytes.Length);
                            clientId = StringUtil.DoubleBytesToInt(bytes);
                        }
                    }
                    //登陆
                    if (CurrentLoginInfo != null)
                    {
                        NSPDispatcher disp   = new NSPDispatcher();
                        var           result = await disp.LoginFromClient(CurrentLoginInfo.UserName, CurrentLoginInfo.UserPwd);

                        if (result.State == 1)
                        {
                            Router.Logger.Debug("登陆成功");
                            var data = result.Data;
                            arrangedToken = data.Token;
                            Router.Logger.Debug($"服务端版本号:{data.Version},当前适配版本号{Global.NSmartProxyServerName}");
                            clientId = int.Parse(data.Userid);
                        }
                        else
                        {
                            throw new Exception("登陆失败,服务端返回错误如下:" + result.Msg);
                        }
                    }
                    else
                    {
                        Router.Logger.Debug("为提供登陆信息,尝试匿名登陆");
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex.Message, ex);
                }
                //1.获取配置
                ConnectionManager = ServerConnectionManager.Create(clientId);
                ConnectionManager.CurrentToken          = arrangedToken;
                ConnectionManager.ClientGroupConnected += ServerConnnectionManager_ClientGroupConnected;
                ConnectionManager.ServerNoResponse      = DoServerNoResponse; //下钻事件
                ClientModel clientModel = null;                               //
                try
                {
                    //非第一次则算作重连,发送clientid过去
                    clientModel = await ConnectionManager.InitConfig(this.ClientConfig).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    //TODO 状态码:连接失败
                    Router.Logger.Error("连接失败:" + ex.Message, ex);
                    //throw;
                }

                //HasConnected = true;
                if (clientModel != null)
                {
                    int counter = 0;

                    //1.5 写入缓存
                    File.WriteAllBytes(NSMART_CLIENT_CACHE_PATH, StringUtil.IntTo2Bytes(clientModel.ClientId));
                    //2.分配配置:appid为0时说明没有分配appid,所以需要分配一个
                    foreach (var app in appIdIpPortConfig)
                    {
                        if (app.AppId == 0)
                        {
                            app.AppId = clientModel.AppList[counter].AppId;
                            counter++;
                        }
                    }
                    Logger.Debug("****************port list*************");
                    List <string> tunnelstrs = new List <string>();
                    foreach (var ap in clientModel.AppList)
                    {
                        var cApp      = appIdIpPortConfig.First(obj => obj.AppId == ap.AppId);
                        var tunnelStr = ap.AppId.ToString() + ":  " + ClientConfig.ProviderAddress + ":" +
                                        ap.Port.ToString() + "=>" +
                                        cApp.IP + ":" + cApp.TargetServicePort;
                        Logger.Debug(tunnelStr);
                        tunnelstrs.Add(tunnelStr);
                    }
                    Logger.Debug("**************************************");
                    ConnectionManager.PollingToProvider(StatusChanged, tunnelstrs);
                    //3.创建心跳连接
                    ConnectionManager.StartHeartBeats(Global.HeartbeatInterval, HEARTBEAT_TOKEN_SRC.Token);

                    IsStarted = true;
                    Exception exception = await _waiter.Task.ConfigureAwait(false) as Exception;

                    if (exception != null)
                    {
                        Router.Logger.Debug($"程序异常终止:{exception.Message}。");
                    }
                    else
                    {
                        Router.Logger.Debug($"未知异常。");
                    }
                }
                else
                {
                    Router.Logger.Debug($"程序启动失败。");
                    //如果程序从未启动过就出错,则终止程序,否则重试。
                    if (IsStarted == false)
                    {
                        StatusChanged(ClientStatus.Stopped, null); return;
                    }
                }

                Router.Logger.Debug($"连接故障,尝试关闭连接并重试");
                if (ConnectionManager != null)
                {
                    ConnectionManager.CloseAllConnections();//关闭所有连接
                }
                //出错重试
                await Task.Delay(Global.ClientReconnectInterval, ONE_LIVE_TOKEN_SRC.Token);

                //TODO 返回错误码
                //await Task.Delay(TimeSpan.FromHours(24), CANCEL_TOKEN.CurrentToken).ConfigureAwait(false);
                Router.Logger.Debug($"连接关闭,开启重试");
            }
            //正常终止
            Router.Logger.Debug($"停止重试,循环终止。");
        }