コード例 #1
0
        public ServiceClient(IClientLogic logic, IPAddress hostIP, int port, int interfaceId, long ticket)
        {
            this.logic = logic;

            client = new DynamicClient(hostIP, port);
            tree   = new ProtocolTree();
            root   = new DummyHandler <DummyProtocol>();
            auth   = new LeafProtocolHandler <AuthenticationProtocol>();

            tree.Register(root);
            tree.Register(auth);
            tree.Entry(root);
            tree.ConnectToLeaf(root, auth);
            tree.Connect(root, logic.ProtocolTree);

            app = new ApplicationConnectionManager(client, tree, 3000, 6000);

            auth.NewData += data =>
            {
                switch (data.statusCode)
                {
                case AuthenticationProtocol.StatusCode.Request:
                    Logger.Log("receiving auth request", "ServiceClient");
                    auth.Send(new AuthenticationProtocol
                    {
                        interfaceId = interfaceId,
                        ticket      = ticket,
                        resumeToken = ResumeToken,
                        statusCode  = AuthenticationProtocol.StatusCode.Ack
                    });
                    break;

                case AuthenticationProtocol.StatusCode.Accept:
                    Logger.Log("auth accepted by the host", "ServiceClient");
                    ResumeToken = data.resumeToken;
                    ConnectionAccepted?.Invoke();
                    break;

                case AuthenticationProtocol.StatusCode.Reject:
                    Logger.Log($"auth rejected by the host, {data.reason}", "ServiceClient", Logger.LogType.WARNING);
                    rejected = true;
                    client.CloseConnection();
                    app.Dispose();
                    ConnectionRejected?.Invoke();
                    break;

                default:
                    Logger.Log("invalid auth msg from host", "ServiceClient", Logger.LogType.WARNING);
                    break;
                }
            };

            app.ConnectionLost += () =>
            {
                if (!rejected)
                {
                    ConnectionLost?.Invoke();
                }
            };
        }
コード例 #2
0
        public IntegrationBase()
        {
            server = new MockTCP(wire);
            client = new MockTCP(wire);

            server.other = client;
            client.other = server;

            serverStatefulSession  = FTConnectionController.CreateStatefulSession(server, new StateProvider(), 5000, 8000);
            clientStatelessSession = FTConnectionController.CreateStatelessSession(client, 5000, 8000);

            serverTree.AttachErrorHandler();
            clientTree.AttachErrorHandler();

            serverSerializer = new DataSerializer();
            clientSerializer = new DataSerializer();
            serverSerializer.AttachErrorHandler();
            clientSerializer.AttachErrorHandler();

            serverTree.ConnectToDownstream(serverSerializer);
            serverSerializer.ConnectToDownstream(server);
            server.ConnectToUpstream(serverSerializer);
            serverSerializer.ConnectToUpstream(serverTree);

            clientTree.ConnectToDownstream(clientSerializer);
            clientSerializer.ConnectToDownstream(client);
            client.ConnectToUpstream(clientSerializer);
            clientSerializer.ConnectToUpstream(clientTree);

            serverData     = new LeafProtocolHandler <MockData1>();
            clientData     = new LeafProtocolHandler <MockData1>();
            clientRecovery = new LeafProtocolHandler <MockData2>();

            serverTree.Register(serverStatefulSession);
            serverTree.Register(serverData);
            serverTree.Entry(serverStatefulSession);
            serverTree.ConnectToLeaf(serverStatefulSession, serverData);

            clientTree.Register(clientStatelessSession);
            clientTree.Register(clientData);
            clientTree.Register(clientRecovery);
            clientTree.Entry(clientStatelessSession);
            clientTree.ConnectToLeaf(clientStatelessSession, clientData);
            clientTree.ConnectToLeaf(clientStatelessSession, clientRecovery);

            serverData.NewData     += protocol => { protocol.Verify(); serverDataCount++; };
            clientData.NewData     += protocol => { protocol.Verify(); clientDataCount++; };
            clientRecovery.NewData += protocol => { protocol.Verify(); recoveryCount++; };
        }
コード例 #3
0
        public void TreeMerge()
        {
            Logger       lg    = new Logger();
            ProtocolTree tree1 = new ProtocolTree();
            ProtocolTree tree2 = new ProtocolTree();
            ProtocolTree tree3 = new ProtocolTree();

            tree1.AttachErrorHandler();
            tree2.AttachErrorHandler();
            tree3.AttachErrorHandler();
            MockData1Handler h11 = new MockData1Handler();
            MockData2Handler h12 = new MockData2Handler();
            MockData3Handler h2  = new MockData3Handler();
            LeafProtocolHandler <MockData4> h31 = new LeafProtocolHandler <MockData4>();
            LeafProtocolHandler <MockData3> h32 = new LeafProtocolHandler <MockData3>();

            tree1.Register(h11);
            tree1.Register(h12);
            tree1.Entry(h11);
            tree1.Entry(h12);
            tree2.Register(h2);
            tree2.Entry(h2);
            tree1.Connect(h12, tree2);
            tree3.Register(h31);
            tree3.Register(h32);
            tree3.EntryToLeaf(h31);
            tree3.EntryToLeaf(h32);
            tree1.Entry(tree3);
            tree1.SenderDataReady += obj => tree1.Receive(obj);

            h11.NewData += obj => lg.Log("data11");
            h12.NewData += obj => lg.Log("data12");
            h2.NewData  += obj => lg.Log("data2");
            h31.NewData += obj => lg.Log("data31");
            h32.NewData += obj => lg.Log("data32");
            h11.Send();
            h12.Send();
            h2.Send();
            h31.Send(new MockData4());
            h32.Send(new MockData3());
            lg.Verify(new List <string>
            {
                "data11", "data12", "data12", "data2", "data31", "data32"
            });
        }
コード例 #4
0
        public void ProtocolTree()
        {
            Logger       lg   = new Logger();
            ProtocolTree tree = new ProtocolTree();

            tree.AttachErrorHandler();
            MockData1Handler h1 = new MockData1Handler();
            MockData2Handler h2 = new MockData2Handler();
            MockData3Handler h3 = new MockData3Handler();
            LeafProtocolHandler <MockData4> h4 = new LeafProtocolHandler <MockData4>();
            LeafProtocolHandler <MockData4> h5 = new LeafProtocolHandler <MockData4>();

            tree.Register(h1);
            tree.Register(h2);
            tree.Register(h3);
            tree.Register(h4);
            tree.Register(h5);
            tree.Entry(h1);
            tree.Entry(h2);
            tree.ConnectToLeaf(h1, h4);
            tree.Connect(h2, h3);
            tree.EntryToLeaf(h5);
            tree.SenderDataReady += obj => tree.Receive(obj);

            h1.NewData += obj => lg.Log("data1");
            h2.NewData += obj => lg.Log("data2");
            h3.NewData += obj => lg.Log("data3");
            h4.NewData += obj => lg.Log("data4");
            h5.NewData += obj => lg.Log("data5");
            h1.Send();
            h2.Send();
            h3.Send();
            h4.Send(new MockData4());
            h5.Send(new MockData4());
            lg.Verify(new List <string>
            {
                "data1", "data2", "data2", "data3", "data1", "data4", "data5"
            });
        }
コード例 #5
0
        static void Main(string[] args)
        {
            string     filePath = "E:/test.zip";
            FileStream stream   = new FileStream(filePath, FileMode.Open, FileAccess.Read);

            DynamicListener listener = new DynamicListener(/*IPAddress.Any*/ IPAddress.Parse("192.168.1.73"), 54321);

            // netsh http add urlacl url=http://+:54322/ws user=everyone
            //WsListener listener = new WsListener("http://+:54322/ws/");
            listener.Start();

            //TCPRemoteClient client = new TCPRemoteClient();
            //WsRemoteClient client = new WsRemoteClient();

            ProtocolTree tree = new ProtocolTree();
            LeafProtocolHandler <Data> leaf = new LeafProtocolHandler <Data>();
            LeafProtocolHandler <Rec>  rec  = new LeafProtocolHandler <Rec>();
            LeafProtocolHandler <Done> done = new LeafProtocolHandler <Done>();

            tree.Register(leaf);
            tree.Register(rec);
            tree.Register(done);
            tree.EntryToLeaf(leaf);
            tree.EntryToLeaf(rec);
            tree.EntryToLeaf(done);

            ApplicationConnectionManager app = null;

            //TcpClient cl = null;
            //WebSocket cl = null;

            bool finish = false;
            Task task   = null;

            bool connected = false;

            void clean()
            {
                Console.WriteLine("conn lost + ");
                connected = false;
                Console.WriteLine("connection is down");
                reconn();
            }

            void rd(Rec data)
            {
                task = new Task(() =>
                {
                    Console.WriteLine("sen task started");
                    long p = data.seq;
                    while (p < stream.Length)
                    {
                        if (!connected)
                        {
                            Console.WriteLine("sen task ended"); return;
                        }
                        long blockSize = Math.Min(65536, stream.Length - p);
                        stream.Seek(p, SeekOrigin.Begin);
                        byte[] b = new byte[blockSize];
                        stream.Read(b, 0, (int)blockSize);
                        p     += blockSize;
                        Data d = new Data(b);
                        Console.WriteLine("sen task send");
                        leaf.Send(d);
                        Console.WriteLine("sen task send, done");
                        Console.WriteLine($"{blockSize} bytes sent, total {p} sent");
                        Thread.Sleep(15);
                    }
                    Console.WriteLine("sen task fined");
                    done.Send(new Done());
                });
                task.Start();
            }

            void fin(Done d) => finish = true;

            // client.ConnectionLost += clean;
            rec.NewData  += rd;
            done.NewData += fin;

            void reconn()
            {
                while (true)
                {
                    if (connected)
                    {
                        return;
                    }
                    try
                    {
                        Console.WriteLine("waiting...");
                        DynamicRemoteClient cl = listener.Accept();
                        if (app != null)
                        {
                            app.Dispose();
                        }
                        app = new ApplicationConnectionManager(cl, tree, 1000, 4000);
                        app.ConnectionLost += clean;
                        cl.Activate();
                        //cl = listener.AcceptWsClient();
                        connected = true;
                        Console.WriteLine("accepted! " /* + cl.Client.RemoteEndPoint.ToString()*/);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("network error");
                        Thread.Sleep(1000);
                        continue;
                    }
                }
            }

            reconn();

            while (true)
            {
                if (finish)
                {
                    Console.WriteLine("finished!!");
                    break;
                }
                else
                {
                    Thread.Sleep(500);
                }
            }
        }
コード例 #6
0
        private void ListenerTask()
        {
            while (true)
            {
                Log("trying to accept a new client ...");

                DynamicRemoteClient remoteClient = null;
                try
                {
                    remoteClient = listener.Accept();
                }
                catch
                {
                    Log("unable to accept client", LogType.ERROR);
                    Thread.Sleep(2000);
                    continue;
                }

                ProtocolTree tree = new ProtocolTree();
                DummyHandler <DummyProtocol> treeRoot = new DummyHandler <DummyProtocol>();
                LeafProtocolHandler <AuthenticationProtocol> authHandler
                    = new LeafProtocolHandler <AuthenticationProtocol>();
                tree.Register(treeRoot);
                tree.Register(authHandler);
                tree.Entry(treeRoot);
                tree.ConnectToLeaf(treeRoot, authHandler);

                ApplicationConnectionManager app =
                    new ApplicationConnectionManager(remoteClient, tree, new DummyProvider(), 3000, 6000);

                applicationConnections.Add(app, -1);

                authHandler.NewData += data =>
                {
                    if (data.statusCode != AuthenticationProtocol.StatusCode.Ack)
                    {
                        Log("invalid auth status code: ACK", LogType.ERROR);
                        return;
                    }
                    void accept()
                    {
                        long resumeToken = 0;

                        if (!resumeTokens.ContainsKey(data.interfaceId))
                        {
                            resumeToken = Rnd64();
                            resumeTokens.Add(data.interfaceId, resumeToken);
                        }
                        else
                        {
                            resumeTokens[data.interfaceId] = resumeTokens[data.interfaceId];
                        }
                        Log($"accept the client {data.interfaceId}, token = {resumeToken}");

                        authHandler.Send(new AuthenticationProtocol
                        {
                            statusCode  = AuthenticationProtocol.StatusCode.Accept,
                            resumeToken = resumeToken
                        });
                    }

                    void reject(string reason)
                    {
                        authHandler.Send(new AuthenticationProtocol
                        {
                            statusCode = AuthenticationProtocol.StatusCode.Reject,
                            reason     = reason
                        });
                    }

                    if (data.interfaceId < 0 || data.interfaceId >= logic.MaxConnection)
                    {
                        Log($"reject the client since the interface {data.interfaceId} is not valie", LogType.WARNING);
                        reject("invalid interface id");
                        return;
                    }

                    lock (interfaceLock)
                    {
                        bool IsExistingUser = connectionInterruptTimers.ContainsKey(data.interfaceId);
                        if (IsExistingUser && data.resumeToken != resumeTokens[data.interfaceId])
                        {
                            Log($"reject the client since the resume token {data.resumeToken} is not correct", LogType.WARNING);
                            reject("wrong resume token");
                            return;
                        }
                        if (!serviceBackupData.connectionInterfaces[data.interfaceId].Enabled && !IsExistingUser)
                        {
                            Log($"reject the client since the interface {data.interfaceId} is not available", LogType.WARNING);
                            reject("interface is not available");
                            return;
                        }
                        if (serviceBackupData.connectionInterfaces[data.interfaceId].Ticket != data.ticket)
                        {
                            Log($"reject the client since the ticket {data.ticket} is not correct", LogType.WARNING);
                            reject("invalid ticket");
                            return;
                        }

                        Log("auth is valid, accept the client");
                        accept();

                        tree.Connect(treeRoot, logic.GetProtocolTree(data.interfaceId));
                        applicationConnections[app] = data.interfaceId;

                        if (IsExistingUser)
                        {
                            Log($"client with id {data.interfaceId} comes back", LogType.WARNING);
                            RemoveTimer(data.interfaceId);
                            logic.OnClientResume(data.interfaceId);
                        }
                        else
                        {
                            Log($"calling logic OnClientEnter and close interface {data.interfaceId}");
                            CloseInterface(data.interfaceId);
                            logic.OnClientEnter(data.interfaceId);
                        }
                    }
                };

                app.ConnectionLost += () =>
                {
                    app.Dispose();
                    int id = applicationConnections[app];
                    applicationConnections.Remove(app);

                    Log($"client {id} is leaving", LogType.WARNING);

                    if (id >= 0)
                    {
                        logic.GetProtocolTree(id).Detach();

                        if (logic.CanResume(id))
                        {
                            System.Timers.Timer timer = new System.Timers.Timer(20000)
                            {
                                AutoReset = false
                            };
                            timer.Elapsed += (s, e) =>
                            {
                                lock (interfaceLock)
                                {
                                    Log($"client {id} leave permanently", LogType.WARNING);
                                    timer.Dispose();
                                    connectionInterruptTimers.Remove(id);
                                    resumeTokens.Remove(id);
                                    logic.OnClientLeave(id);
                                }
                            };
                            timer.Start();
                            connectionInterruptTimers.Add(id, timer);
                            logic.OnClientDisconnect(id);
                            Log($"start timer to wait for client {id} to come back", LogType.WARNING);
                        }
                        else
                        {
                            logic.OnClientLeave(id);
                            Log($"client {id} leave permanently since logic cannot resume now", LogType.WARNING);
                        }
                    }
                };

                remoteClient.Activate();

                Logger.Log("sending auth data ...", "ServiceHost");
                authHandler.Send(new AuthenticationProtocol {
                    statusCode = AuthenticationProtocol.StatusCode.Request
                });
            }
        }
コード例 #7
0
        static void Main(string[] args)
        {
            string filePath = "E:/r.txt";

            if (!File.Exists(filePath))
            {
                Console.WriteLine("transfer complete");
                return;
            }

            StreamReader r = new StreamReader(filePath);

            ST state = new ST();

            state.seq = Convert.ToInt64(r.ReadLine());

            r.Close();

            DynamicClient client = new DynamicClient(IPAddress.Parse("192.168.1.73"), 54321);
            //WsClient client = new WsClient("ws://192.168.1.73:54322/ws");

            ProtocolTree tree = new ProtocolTree();
            LeafProtocolHandler <Data> leaf = new LeafProtocolHandler <Data>();
            LeafProtocolHandler <Rec>  rec  = new LeafProtocolHandler <Rec>();
            LeafProtocolHandler <Done> done = new LeafProtocolHandler <Done>();

            tree.Register(leaf);
            tree.Register(rec);
            tree.Register(done);
            tree.EntryToLeaf(leaf);
            tree.EntryToLeaf(rec);
            tree.EntryToLeaf(done);

            ApplicationConnectionManager app = new ApplicationConnectionManager(client, tree, state, 1000, 2000);

            bool finish = false;

            void conn()
            {
                while (true)
                {
                    Console.WriteLine("connecting... ");
                    if (client.Connect())
                    {
                        Console.WriteLine("connected!!!! ");
                        break;
                    }
                    else
                    {
                        Console.WriteLine("connect failed");
                        Thread.Sleep(1000);
                    }
                }
            }

            /*client.ConnectionLost += () =>
             * {
             *  conn();
             * };*/

            app.ConnectionLost += () =>
            {
                conn();
            };

            string     wpath = "E:/recv.zip";
            FileStream ws    = new FileStream(wpath, FileMode.Append, FileAccess.Write);

            ws.Seek(state.seq, SeekOrigin.Begin);

            leaf.NewData += d =>
            {
                try
                {
                    ws.Write(d.data, 0, d.data.Length);
                    ws.Flush();
                    state.seq += d.data.Length;
                    File.WriteAllText(filePath, state.seq.ToString());
                    Console.WriteLine($"received {d.data.Length}, now pointer is {state.seq} ");
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            };

            done.NewData += obj =>
            {
                finish = true;
                File.Delete(filePath);
            };

            conn();

            while (true)
            {
                if (finish)
                {
                    Console.WriteLine("finished!!");
                    break;
                }
                Thread.Sleep(100);
            }
        }