Skip to content

Instantly share code, notes, and snippets.

@yallie
Last active November 25, 2016 02:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yallie/1e31bef306f7c53db8b9e9e23187c10f to your computer and use it in GitHub Desktop.
Save yallie/1e31bef306f7c53db8b9e9e23187c10f to your computer and use it in GitHub Desktop.
Zyan authenticated peer-to-peer example (caution: no error handling)
// http://zyan.com.de
//
// Compile using: csc test.cs /r:Zyan.Communication.dll
//
// Start up test.exe several times (up to 3 peers).
// Every process acts as a server and a client at the same time.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Zyan.Communication;
using Zyan.Communication.Protocols.Tcp;
using Zyan.Communication.Security;
using Hash = System.Collections.Hashtable;
class Program
{
const int MaxPeers = 3;
const int BasePortNumber = 9876;
const string AppName = "AuthenticatedPeersDemo";
static void Main()
{
// try to find the first free server port
foreach (var port in Enumerable.Range(BasePortNumber, MaxPeers))
{
try
{
StartServer(port);
return;
}
catch
{
Console.WriteLine("Port {0} is taken, trying the next...", port);
}
}
Console.WriteLine("Too many peers: all ports are taken.");
}
// ------------ Server code --------------
class MyAuthProvider : IAuthenticationProvider
{
public AuthResponseMessage Authenticate(AuthRequestMessage authRequest)
{
// here you check if your login/password is in the database
if (authRequest.Credentials["Login"].ToString() == "Hacker" &&
authRequest.Credentials["Password"].ToString() == "Pa55w0rd")
{
// ok
return new AuthResponseMessage
{
Success = true,
AuthenticatedIdentity = new GenericIdentity("Hacker")
};
}
// fail
return new AuthResponseMessage
{
Success = false,
ErrorMessage = "Access denied"
};
}
}
static void StartServer(int port)
{
var auth = new MyAuthProvider();
var proto = new TcpDuplexServerProtocolSetup(port, auth, encryption: true);
using (var host = new ZyanComponentHost(AppName, proto))
{
host.RegisterComponent<IService, Service>();
Console.WriteLine("Server started on port: {0}.", port);
Console.WriteLine("Enter a message to send to all peers...");
var message = Console.ReadLine();
// connect to peers
var peers = ConnectToAllExcept(port);
while (!string.IsNullOrWhiteSpace(message))
{
foreach (var peer in peers)
{
Console.WriteLine("Calling peer: {0}", peer.ServerUrl);
var proxy = peer.CreateProxy<IService>();
proxy.Hello(message);
}
Console.WriteLine("Enter a message, empty line to exit...");
message = Console.ReadLine();
}
Console.WriteLine("Closing connections...");
foreach (var peer in peers)
{
Console.WriteLine("Disconnecting from {0}", peer.ServerUrl);
peer.Dispose();
}
}
}
public class Service : IService
{
public void Hello(string format, params object[] args)
{
var color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(format, args);
Console.ForegroundColor = color;
}
}
// ------------ Shared code --------------
public interface IService
{
void Hello(string format, params object[] args);
}
// ------------ Client code --------------
static IEnumerable<ZyanConnection> ConnectToAllExcept(int port)
{
// connect to all peers in parallel
var tasks =
from p in Enumerable.Range(BasePortNumber, MaxPeers)
where p != port
select ConnectTo(p);
// wait until all connections are established, skip invalid
return Task.WhenAll(tasks).Result.Where(c => c != null);
}
static Task<ZyanConnection> ConnectTo(int port)
{
return Task.Run(() =>
{
try
{
// prepare login/password
var credentials = new Hash();
credentials["Login"] = "Hacker";
credentials["Password"] = "Pa55w0rd";
// use encrypted duplex tcp protocol
var proto = new TcpDuplexClientProtocolSetup(encryption: true);
var url = proto.FormatUrl("localhost", port, AppName);
// connect
var connection = new ZyanConnection(url, proto, credentials, false, true);
connection.Error += (s, e) =>
{
Console.WriteLine("Error: {0}", e.Exception.Message);
e.Action = ZyanErrorAction.Ignore;
};
Console.WriteLine("Connected to {0}", url);
return connection;
}
catch
{
// peer not listening, skip
return null;
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment