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(); } }; }
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++; }; }
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" }); }
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" }); }
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); } } }
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 }); } }
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); } }