-
Notifications
You must be signed in to change notification settings - Fork 3
Home
Phil edited this page Feb 20, 2018
·
27 revisions
This document is for version 1.1.18+
Table of Contents:
- Overview of vaser
- Using directives
- Build a container
- Event handling functions
- Initialize a portal collection
- Start the server
- Connect a client
- Send a message
- Receive a message
- Disconnect a client
- Stop the server
- Reqeust/response pattern
- Channel pattern
The Vaser API and reference catalog can be found here.
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
- 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
- Added Unity Support
- a better wikisite
- the release of the file transfer and content delivery library
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 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];
}
When a Client connects to a Server, Vaser raises standard Events like 'on new connection', 'on disconnect' or when the buffer of the sending queue is empty.
// 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 your own client class and attach it to the link
// Note: Vaser has no client class, this is an example
Client myClient = new Client();
myClient.lnk = e.lnk; // attach the link to the client class
e.lnk.AttachedID = myID;
e.lnk.AttachedObject = myClient;
// 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);
// for exemple: you can get a custom attached object from your link
Client myClient = (Client)e.lnk.AttachedObject;
}
// Use for every function a separate container
TestContainer con6 = new TestContainer();
static void OnEmptyBuffer(object p, LinkEventArgs e)
{
// Warning: operate threadsafe here!
Console.WriteLine("OnEmptyBuffer called!");
}
The portals are attached to the data processing methods.
// 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!
static Portal system = null;
static Portal login = null;
static Portal files = null;
static PortalCollection PColl = null;
static void CreatePortalCollection()
{
system = new Portal(100); // Portal ID 100 - first priority
system.IncomingPacket += OnSystemPacket;
login = new Portal(101); // Portal ID 101 - second priority
login.IncomingPacket += OnLoginPacket;
files = new Portal(255); // Portal ID 255 - last priority
files.IncomingPacket += OnFilesPacket;
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 myClient = (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
// 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
static VaserKerberosServer vkerberos = null;
static VaserServer Server = null;
static void StartServer()
{
CreatePortalCollection();
vkerberos = new VaserKerberosServer();
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();
}
// First, initialize the portals like on the server side
// Connect the client to the Server
// Supported Modes:
// - Not Encrypted
// - Kerberos
// - SSL TLS 1.2
// Portal Collection: the collection you have created
static Link ConnectClient(string ServerAddress, int Port)
{
try
{
if(PColl == null) CreatePortalCollection();
VaserKerberosClient ckerberos = new VaserKerberosClient();
Link lnk = VaserClient.ConnectClient(ServerAddress, Port, PColl, ckerberos);
// delegate your disconnecting function to the disconnecting event handler
lnk.Disconnecting += OnDisconnectingLink;
return lnk;
}
catch
{
MessageBox.Show("can't connect to " + ServerAddress + ":" + Port);
return null;
}
}
// 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);
// 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)) // 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();
}
}
lnk.Dispose();
// Stops the server
Server.Stop();
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 (con1.UnpackContainer(e.pak))
{
Console.WriteLine(con1.test);
con1.test = "Hello Back!";
RequestResponse(con1);
}
else
{
RequestResponse(null);
}
}
}
}
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 (con2.UnpackContainer(e.pak))
{
Console.WriteLine(con2.test);
SetDone("myResult");
}
else
{
SetError("Decode error.");
}
}
}
}
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);
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 (con2.UnpackContainer(e.pak))
{
Console.WriteLine(con2.test);
con2.test = "Hello Back channel!";
SendPacket(con2);
}
else
{
Console.WriteLine("Decode error!");
}
}
}
}
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 (con2.UnpackContainer(e.pak))
{
Console.WriteLine(con2.test);
}
else
{
Console.WriteLine("Decode error!");
}
}
}
}