Last active
November 25, 2016 02:22
-
-
Save yallie/1e31bef306f7c53db8b9e9e23187c10f to your computer and use it in GitHub Desktop.
Zyan authenticated peer-to-peer example (caution: no error handling)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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