Welcome to the Tutorials, here you can learn how to use certain aspects of this Library
- Note
- As this is an alpha release, there is bound to be unstable, barely useable, bugy experience.
Connections
This shows you how to handle anything related to connections You can jump to Practical Example for a practical and proper way to Start a new connection.
For the Proper use and setup of the Connection Ìnstances you have to go through 5 steps:
Instantiate a new Connection object
Never call new Connection()
to get a new object instance instead there is 2 methods you can use (Depending On your use case)
In case of a Single Connection
Then preferably Use the global instantiator and always use the Global Instance for sending/receiving requests
Connection.Instantiate()
.SetHost("<URL>")
.SetPort(<PORT>);
In case of multiple Connections
Then create instances using the Instantiate(string, int) Method
Connection cnx = Connection.Instantiate(
"<URL>",
<PORT>
);
- Note
- Using Method 1 or 2 is purely personal choice, however for the Sake of this tutorial we'll be using the Method 1 for the following examples
Set Event CallBacks
SNF Connections currenty has 5 Event Callbacks each serving a purpose
- Warning
- Never Set any Event Callback after(if it connected) and/or while Connecting
OnConnection
When is it Called?: This Event will raise it's call back when a connection was established between the Client and Server and the SNF Protocol has finished the initial handshake
Type of CallBack: SimpleCB
How to Set: SetOnConnection(SimpleCB)
Method 1:
- Define the callback
void OnConnectCallBack() {
...
...
}
- Set the CallBack
Connection cnx;
...
cnx.SetOnConnection(OnConnectCallBack);
...
Method 2:
- Define the callback and Set it directly
...
cnx.SetOnConnection(
() => {
...
...
}
);
...
OnException
When is it Called?: This Event will raise a certain(and possibly unknown) exception was called and wasn't handled properly by SNFClient
Type of CallBack: ExceptionCB
How to Set: SetOnException(ExceptionCB)
Method 1:
- Define the callback
void OnExceptionCallBack(Exception ex) {
...
...
}
- Set the CallBack
Connection cnx;
...
cnx.SetOnException(OnExceptionCallBack);
...
Method 2:
- Define the callback and Set it directly
...
cnx.SetOnException(
(Exception ex) => {
...
...
}
);
...
OnSNFFail
When is it Called?: This Event will be raised when SNF Protocol has failed the initial handshake
Type of CallBack: SimpleCB
How to Set: SetOnSNFFail(SimpleCB)
Method 1:
- Define the callback
void OnSNFFailCallBack() {
...
...
}
- Set the CallBack
Connection cnx;
...
cnx.SetOnSNFFail(OnSNFFailCallBack);
...
Method 2:
- Define the callback and Set it directly
...
cnx.SetOnSNFFail(
() => {
...
...
}
);
...
OnSocketFail
When is it Called?: This Event will be raised when the Socket Connection between the client and the Server has raised a SocketException
Type of CallBack: SocketExceptionCB
How to Set: SetOnSocketFail(SocketExceptionCB)
Method 1:
- Define the callback
void OnSocketFailCallBack(SocketException ex) {
...
...
}
- Set the CallBack
Connection cnx;
...
cnx.SetOnSocketFail(OnSocketFailCallBack);
...
Method 2:
- Define the callback and Set it directly
...
cnx.SetOnSNFFail(
(SocketException ex) => {
...
...
}
);
...
OnTimeout
When is it Called?: This Event will be raised when the Connection between the client and the Server has exceeded the timeout limit set by AwaitConnection(..)
Type of CallBack: SimpleCB
How to Set: SetOnTimeout(SimpleCB)
Method 1:
- Define the callback
void OnSocketFailCallBack(SocketException ex) {
...
...
}
- Set the CallBack
Connection cnx;
...
cnx.SetOnSocketFail(OnSocketFailCallBack);
...
Method 2:
- Define the callback and Set it directly
...
cnx.SetOnSNFFail(
(SocketException ex) => {
...
...
}
);
...
Connect
To Connect is pretty Simple you, just call Connect
- Note
- Always configure the Connection and the event Callback before calling Connect
- Warning
- Connect May Return
null
so be Aware
Wait for the Connection
To Connect is pretty Simple you, just call AwaitConnection(int) Which Counts in Miliseconds AwaitConnection(TimeSpan) that uses TimeSpan
. I will only give an example of the former
- Warning
- Always wait for the connection after calling Connect
...
cnx.AwaitConenction(5000);
...
Send Requests
Assuming you have instantiated a new Request Object and Set it properly, we can send it according to your use case
- Note
- Preferably Always Send after the Connection Instance has Connected (eg isConnected returns
true
)
In case of a non-Global Instance
For this case (Assuming cnx
is your Connection Instance and that Rqst
is your Request instance that you want to send ) you can use Send(Request)
In case of a Global Instance
For this case you can use the same Method as the In case of a non-Global Instance( Method 1 ) or the Function Specefic to Global Instances (Method 2) (Assuming that Rqst
is your Request instance that you want to Send )
Method 1 Using Send(Request)
...
Connection cnx = Connection.get();
cnx.Send(Rqst)
Connection.get().Send(Rqst);
...
Method 2 Using InstanceSend(Request)
...
Connection.InstanceSend(Rqst);
...
Practical Example
In this Example I'm gonna create a Console that created a Global Connection instance that connects into a Server Hosted in the same machine on Port 9114
namespace Example
{
public class Program
{
public static void Main(string[] args)
{
() => {
Console.WriteLine("Connected");
}
)
.SetOnSocketFail(
(ex) => {
Console.WriteLine("SocketFailed: " + ex.ToString());
}
)
.SetOnSNFFail(
() => {
Console.WriteLine("SNF HandShake Failed");
}
)
.SetOnException(
(ex) =>
{
Console.WriteLine("Unknown Exception" + ex.ToString());
}
)
.Connect()?
...
}
}
}
Objects of this class are what controls and handles Connections to the Host.
Definition Connection.cs:14
Connection SetPort(int Port)
Sets the connection host's port for this instance.
Definition Connection.cs:250
Connection SetOnConnection(SimpleCB OnConnect)
Sets The callbackto be called Upon Connection.
Definition Connection.cs:268
Connection SetHost(string Host)
Set's the connection host for this instance.
Definition Connection.cs:230
Connection AwaitConnection(TimeSpan timeout)
Block Until the instance is Connected.
Definition Connection.cs:361
static Connection Instantiate(string host, int Port)
Instantiates a new Global Connection Instance.
Definition Connection.cs:45
This Class Defined THe Base OPCode Structure for Basic SNF Functioning.
Definition OPCode.cs:749
static void Initialize()
Initializes OPCode.Base.
Definition OPCode.cs:824
Objects of this class Define the action to do to the host.
Definition OPCode.cs:11
Definition Callbacks.cs:5
OPCodes
Setting up new OPCodes
- Warning
- Although you can define new opcode, the current version of SNF Server doesnt let you make use of user-defined Commands as of 0.0.1-alpha
One thing to note is that you do not define whole OPCodes but you define each part of the OPCode one by one with a String definitoin of each Member, which means you define the Category, then the Sub-Category and so on
- Warning
- Never Add/Modify Base OPCode Members!
- Note
- Every OPCode Member that is of Command Rank, it will have always by default a Detail 0 called DET_UNDETAILED
Example Let's Say we have to define this hierachy
- Category 1 its definition is "Category for Vehicle Commands"
- Sub Category 1 "Subcategory for Vehicle Screen Commands"
- Command 1 "Change Vehicle Screen Bightness Command"
- Detail 1 "Maximum Brightness"
- Detail 2 "Minimum Brightness"
- Command 2 "Toggle Vehicle Screen Command"
namespace Example
{
public class Program
{
public static void Main(string[] args)
{
Base.Initialize();
Member Category = new Member(
Member.Rank.Category,
0x01,
"Category for Vehicle Commands"
);
Member.AddCategory( Category );
Member SubCategory1 = new Member(
Member.Rank.SubCategory,
0x00,
"Subcategory for Vehicle Screen Commands"
);
Member.AddSubCategory(
Category,
SubCategory1
);
Member Command1 = new Member(
Member.Rank.Command,
0x00,
"Change Vehicle Screen Bightness Command"
);
Member.AddDetail(
Command1,
new Member(
Member.Rank.Detail,
0x01,
"Maximum Brightness"
)
);
Member.AddDetail(
Command1,
new Member(
Member.Rank.Detail,
0x02,
"Minimum Brightness"
)
);
Member.AddCommand(
SubCategory1,
new Member(
Member.Rank.Command,
0x01,
"Toggle Vehicle Screen Command"
)
);
...
}
}
}
- Warning
- I did not check the returns of functions and their exception for the sake of simplicity, See the returns of each function and their exceptions
Generating an OPCode
OPCodes are a Set of bytes who's sole purpose is defining the action to perform on the server side which are mandaroty to generate new Request Instances
Generating a Base OPCode
- Note
- You can Generate Base OPCodes using the same Method as Generating a User-defined OPCode but the The defining Byte for Base
Category
and Base Subcategory
is 0x00
For Base OPCodes there is 2 Methods (Each having 2 Overloads)
1- Getting any base Command
);
);
static OPCode get(byte Command)
Gets an OPCode using a Base Command without any detail.
static byte CMD_SNF_VER
When client requests SNF version of the Server.
Definition OPCode.cs:780
static byte DET_UNDETAILED
Default Detail for every Command.
Definition OPCode.cs:762
2- Getting the Invalid
Command
)
static byte DET_INVALID_ERROR_PROTOCOL
Protocol used is invalid.
Definition OPCode.cs:806
static OPCode getInvalid()
Gets an OPCode using a 'Invalid' Command without any detail.
Generating a User-defined OPCode
There is 2 Methods To Generate an OPCode
1- Using The defining byte of it's Members
...
OPCode.Base.Initialize();
...
0x01,
0x00,
0x02,
0x05
);
static OPCode get(byte Category, byte SubCategory, byte Command, byte Detail=0)
Generates an OPCode Instnce Depending on the Registred Parameters.
Definition OPCode.cs:56
2- Using OPCode.Member Instances of it's Members
See Also:
...
OPCode.Base.Initialize();
...
OPCode.Member Category;
...
Category,
SubCategory,
Command,
Detail
);
Objects of this class Defines every OPCode instance.
Definition OPCode.cs:193
- Note
- If you want Undetailed OPCodes using Method 1 and/or 2 you can put in the OPTIONAL Parameter with a value of
0x00
and/or null
respectively, or not write that parameter to begin with
Getting an OPCode Member
In case you want to fetch a Base OPCode Member for some reason, use one of the Following
- Note
- During all of these Examples below we use this
using
Getting a Category
In case you want a specefic Category, you must use their defining byte
Member C = Member.getCategory(
0x00
);
or if you want the base Category
Member C = Base.getCategory();
Getting a Subcategory
In case you want a specefic subcategory, you must use their defining byte and the parent Category's defining byte or the category Member instance.
Member C = Member.getSubcategory(
0x00,
0x00
);
Member C = Member.getSubcategory(
Category,
0x00
);
or if you want the base SubCategory
Member C = Base.getSubCategory();
Getting a Command
In case you want a specefic command, you must use their defining byte and the parent Category and Subcategory's defining Byte or the Subcategory's Member Instance,
Member C = Member.getCommand(
0x00,
0x00,
0x01
);
Member C = Member.getCommand(
Subategory,
0x00
);
or if you want a base command
Member C = Base.getCommand(
0x01
);
Getting a Command's Detail
In case you want a specefic command's detail, you must use their defining byte and the parent Category, Subcategory and Command's defining byte or the Command's Member Instance,
Member C = Member.getCommand(
0x00,
0x00,
0x01,
0x01,
);
Member C = Member.getDetail(
Command,
0x00
);
or if you want a base command's detail
Member C = Base.getDetail(
0x01,
0x01
);
Requests
- Note
- Always makesure your opcodes and the server is up and running and connected before sending any request !
Generating a Request
There is X different overload to create a new Request for different usecases
Generating a Request with just an OPCode and doesnt await a response
<OPCODE Object>
);
"Request" Members are the object that are sent through SNF.Client.Connection
Definition Request.cs:19
Generating a Request with just an OPCode and awaits a response
1- Declare a function and pass it as an argument
eg of a function Declaration
public void NameOfYourCallBack(
Request Response)
{
...
...
}
and then pass it as an argument upon the creation of the request object
<OPCODE Object>,
NameOfYouCallBack
);
2- Declare the function directly in the arguents eg
<OPCODE Object>,
...
...
}
);
Generating a Request with an OPCode, Arguments and doesnt await a response
byte[][] args =
{
new byte[] { 0x22, 0x33},
Encoding.ASCII.GetBytes("Argument From String"),
.
.
};
<OPCODE Object>,
args
);
Generating a Request with an OPCode, Arguments and awaits a response
and put them in your constructore just like this
<OPCODE Object>,
args,
Callback
);
Generating a Request with a custom UID
You can Set a Custom Request by Defining the byte array that has the length stated in the Variable _UID_LENGTH and pass it as the firest argument in either one of the Cunstructors that allows a Custom UID
- Note
- All Requests(Except those who have a CustomUID) Will have an auto incrementing Unique UID generated by the generateUID() Function
First generate your UID
..
..
static int _UID_LENGTH
The length of the UID of each Request "Request".
Definition Request.cs:25
Then if you want a Request that doesnt Await a response, create it like this:
- See this to know how to get an `OPCODE Object`
- Declare your arguments in an array of
byte[]
and then pass it as argument when creating the object, just like **here** - Note
- If you dont have an argument then put
null
instead of args
UID,
<OPCODE Object>,
args
);
and if you want a Request that Awaits a response, create it like this:
- Delclare your Response Callabck just like **here**
UID,
<OPCODE Object>,
args,
Callback
);
Making use of your Request
After you have genrated the Request object to your needs, you can send it Using this tutorial