-
Notifications
You must be signed in to change notification settings - Fork 3
Home
#Welcome to the Vaser wiki!
This document is for version 1.1.18+
Important: Please look at my other project VaserChat for a live vaser demo application!
Click on this link for a live demo: VaserChatv1.1.7.zip or ClickOnce setup.exe App
###New Features:
- Event based communication
- added “OnEmptyBuffer” event on links
- QoS packet priority
- “Portal.Finalize()” is now obsolete
- Added packet dispacher
- Added Xamarin iOS Support
- Added NetCore Support
###Planned Features:
- a better wikisite
- the release of the file transfer and content delivery library
Example:
Step by step:
- Using directives
- Build a container
- Initialize a portal collection
- Start the server
- delegate the events
- send a message
- receive a message
- Reqeust/response pattern
- Channel pattern
###Using directives:
using Vaser; // for normal networking usage
using Vaser.OON; // advanced functionality for request/response pattern and data channeling
using Vaser.ConnectionSettings; // contains the connection settings classes
###Build a container:
// Build your container for transmitting your data
// One message is limited to 65000 bytes
// Note that your container needs an ID for identifying which one is used
// For sending you create a new instance and giving the container to a portal
public class TestContainer : Container
{
// be careful by using write protected 'const' container IDs for 'switch', do not use 'public'
internal const ushort myContainerID = 1;
// Only public, non-static and standard datatypes can be transmitted
public string message = "default message";
// Also 1D arrays are possible
public int[] array = new int[1000];
}
###Initialize a portal collection:
// Before a server or a client can be created, you need a portal collection and portals
// delegate your data processing function to the portal event handler
// Note: The Portal ID is the priority of the QoS management. Please set all file transfers on ID 255!
Portal system = new Portal(100); // Portal ID 100 - first priority
system.IncomingPacket += OnSystemPacket;
Portal login = new Portal(101); // Portal ID 101 - second priority
login.IncomingPacket += OnLoginPacket;
Portal files = new Portal(255); // Portal ID 255 - last priority
files.IncomingPacket += OnFilesPacket;
PortalCollection PColl = new PortalCollection(); // The portal collection
// portals can be used with multiple collections
PColl.RegisterPortal(system);
PColl.RegisterPortal(login);
PColl.RegisterPortal(files);
// Use for every function a separate container
TestContainer con1 = new TestContainer();
static void OnSystemPacket(object p, PacketEventArgs e)
{
// ToDo
// for exemple: you can get a custom attached object from your link
Client c = (Client)e.lnk.AttachedObject;
}
// Use for every function a separate container
TestContainer con2 = new TestContainer();
static void OnLoginPacket(object p, PacketEventArgs e)
{
// ToDo
}
// Use for every function a separate container
TestContainer con3 = new TestContainer();
static void OnFilesPacket(object p, PacketEventArgs e)
{
// ToDo
}
###Start the server:
// Start the server
// The Server is now listen on port 1000 on all adapters.
// The stream is secured and encrypted by Kerberos. More info at: https://msdn.microsoft.com/en-us/library/bb742516.aspx
// Typical used in Domain infrastructures.
// Supported Modes:
// - Not Encrypted
// - Kerberos
// - SSL TLS 1.2
// Portal Collection: the collection you have created
VaserKerberosServer vkerberos = new VaserKerberosServer();
VaserServer Server = new VaserServer(System.Net.IPAddress.Any, 1000, PColl, vkerberos);
// Delegate your action processing function to the server event handler
Server.NewLink += OnNewLink;
Server.DisconnectingLink += OnDisconnectingLink;
// start the server
Server.Start();
Console.WriteLine("Server has started.");
// you can now pause your console
Console.ReadKey();
###Event handling functions:
// Use for every function a separate container
TestContainer con4 = new TestContainer();
static void OnNewLink(object p, LinkEventArgs e)
{
Console.WriteLine("Client connected from IP: " + e.lnk.IPv4Address);
// Delegate a function if the buffer of the link is empty
// see at “Send a message” for more details
e.lnk.EmptyBuffer += OnEmptyBuffer;
//To do: add the link to your connected client list
// you can attach a custom ID and an object the link
// create a client class and attach it to the link
e.lnk.AttachedID = myID;
e.lnk.AttachedObject = myObject;
// new links needs to be accepted
e.lnk.Accept();
}
// Use for every function a separate container
TestContainer con5 = new TestContainer();
static void OnDisconnectingLink(object p, LinkEventArgs e)
{
Console.WriteLine("Client disconnected from IP: " + e.lnk.IPv4Address);
}
// Use for every function a separate container
TestContainer con6 = new TestContainer();
static void OnEmptyBuffer(object p, LinkEventArgs e)
{
// Waring: operate threadsafe here!
Console.WriteLine("OnEmptyBuffer called!");
}
###Stoping a Server:
// Stops the server
Server.Stop();
###Connect a client:
// First, initialize the portals like on the server side
try
{
// Connect the client to the Server
// Supported Modes:
// - Not Encrypted
// - Kerberos
// - SSL TLS 1.2
// Portal Collection: the collection you have created
VaserKerberosClient ckerberos = new VaserKerberosClient();
Link lnk = VaserClient.ConnectClient("localhost", 1000, PColl, ckerberos);
// delegate your disconnecting function to the disconnecting event handler
lnk.Disconnecting += OnDisconnectingLink;
}
catch
{
MessageBox.Show("can't connect to " + tb_ServerAddress.Text);
return;
}
###Disconnect a client:
lnk.Dispose();
###Send a message:
// Create a new container, should be reused
// Note: the container is not threadsafe
TestContainer con = new TestContainer();
// Save the message in the container
con.message = "transmitting a message via Vaser.";
// Send the message through the portal to the client
system.SendContainer(link, con, 1, 1);
// Hint: the last two digits are the containerID and the objectID
// -> system.SendContainer(link, con, containerID, objectID);
// These are the <Packet_Recv>.ContainerID and <Packet_Recv>.ObjectID on the receive side
// You can send as well empty packets for commands:
// system.SendContainer(link, null, 2, 1);
// if you want that a link rises the empty buffer event use this:
system.SendContainer(link, null, TestContainer.myContainerID, 1, true);
###Receive a message:
// a packet was send -> system.SendContainer(link, con, containerID, objectID);
public void OnLoginPacket(object sender, PacketEventArgs e)
{
try
{
// convert the attached object back
Client c = (Client)e.lnk.AttachedObject;
// assign your used container
switch (e.pak.ContainerID)
{
case TestContainer.myContainerID: // packet ID 1
// To do: packet logic here
// try to decrypt the incoming packet
TestContainer con = new TestContainer(); // Better to use an existing container
if(con.UnpackContainer(e.pak, e.portal)) // Is true if the decode of the packet was successful
{
Console.WriteLine(con.message);
} // maybe on false disconnect the client?
break;
}
}
catch
{
// On any error, disconnect the client
e.lnk.Dispose();
}
}
##Reqeust/response pattern:
###Request receive class on the server side.
using System;
using Vaser;
using Vaser.OON;
namespace test_server
{
public class TestRequest : cRequest
{
TestContainer con1 = new TestContainer();
public override void IncomingRequest(object p, PacketEventArgs e)
{
if (e.pak != null && con1.UnpackContainer(e.pak, e.portal))
{
Console.WriteLine(con1.test);
con1.test = "Hello Back!";
RequestResponse(con1);
}
else
{
RequestResponse(null);
}
}
}
}
###Response send and receive class on the client side.
using System;
using Vaser;
using Vaser.OON;
namespace test_client
{
public class TestRequest : cRequest
{
TestContainer con1 = new TestContainer();
public cStatus myRequestStarter(string myMessage, Link lnk)
{
con1.test = myMessage;
return StartRequest(lnk, con1);
}
TestContainer con2 = new TestContainer();
public override void RequestResult(object p, PacketEventArgs e)
{
if (e.pak != null && con2.UnpackContainer(e.pak, e.portal))
{
Console.WriteLine(con2.test);
SetDone("myResult");
}
else
{
SetError("Decode error.");
}
}
}
}
###Register the request at the PortalCollection, same goes for the channeling.
Portal system = new Portal(100);
PortalCollection PC = new PortalCollection();
PC.RegisterPortal(system);
system.IncomingPacket += OnSystemPacket;
TestRequest myRequest = new TestRequest();
PC.RegisterRequest(myRequest, system, 501);
TestChannel myChannel = new TestChannel();
PC.RegisterChannel(myChannel, system, 502);
// ... start your server here...
// usage:
cStatus requestStatus = myRequest.myRequestStarter("Hello World!", clientLink);
requestStatus.Wait();
Console.WriteLine((string)requestStatus.ResultObject);
##Channel pattern:
###Server side.
using System;
using Vaser;
using Vaser.OON;
namespace test_server
{
public class TestChannel : cChannel
{
TestContainer con1 = new TestContainer();
public void mySendStarter(string myMessage, Link lnk)
{
con1.test = myMessage;
SendPacket(con1, lnk);
}
TestContainer con2 = new TestContainer();
public override void IncomingPacket(object p, PacketEventArgs e)
{
if (e.pak != null && con2.UnpackContainer(e.pak, e.portal))
{
Console.WriteLine(con2.test);
con2.test = "Hello Back channel!";
SendPacket(con2);
}
else
{
Console.WriteLine("Decode error!");
}
}
}
}
###On the client side.
using System;
using Vaser;
using Vaser.OON;
namespace test_client
{
public class TestChannel : cChannel
{
TestContainer con1 = new TestContainer();
public void mySendStarter(string myMessage, Link lnk)
{
con1.test = myMessage;
SendPacket(con1, lnk);
}
TestContainer con2 = new TestContainer();
public override void IncomingPacket(object p, PacketEventArgs e)
{
if (e.pak != null && con2.UnpackContainer(e.pak, e.portal))
{
Console.WriteLine(con2.test);
}
else
{
Console.WriteLine("Decode error!");
}
}
}
}