示例#1
0
        public static void Eventer_Tefreeca_client_event(object sender, EventArgs e)
        {
            try
            {
                Tefreeca_client_EventArgs RecieveEventArg = e as Tefreeca_client_EventArgs;
                if (RecieveEventArg == null)
                {
                    return;
                }
                Unit_Event_Type type = RecieveEventArg.type;

                switch (type)
                {
                case Unit_Event_Type.Account_Check_Login:
                {
                    int connect_no = RecieveEventArg.data_int;

                    //실질적인 로그인 시도.
                    if (!Ldriver.Has_int_key(connect_no))         //드라이브가 없으면 바로 삭제한것으로 간주
                    {
                        return;
                    }
                    IWebDriver drv = (IWebDriver)Ldriver.Select_key(connect_no);

                    if (login_check(drv))
                    {
                        i_Updated_Connection_Account iua = new i_Updated_Connection_Account();
                        iua.Connect_No = connect_no;
                        iua.State      = State_Account_on_connected.Logged_Account;
                        TefreecaUnit_interface.Add_Command(Command_Client.Updated_Connection_Account, iua);
                    }
                    else         //로긴 상태가 아니라면, 로긴을 해야하는데.. 그래서 다시 setting 로 바꿔서 로긴시도하게끔 만듬.
                    {
                        i_Updated_Connection_Account iua = new i_Updated_Connection_Account();
                        iua.Connect_No = connect_no;
                        iua.State      = State_Account_on_connected.Setting;
                        TefreecaUnit_interface.Add_Command(Command_Client.Updated_Connection_Account, iua);
                    }
                }
                break;

                case Unit_Event_Type.Account_Login:     //ㄹ
                {
                    i_Account_Set iac = (i_Account_Set)RecieveEventArg.Data_object_list[0];

                    //실질적인 로그인 시도.
                    if (!Ldriver.Has_int_key(iac.Connect_No))         //드라이브가 없으면 바로 삭제한것으로 간주
                    {
                        return;
                    }
                    IWebDriver drv = (IWebDriver)Ldriver.Select_key(iac.Connect_No);

                    login_afreeca(drv, iac.ID, iac.PW);         //여기선 로긴만 한다.
                }
                break;

                case Unit_Event_Type.Check_End_broadcast:     //방송이 진행중에 종료되었는지 확인하는 코드
                {
                    foreach (i_connect C in RecieveEventArg.Data_object_list)
                    {
                        Thread th = new Thread(new ParameterizedThreadStart(Thread_check_End_Broadcasting));
                        th.Start(C);         //웹브라우저 객체를 매게변수로 넘긴다.
                    }
                }
                break;

                case Unit_Event_Type.Disconnect_All:
                {
                    Shutdown_ALL();
                }
                break;

                case Unit_Event_Type.Disconnect_connect:    //하나의 연결 해제.
                {
                    i_connect C = (i_connect)RecieveEventArg.Data_object_list[0];

                    if (!Ldriver.Has_int_key(C.No))         //드라이브가 없으면 바로 삭제한것으로 간주
                    {
                        TefreecaUnit_interface.Add_Command( //상태를 업데이트 하도록 한다.
                            Command_Client.Updated_Connection,
                            new i_Updated_Connection(C.No, i_Updated_Connection_Type.State_Connect, State_Connect.Close));
                        return;
                    }

                    TefreecaUnit_interface.Add_Command(         //상태를 업데이트 하도록 한다.
                        Command_Client.Updated_Connection,
                        new i_Updated_Connection(C.No, i_Updated_Connection_Type.State_Connect, State_Connect.Closing));

                    Thread th = new Thread(new ParameterizedThreadStart(Close_Driver));
                    th.Start(Ldriver.Select_key(C.No));         //웹브라우저 객체를 매게변수로 넘긴다.

                    th.Join();

                    TefreecaUnit_interface.Add_Command(         //상태를 업데이트 하도록 한다.
                        Command_Client.Updated_Connection,
                        new i_Updated_Connection(C.No, i_Updated_Connection_Type.State_Connect, State_Connect.Close));
                    try
                    {
                        Ldriver.Remove(C.No);
                    }
                    catch
                    {
                        Console.WriteLine("Already remove webdriver : {0}", C.No);
                    }
                }
                break;

                case Unit_Event_Type.Order_Connect:
                {
                    i_connect C = JsonConvert.DeserializeObject <i_connect>(RecieveEventArg.data_string);
                    Command_Connect(C);
                }
                break;

                case Unit_Event_Type.Order_Disconnect:
                {
                }
                break;

                case Unit_Event_Type.Connect_sideBreak:
                {
                    SideBreak_ConnectNo = RecieveEventArg.data_int;
                }
                break;

                default:
                { }
                break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error : {0}", ex.ToString());
                //throw;
            }
        }
示例#2
0
        private static void Commander(command_data_client CMD)
        {
            //Console.WriteLine("Command] {0} : ", ((Command_Client)CMD.Command_code).ToString());
            switch (CMD.Command_code)
            {
                case (int)Command_Client.Updated_Connection_Account: //현재 로그인할수 있는 연결들을 관리하는 메니저.
                    {
                        i_Updated_Connection_Account iuca = (i_Updated_Connection_Account)CMD.data; //내부에서 호출하기 땜에 시리얼라이즈하지 않는다.

                        DataRow[] C = DB_Connection.Select("No = " + iuca.Connect_No);
                        if (C.Length == 1)
                        {
                            C[0]["State_Account_on_connected"] = iuca.State;
                        }
                    }
                    break;
                case (int)Command_Client.Managing_Account: //현재 로그인할수 있는 연결들을 관리하는 메니저.
                    {
                        //Trying_Login 상태인 연결들을 찾아 로그인 체크,
                        DataRow[] C = DB_Connection.Select("State_Account_on_connected =" + (int)State_Account_on_connected.Trying_Login);
                        if (C.Length > 0)
                        {
                            foreach (DataRow Cnt in C)
                            {
                                Make_Client_Event(Unit_Event_Type.Account_Check_Login, (int)Cnt["No"]);
                            }
                        }

                        //상태가 setting 인 연결을 찾아 새로그인을 시킨다.
                        C = DB_Connection.Select("State_Account_on_connected =" + (int)State_Account_on_connected.Setting);
                        if (C.Length > 0)
                        {
                            foreach (DataRow Cnt in C)
                            {
                                i_Account_Set IAS = new i_Account_Set(
                                    (Type_Order)Cnt["Type_order"],
                                    (int)Cnt["No"],
                                    (int)Cnt["Login_Account_no"],
                                    (string)Cnt["Account_ID"],
                                    (string)Cnt["Account_PW"],
                                    (int)Cnt["Order_No"]
                                    );
                                Cnt["State_Account_on_connected"] = State_Account_on_connected.Trying_Login;
                                Make_Client_Event(Unit_Event_Type.Account_Login, new List<object> { IAS });
                            }
                        }
                        //Failure_Login 인 연결은 글쌔..
                    }
                    break;
                case (int)Command_Client.Account_Set: //개별적인 연결에 로그인 계정을 임명하는 명령어. 
                    {
                        //Add_Response((int)candidate[candidate_No]["Unit_No"], Command_Client.Account_Set, ias);
                        i_Account_Set ils = JsonConvert.DeserializeObject<i_Account_Set>(CMD.data.ToString());

                        DataRow[] C = DB_Connection.Select("No =" + ils.Connect_No);

                        if (C.Length != 1)
                            return;

                        C[0]["Login_Account_no"] = ils.Account_No;
                        C[0]["Account_ID"] = ils.ID;
                        C[0]["Account_PW"] = ils.PW;
                        C[0]["State_Account_on_connected"] = State_Account_on_connected.Setting; //첫 세팅.

                        //
                        //여기서 직접 로긴 명령을 내리는것이 아니라 메니저에서 별도로 로긴명령을 내린다.
                        //디비에 정보를 저장하고
                        //이벤트로 크롬드라이브에 로그인 명령을 내린다
                    }
                    break;
                case (int)Command_Client.Close_connect:
                    {
                        int connect_no = int.Parse(CMD.data.ToString());

                        DataRow[] CC = DB_Connection.Select(
                            "No = " + connect_no + " and not State = " + (int)State_Connect.Closing +
                            " and not State = " + (int)State_Connect.Close
                            ); //이미 닫혔거나 닫고 있지 않은경우 실행한다.
                        if (CC.Length == 1)
                        {
                            Make_Client_Event(
                                    Unit_Event_Type.Disconnect_connect,
                                    new List<object> {new i_connect(
                                            (int)CC[0]["No"],
                                            (int)CC[0]["Order_No"],
                                            (string)CC[0]["Connect_URL"],
                                            (Type_Order)CC[0]["Type_order"],
                                            (string)CC[0]["Proxy_host"]) }
                                    );
                        }
                    }
                    break;
                case (int)Command_Client.Set_UnitNo:
                    {
                        int No = Convert.ToInt32(CMD.data);
                        
                        Unit_No = No;
                        Console.WriteLine("Set Unit No] {0}.", Unit_No.ToString());

                        if (None_proxy) //자신의 아이피를 프록시 서버 호스트로 지정.
                            Add_Command(Command_Client.Set_Proxy, Client_IP);
                        else
                            Unit_State = State_Unit.Wait_proxy;

                        Console.WriteLine("Updated State_Unit [{0}]", Unit_State.ToString());
                    }
                    break;
                case (int)Command_Client.Login_success:
                    {
                        i_Login_success ils = JsonConvert.DeserializeObject<i_Login_success>(CMD.data.ToString());

                        User_No = ils.User_No;
                        //Unit_State = State_Unit.Logged;
                        Session = ils.Session;
                        Type_user = ils.Type_user;
                    }
                    break;
                case (int)Command_Client.Set_Proxy: //서버로 부터 프록시 배정 신호가 온다.
                    {
                        string host = (string)CMD.data;

                        if (None_proxy) //다이렉트 아이피 모드
                        {
                            Proxy_host = host;
                            Setted_proxy = true;
                            Console.WriteLine("Setted Direct ip : {0}.", Proxy_host);
                        }
                        else if (host.Length > 8 && Test_proxy(host))
                        {
                            Proxy_host = host;
                            Setted_proxy = true;
                            Console.WriteLine("Setted Proxy : {0}.", Proxy_host);
                            Add_Response(Command_Server.Sucsses_Proxy, host);
                        }
                        else
                        {
                            Setted_proxy = false;
                            Unit_State = State_Unit.Wait_proxy;
                            Add_Response(Command_Server.Failure_Proxy, host);
                            Console.WriteLine("Error Set_Proxy : {0}.", host);
                        }
                    }
                    break;
                case (int)Command_Client.Managing_State: //일단 현재의 상태를 주기적으로 보내는 것으로 하자.
                    {
                        ///=====================================================
                        /// 유닛의 상태를 자동으로 결정하는코드
                        if (Unit_No < 0)
                            return;


                        if (Setted_proxy)
                        {
                            DataRow[] C = DB_Connection.Select("State = " + (int)State_Connect.Connecting
                            + " or State = " + (int)State_Connect.Wait + "");
                            if(Unit_State != State_Unit.Logged && Proxy_host != "")
                                if (C.Length > 0)
                                    Unit_State = State_Unit.Ordering; //연결 상태를 오더 처리중으로 변경.
                                else
                                    Unit_State = State_Unit.Enable; //연결 상태를 오더 처리중으로 변경.
                        }
                        
                        //==========================================
                        //현재의 상태를 주기적으로 보내는 코드.

                        i_State istate = new i_State();

                        istate.State_unit = Unit_State;
                        istate.State_connect = new List<i_Updated_Connection>();

                        foreach (DataRow R in DB_Connection.Rows) //모든 내용.
                        {
                            i_Updated_Connection iuc = new i_Updated_Connection((int)R["No"], i_Updated_Connection_Type.State_Connect, (State_Connect)R["State"]);
                            istate.State_connect.Add(iuc); //모든 커넥션을 추가.

                            if (R["State_Account_on_connected"] != null)
                            {
                                i_Updated_Connection iuc2 = new i_Updated_Connection((int)R["No"], i_Updated_Connection_Type.State_Account_on_connected, (State_Account_on_connected)R["State_Account_on_connected"]);
                                istate.State_connect.Add(iuc2); //모든 커넥션을 추가.
                            }

                            if (R["Login_Account_no"] != null)
                            {
                                i_Updated_Connection iuc3 = new i_Updated_Connection((int)R["No"], i_Updated_Connection_Type.Login_Account_no, (int)R["Login_Account_no"]);
                                istate.State_connect.Add(iuc3); //모든 커넥션을 추가.
                            }

                            //반으시 닫힘을 알리고 삭제되어야 하므로Managing_connecting에서 별도 처리 하기 보다 한번에 여기서 순서에 맞춰 먼저 보내고 삭제,
                            if ((int)R["State"] == (int)State_Connect.Close) //만약 종료되었음을 알리는 신호라면,
                            {
                                Console.WriteLine("Deleted Connection [C[{0}]", iuc.Connect_No);
                                DB_Connection.Rows.Remove(R); //정말 지워지는지 검증필요
                                break;
                            }

                        }
                        Add_Response(Command_Server.State, istate);
                    }
                    break;
                case (int)Command_Client.Managing_connecting:
                    {
                        //연결되어 있는 브라우저의 방송이 종료되었는지 체크하여
                        //종료되었으면 방송을 닫는다.

                        DataRow[] Cr = DB_Connection.Select("State = " + (int)State_Connect.Connected);
                        List<object> i_connect_list = new List<object>();

                        foreach (DataRow R in Cr) //연결된 상태에 있는 커넥션들을 가져와서 이벤트를 발생시킨다.
                        {
                            i_connect ic = new i_connect(
                                            (int)R["No"],
                                            (int)R["Order_No"],
                                            (string)R["Connect_URL"],
                                            (Type_Order)R["Type_order"],
                                            (string)R["Proxy_host"]);
                            i_connect_list.Add(ic);
                        }

                        try
                        {
                            Make_Client_Event(Unit_Event_Type.Check_End_broadcast, i_connect_list);
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }

                        //실패한 연결을 닫는 명령을 내린다.
                        foreach (DataRow C in DB_Connection.Rows)
                        {
                            if((State_Connect)C["State"] == State_Connect.Failure)
                            {
                                Make_Client_Event(
                                    Unit_Event_Type.Disconnect_connect, 
                                    new List<object> {new i_connect(
                                            (int)C["No"],
                                            (int)C["Order_No"],
                                            (string)C["Connect_URL"],
                                            (Type_Order)C["Type_order"],
                                            (string)C["Proxy_host"]) }
                                    );

                            }
                        }

                    }
                    break;
                case (int)Command_Client.set_proxy_success_ok: //일단 현재의 상태를 주기적으로 보내는 것으로 하자.
                    {
                        if (Tester)
                        {
                            Add_Response(Command_Server.Login, new i_Login(
                                Unit_No,
                                "Test_" + Unit_No,
                                "",
                                Type_User.Tester_Unit
                                ));
                        }
                        
                        Unit_State = State_Unit.Enable; //사용가능 상태로 바꿈.
                    }
                    break;
                case (int)Command_Client.order_connect: //연결 명령.
                    {
                        i_connect C = JsonConvert.DeserializeObject<i_connect>(CMD.data.ToString());

                        //Unit_State = State_Unit.Ordering; //연결 상태를 오더 처리중으로 변경.

                        DB_Connection.Rows.Add(C.No, C.Order_No, C.URL, Proxy_host, C.order_type, State_Connect.Connecting, -1,"","", State_Account_on_connected.NotSet);
                        //디비에 등록.
                        try
                        {
                            if (Tefreeca_client_event != null)
                            {
                                Tefreeca_client_EventArgs TC_EvtArgs = new Tefreeca_client_EventArgs();
                                TC_EvtArgs.type = Unit_Event_Type.Order_Connect;

                                i_connect iC = JsonConvert.DeserializeObject<i_connect>(CMD.data.ToString());

                                if(iC.Proxy.Length < 6) //프록시가 지정되어 있지 않은 채 명령이 들어오면 유닛에 지정된 ip를 사용한다.
                                    iC.Proxy = Proxy_host;

                                TC_EvtArgs.data_string = JsonConvert.SerializeObject(iC);
                                
                                // TC_EvtArgs.Data_object_list = new List<object>(new object[] { C }); //connect가 들어있는 리스트를 매개변수로 넘김.
                                Tefreeca_client_event(null, TC_EvtArgs);
                            }
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }
                    break;
                case (int)Command_Client.Updated_Connection:
                    {
                        i_Updated_Connection iuc = (i_Updated_Connection)CMD.data;

                        switch (iuc.Updated_Connection_Type)
                        {
                            case i_Updated_Connection_Type.State_Connect:
                                {
                                    State_Connect State_connect = (State_Connect)iuc.Data;
                                    DataRow[] C = DB_Connection.Select("No = " + iuc.Connect_No + "");

                                    if (C.Length == 1)
                                    {
                                        if ((int)C[0]["State"] == (int)State_connect)
                                            return; //변동없으면 패스.

                                        if ((int)C[0]["State"] == (int)State_Connect.Connecting && //연결상태가 연결중에서 종료쪽으로 바뀌면,
                                            (   State_connect == State_Connect.Failure  ||
                                                State_connect == State_Connect.Close    ||
                                                State_connect == State_Connect.Closing  ))
                                        {
                                            Make_Client_Event(Unit_Event_Type.Connect_sideBreak, iuc.Connect_No);
                                        }

                                        C[0]["State"] = (int)State_connect;
                                        Console.WriteLine("Updated Connection [C[{0}] {1}]", iuc.Connect_No, State_connect.ToString());

                                        if (State_connect == State_Connect.Failure) //연결 실패로 바꾸는 경우.
                                        {
                                            Add_Command(Command_Client.Failure_Counter, (int)C[0]["Order_No"]); //실패 카운트함.
                                        }
                                    }
                                    else
                                        Console.WriteLine("Error Updated_Connection.");
                                }
                                break;
                            case i_Updated_Connection_Type.Login_Account_no:
                                {
                                }
                                break;
                            case i_Updated_Connection_Type.State_Account_on_connected:
                                {
                                }
                                break;

                        }
                    }
                    break;
                case (int)Command_Client.Failure_Counter:
                    {
                        int order_no = (int)CMD.data;

                        ///order에 해당하는 엔트리가 있는지 Faliure_counting에서 검사해 
                        ///Faliure_counting에 있으면
                        ///발생한 애러의 order를 가지고 Faliure_counting에서 조회해 해당 카운트를 올린다.
                        ///없으면 새로 생성,
                        ///Faliure_counting를 관리하는데.. 
                        ///connected인 상태가 하나라도 있으면 삭제,
                        ///
                        ///10을 넘어가는 카운트가 있으면
                        ///실패신호를 보내게 된다. 그리고나면 삭제.
                        ///그리고 실패신호를 저장해두었다가  10회가 넘으면 해당 order를 종료시킨다.

                        if (Faliure_counting.Has_int_key(order_no)) //키가 존재하면, +1한 카운트로 업데이트 하고,
                            Faliure_counting.Update(order_no, (int)Faliure_counting.Select_key(order_no) + 1);
                        else //없으면
                            Faliure_counting.Insert(order_no, 1); //새 테이블을 생성.

                        DataRow[] R = DB_Connection.Select("Order_No = " + order_no + " and State = " + (int)State_Connect.Connected);
                        //해당 order중 연결된 상태의 커넥션이 있다면
                        if (R.Length > 0)
                            if (Faliure_counting.Has_int_key(order_no)) //키가 존재하면, 
                                Faliure_counting.Remove(order_no);  //삭제.

                        if (Faliure_counting.Has_int_key(order_no)) //키가 존재하면, +1한 카운트로 업데이트 하고,
                            if ((int)Faliure_counting.Select_key(order_no) >= 5) //5가 되면,
                                Add_Response(Command_Server.Failure_Connect, order_no);
                    }
                    break;
                case (int)Command_Client.Change_Proxy: //연결실패로 프록시를 바꾸자 하면..
                    {
                        ///모든 연결을 닫고, 그럴 필요 없다. 이미 접속된 연결을 그대로 두고,
                        /// 실패한 접속은 자동으로 닫힐테고,
                        /// 프록시 실패 명령을 보내면 서버는 그 프록시를 사용불가 처리 할 것이다
                        /// 그리고 상태를 wait_proxy로 바꾸면 새로운 프록시가 배정된다.
                        /// 그리고 다시 돌아갈 수 있다.

                        if(Proxy_host != "")
                            Add_Response(Command_Server.Failure_Proxy, Proxy_host);
                        else
                            Console.WriteLine("Error Command_Client.Change_Proxy, host:{0}", Proxy_host.ToString());


                        Unit_State = State_Unit.Wait_proxy;
                    }
                    break;
                case (int)Command_Client.Set_Tester: //연결실패로 프록시를 바꾸자 하면..
                    {
                        Console.WriteLine("Set_Tester_Unit.");
                        if (!Tester)
                        {
                            Tester = true;
                            Add_Response(Command_Server.Login, new i_Login(
                                    Unit_No,
                                    "Test_" + Unit_No,
                                    "",
                                    Type_User.Tester_Unit
                                    ));
                            //모든 연결을 닫는 코드 필요.
                        }
                    }
                    break;
                case (int)Command_Client.Order_Info: //연결실패로 프록시를 바꾸자 하면..
                    {

                    }
                    break;
                case (int)Command_Client.HeartBeat: //연결실패로 프록시를 바꾸자 하면..
                    {
                        
                    }
                    break;
                default:
                    {
                        Command_Client S = (Command_Client)CMD.Command_code;
                        Console.WriteLine("Unknown Command : {0}", S.ToString());
                    }
                    break;
            }
        }