|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
Please be patient, more source files and demos coming soon!
IntroductionWhat is FreeDOM? Well FreeDOM is a new concept I created that changes a webpage into a fully asynchronous event driven application by using current available technologies. Below I will compare FreeDOM with currently working Web 2.0 concepts and show you the benefits of switching to this architecture. Web 2.0 TechniquesThere are many ways of creating webpages that go and get content from servers and update themselves. Below is a list of common ways.
Most of these concepts come with plenty of downfalls to true application state. Ajax and Iframes, both are very resource happy. Everytime you want to get data from the server you must create an object or element and send an HTTP Request. This causes the http server to have huge amounts of requests eating up memory and processor time. There is also a delay in response time do to header information being passed back and forth. Also Ajax and Iframes do not know if there is data available, they have to send a request just to find out if it is available, an once again causing alot of not needed talking between server and client. Another issue with HTTP Requests is that it fills up your server logs. This can be a headache for servers with large amounts of traffic. Extremely large logs take up processor time, harddrive space and backup space. Ajax/Frames also can only receive text or XML. This can be very irratating because in order to use it on a page you must convert it into a usable format. Alot of websites use XML objects backend and JSON objects front end, in doing this they must have a conversion process. This is at another memory and processor expense.
Alot of developers have notice these flaws in Ajax and IFrames and have started to invent new technologies. One being Comet, another cleansing name. Comet is very hard to implement and comes with alot of unknown bugs. Basically in order to use it you usually have to create a custom web server, because most today were not made to leave requests in an open state. Most servers have timeouts and caching built in to make them faster for a get in get out way of doing business. Comet is a step up from Ajax but its not the cure. Comet can only receive asynchronous events, it cannot talk back to the server. You need to implement Comet to receive and Ajax to send, making Coment dependant on Ajax. Another downside of using Comet is that browsers also have an issue with a never ending webpage. Have you ever been on a page and it locks up causing all your other browsers windows to close... this is caused by the exe sharing memory and thread space. So Comet was a great idea but it is not feasable do to current technology.
Another technology is HTTP Streaming. There is many different versions of http streaming. One way is setting up a server to talk back and forth to ActiveX or Java Applet. Very hard to implement and maintain, with many security and licensing issues for both client and server. Most users will not install your code because of fears of corrupt code that they will not be able to remove, plus cause damage to their operating system or files. This can be very scary to the end user. This next section I will describe FreeDOM and how it will fix these issues. FreeDOM!So how would one go about fixing these old technologies to make websites and application one. Should we wait for large companies to create better working browsers or should we invent it now with currently working technologies. As a developer I feel I should wait... but as an inventor I have decided to make it work. What I want is the freedom to do what I want and build what i want on a webpage. I came up with the name FreeDOM for this reason, plus it is really what we want to do. We want to be able to work with the browser How Does FreeDOM Work?FreeDOM works by using
Flash SWF CodeAdd the following code to a document class .AS file. It is a wrapper for the custom package {
//Imports--------------------
import flash.external.ExternalInterface;//For communicating with javascript
import JSockets.JSocket;//JSocket
import flash.display.MovieClip;//Movie Clip
import flash.system.Security;//For Domain Security
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
//---------------------------
//Main Class for creating javascript sockets
public class Main extends MovieClip {
//Create Properties----------------
private var SocketArray:Array;
//---------------------------------
//Constructor
public function Main() {
//Add Javascript EntryPoints-------------------
ExternalInterface.addCallback("CreateSocket", this.CreateSocket);
ExternalInterface.addCallback("Connect", this.Connect);
ExternalInterface.addCallback("Close", this.Close);
ExternalInterface.addCallback("Flush", this.Flush);
ExternalInterface.addCallback("Send", this.Send);
//---------------------------------------------
}
//Creates a socket for use in javascript
public function CreateSocket(_ID:String, _Cls:String, _Con:String,
_Ioe:String, _Se:String, _Dat:String):void {
var NS:JSocket = new JSocket();
NS.ID = _ID;
NS.CloseEventCallback = _Cls;
NS.ConnectEventCallback = _Con;
NS.IOErrorEventCallback = _Ioe;
NS.SecurityErrorEventCallback = _Se;
NS.SocketDataEventCallback = _Dat;
this.SocketArray = new Array();
this.SocketArray.push(NS);
}
//Gets the socket object
private function GetSocket(_ID:String):JSocket {
for each (var S:JSocket in this.SocketArray) {
if (S.ID == _ID) {
return S;
}
}
return null;
}
//Connects to a host and port
public function Connect(_ID:String, _Host:String, _Port:uint):void {
//Get Working Socket----
var FS:JSocket = this.GetSocket(_ID);
//----------------------
if (FS) {
FS.Connect(_Host, _Port);
}
}
//Closes a connection to a host
public function Close(_ID:String):void {
//Get Working Socket----
var FS:JSocket = this.GetSocket(_ID);
//----------------------
if (FS) {
FS.close();
}
}
//Flushes a connection
public function Flush(_ID:String):void {
//Get Working Socket----
var FS:JSocket = this.GetSocket(_ID);
//----------------------
if (FS) {
FS.flush();
}
}
//Sends data to a connection
public function Send(_ID:String, _Data:String):void {
//Get Working Socket----
var FS:JSocket = this.GetSocket(_ID);
//----------------------
if (FS) {
FS.writeUTFBytes(_Data);
}
}
}
}
Next is the package JSockets{
//Imports--------------------
import flash.external.ExternalInterface;//For communicating with javascript
import flash.net.Socket;//Flash Socket Class
import flash.errors.*;//Flash Errors
import flash.events.*;//Flash Events
//---------------------------
//Actual socket class
public class JSocket extends Socket {
//Create Properties---------------
public var ID:String;
public var Host:String;
public var Port:uint;
public var CloseEventCallback:String;
public var ConnectEventCallback:String;
public var IOErrorEventCallback:String;
public var SecurityErrorEventCallback:String;
public var SocketDataEventCallback:String;
//--------------------------------
//Constructor
public function JSocket() {
AttachEvents();
}
//Attach Events
private function AttachEvents():void {
//Add Event Handlers-------------------------------------------------------
addEventListener(Event.CLOSE, Handler_Close);
addEventListener(Event.CONNECT, Handler_Connect);
addEventListener(IOErrorEvent.IO_ERROR, Handler_IOError);
addEventListener(SecurityErrorEvent.SECURITY_ERROR, Handler_SecurityError);
addEventListener(ProgressEvent.SOCKET_DATA, Handler_SocketData);
//-------------------------------------------------------------------------
}
//Connects to a host and port
public function Connect(_Host:String, _Port:uint):void {
Host = _Host;
Port = _Port;
//Call socket connect---
connect(Host,Port);
//----------------------
}
// Handles the close event
private function Handler_Close(event:Event):void {
ExternalInterface.call(this.CloseEventCallback, event.type);
}
// Handles the connect event
private function Handler_Connect(event:Event):void {
ExternalInterface.call(this.ConnectEventCallback, event.type);
}
// Handles if io error event
private function Handler_IOError(event:IOErrorEvent):void {
ExternalInterface.call(this.IOErrorEventCallback, event.type, event.text);
}
// Handles security error event
private function Handler_SecurityError(event:SecurityErrorEvent):void {
ExternalInterface.call(this.SecurityErrorEventCallback, event.type, event.text);
}
// Handles socket data event
private function Handler_SocketData(event:ProgressEvent):void {
ExternalInterface.call(this.SocketDataEventCallback, event.type, this.readUTFBytes(this.bytesAvailable));
}
}
}
There is alot of tweaks you can do to these classes to customize it to your needs. These are just simple examples that I got my test app to work with. Keeping the flash as a simple byte router is the best solution. Javascript ImplementationLets see how to use these classes in Javascript. The code below is for the FreeDOM chat program example. It simulates a custom personal irc. If the page is not up its because im updating it. Here is the code for that example. Please keep in mind, this is a simple test, it doesn't support validation or bugs, use at your own risk. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"%22%3C/span">%22%3C/span">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd<html xmlns="
http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml<head>
<title>Test</title>
</head>
<script type="text/javascript">
function Connect()
{
var f = thisMovie("flashObject");
f.CreateSocket("id1", "CloseEventCallback",
"ConnectEventCallback", "IOErrorEventCallback",
"SecurityErrorEventCallback", "SocketDataEventCallback");
f.Connect("id1", "%22%22%3C/span%22">
%22%3C/span">%22%3C/span">http://www.codevendor.com/">www.codevendor.com}
function DisConnect()
{
var f = thisMovie("flashObject");
f.Send("id1", "Logout: \n");
f.Flush("id1");
}
function thisMovie(movieName)
{
return (navigator.appName.indexOf("Microsoft") != -1)?
window[movieName]:document[movieName];
}
function SendMessage()
{
var M = document.getElementById("Message").value;
document.getElementById("Message").value = "";
var f = thisMovie("flashObject");
f.Send("id1", "MESSAGE: " + M + "\n");
f.Flush("id1");
}
function SendCommand()
{
var M = document.getElementById("CommandBox").value;
document.getElementById("CommandBox").value = "";
var f = thisMovie("flashObject");
f.Send("id1", M + "\n");
f.Flush("id1");
}
function CloseEventCallback(T)
{
document.getElementById("Status").value+=" -> " + T + "\n";
ScrollToBottom();
}
function ConnectEventCallback(T)
{
document.getElementById("Status").value+=" -> " + T + "\n";
ScrollToBottom();
GetUsers();
}
function GetUsers()
{
var f = thisMovie("flashObject");
f.Send("id1", "USERS: ");
f.Flush("id1");
}
function IOErrorEventCallback(T, E)
{
document.getElementById("Status").value+=" -> " + T + "\n";
document.getElementById("Errors").innerHTML+=" -> " + E + "\n";
ScrollToBottom();
}
function SecurityErrorEventCallback(T, E)
{
document.getElementById("Status").value+=" -> " + T + "\n";
document.getElementById("Errors").innerHTML+=" -> " + E + "\n";
ScrollToBottom();
}
function SocketDataEventCallback(T, D)
{
eval("D2 = " + D);
if(D2.CMD == "USERLIST" || D2.CMD == "LOGOUT")
{
document.getElementById("Users").value = D2.DATA.split(",").join("\n");
document.getElementById("ChatRoom").value+= D2.STAT + "\n";
}
if(D2.CMD == "MESSAGE")
{
document.getElementById("ChatRoom").value+= D2.STAT + "\n";
}
document.getElementById("Status").value+=" -> " + T + "\n";
document.getElementById("Data").value+=D + "\n";
ScrollToBottom();
}
function ScrollToBottom()
{
document.getElementById("ChatRoom").scrollTop =
document.getElementById("ChatRoom").scrollHeight;
document.getElementById("Status").scrollTop =
document.getElementById("Status").scrollHeight;
document.getElementById("Data").scrollTop =
document.getElementById("Data").scrollHeight;
document.getElementById("Errors").scrollTop =
document.getElementById("Errors").scrollHeight;
}
</script>
<body>
<table cellpadding="0px" cellspacing="10px">
<tr>
<td valign="top"><strong>Client Chat</strong><br /><br />
<input type="button" onclick="Connect();"
name="Connect" value="Connect" /> <input type="button" onclick="DisConnect();"
name="DisConnect" value="DisConnect" />
<br /><br /><table><tr><td>Chat Room</td><td>
Users</td></tr><tr><td><textarea id="ChatRoom" rows="20" cols="40"></textarea></td><td><textarea
id="Users" rows="20" cols="20"></textarea></td></tr></table> Message:
<input type="text" id="Message" style="width:230px;" />
<input type="button" onclick="SendMessage();" name="Send"
value="Send" /> CMD:
<input type="text" id="CommandBox" style="width:80px;" /><input type="button" onclick="SendCommand();"
name="Issue"
value="Issue" /><br />
</td>
<td valign="bottom"><strong>Socket Events</strong><br /><br />
Status<br />
<textarea id="Status" rows="5" cols="30"></textarea>
<br />
Data<br />
<textarea id="Data" rows="5" cols="30"></textarea>
<br />
Errors<br />
<textarea id="Errors" rows="5" cols="30"></textarea></td>
</tr>
</table>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="flashObject" width="0"
height="0" codebase="%22%3C/span">%22%3C/span">http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab style="display: hidden">
<param name="movie" value="javascriptsockets.swf" />
<param name="quality" value="low" />
<param name="allowScriptAccess" value="always" />
<embed src="javascriptsockets.swf" quality="low" width="0" height="0" name="flashObject"
id="flashObject" align="middle" play="true" loop="false" allowscriptaccess="always"
type="application/x-shockwave-flash" pluginspage="%22%3C/span">%22%3C/span">http://www.macromedia.com/go/getflashplayer%22%3Cbr%3E">
http://www.macromedia.com/go/getflashplayer"
style="display: hidden">
</embed>
</object>
</body>
</html>"
", 81);
">
">
Socket Server ImplementationI wont go into the full detail of the code, but its a simple async socket server created in C#. It handles the incoming connection requests and sends out responses. The important things to look at is the Sandbox Cross Domain Policy it sends out. Basically flash will request this from your server to make sure its allowed to use your server. The code for this is below.
/// <summary>Class for creating a tcp socket listener.</summary>
class Listener
{
#region Variables
private ManualResetEvent vManualReset = null;
private Dictionary<Guid, StateObject> vStateObjects = null;
private List<Guid> vStateIDS = null;
private Socket vListenerSocket = null;
#endregion Variables
#region Properties
/// <summary>Holds the current state ids.</summary>
public List<Guid> StateIDS
{
get { return vStateIDS; }
set { vStateIDS = value; }
}
/// <summary>Holds all currently working socket stateobject information.</summary>
internal Dictionary<Guid, StateObject> StateObjects
{
get { return vStateObjects; }
}
/// <summary>The main listener socket.</summary>
public Socket ListenerSocket
{
get { return vListenerSocket; }
}
#endregion Properties
#region Constructor
/// <summary>Constructor</summary>
public Listener()
{
}
#endregion Constructor
#region Server Methods
/// <summary>Listen for connections.</summary>
public void Listen()
{
//Declare variables--------------
IPHostEntry Host = null;
IPEndPoint EP = null;
IPAddress IP = null;
//-------------------------------
//Set Host and Endpoint----------
IP = IPAddress.Parse("127.0.0.1");
if (IPAddress.TryParse(ConfigurationManager.AppSettings["ListeningAddress"], out IP))
{
EP = new IPEndPoint(IP, int.Parse(ConfigurationManager.AppSettings["ListeningPort"]));
}
else
{
Host = (ConfigurationManager.AppSettings["ListeningAddress"] == string.Empty) ?
Dns.GetHostEntry(ConfigurationManager.AppSettings
["ListeningAddress"]) : Dns.GetHostEntry(Dns.GetHostName());
EP = new IPEndPoint(Host.AddressList[0],
int.Parse(ConfigurationManager.AppSettings["ListeningPort"]));
}
//-------------------------------
//Create listener and stateobject holder----------------
vManualReset = new ManualResetEvent(false);
vListenerSocket = new Socket(EP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
//------------------------------------------------------
try
{
//Bind Socket and start listening----
vListenerSocket.Bind(EP);
vListenerSocket.Listen(int.Parse(ConfigurationManager.AppSettings["TotalAllowedConnections"]));
//-----------------------------------
while (true)
{
vManualReset.Reset();
vListenerSocket.BeginAccept(new AsyncCallback(ConnectionAccept), vListenerSocket);
vManualReset.WaitOne();
}
}
catch { }
finally
{
}
}
/// <summary>Accepts the connection and transfers it and calls listening thread to repeat</summary>
/// <param name="_AR">The async result.</param>
private void ConnectionAccept(IAsyncResult _AR)
{
//Declare Variables-----------
Socket ListSocket = null;
Socket CurrentSocket = null;
StateObject CurrentStateObject = null;
//----------------------------
//Set Sockets-----------------
ListSocket = (Socket)_AR.AsyncState;
CurrentSocket = ListSocket.EndAccept(_AR);
//----------------------------
//Set ManualEvent-------------
vManualReset.Set();
//----------------------------
//Check if there is stateobjects and add to it----------
if (vStateObjects == null) { vStateObjects = new Dictionary<Guid, StateObject>(); }
//------------------------------------------------------
//Check if stateids is null and add to it---------------
if (vStateIDS == null) { vStateIDS = new List<Guid>(); }
//------------------------------------------------------
//Set Current State Object------------
CurrentStateObject = new StateObject(CurrentSocket,
int.Parse(ConfigurationManager.AppSettings["BufferSize"]));
//------------------------------------
//Add StateObject to generic list-----
vStateObjects.Add(CurrentStateObject.UniqueID, CurrentStateObject);
//------------------------------------
//Add ID------------------------------
vStateIDS.Add(CurrentStateObject.UniqueID);
//------------------------------------
try
{
//Start Receiving Data----------------
CurrentSocket.BeginReceive(CurrentStateObject.Buffer, 0,
CurrentStateObject.BufferSize, 0, new AsyncCallback(ReadCallback),
CurrentStateObject);
//------------------------------------
}
catch { CloseSocket(CurrentStateObject); return; }
}
/// <summary>Handles the receiving of data from a current socket.</summary>
/// <param name="_AR">The async result.</param>
private void ReadCallback(IAsyncResult _AR)
{
//Declare Variables-----------
StateObject CurrentState = null;
int BytesRead = 0;
string Command = string.Empty;
string r = string.Empty;
bool first = false;
Guid[] CurrentIDS = new Guid[vStateIDS.Count];
//----------------------------
//Copy IDS--------------------
vStateIDS.CopyTo(CurrentIDS);
//----------------------------
//Set StateObject-------------
CurrentState = (StateObject)_AR.AsyncState;
//----------------------------
//Get the total bytes read----
try
{
BytesRead = CurrentState.WorkSocket.EndReceive(_AR);
}
catch { CloseSocket(CurrentState); return; }
//----------------------------
if (BytesRead > 0)
{
//Check for XML Domain Policy Request-------
Command = Encoding.Default.GetString(CurrentState.Buffer, 0, BytesRead);
//------------------------------------------
switch (Command.ToUpper())
{
case "<POLICY-FILE-REQUEST/>\0":
//Send Cross Domain Policy--------------------------------------------
XmlDocument XD = new XmlDocument();
Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection CS = (ConfigurationSection)Config.GetSection("CrossDomainPolicy/Policy");
XD.LoadXml(CS.SectionInformation.GetRawXml());
XmlNode XN = XD.SelectSingleNode("Policy");
Send(XN.InnerText.Replace("\r\n", "") + "\0", CurrentState, true);
//--------------------------------------------------------------------
break;
default:
string[] cmd = Command.Split(':');
switch (cmd[0].ToUpper())
{
case "MESSAGE":
foreach (Guid ID in CurrentIDS)
{
if (ID != CurrentState.UniqueID)
{
if (vStateObjects.ContainsKey(ID))
{
Send("{CMD:'MESSAGE', STAT:'<"
+ CurrentState.WorkSocket.RemoteEndPoint.ToString().Split(':')[0] + "> " + cmd
[1].Trim() + "'}", vStateObjects[ID], false);
}
else
{
vStateIDS.Remove(ID);
}
}
}
Send("{CMD:'MESSAGE', STAT:'<" +
CurrentState.WorkSocket.RemoteEndPoint.ToString().Split(':')[0] + "> " + cmd[1].Trim() +
"'}", CurrentState, false);
break;
case "NICKNAME": Send("Your nickname has been changed to" + cmd[1], CurrentState, false); break;
case "LOGOUT":
foreach (Guid ID in CurrentIDS)
{
if (ID != CurrentState.UniqueID)
{
if (vStateObjects.ContainsKey(ID))
{
if (first) { r += "\n"; } else { first = true; }
r += vStateObjects[ID].WorkSocket.RemoteEndPoint.ToString().Split(':')[0];
}
else
{
vStateIDS.Remove(ID);
}
}
}
foreach (Guid ID in CurrentIDS)
{
if (ID != CurrentState.UniqueID)
{
if (vStateObjects.ContainsKey(ID))
{
Send("{CMD:'LOGOUT', DATA:'" + r + "',STAT:'User Disconnected - " +
CurrentState.WorkSocket.RemoteEndPoint.ToString().Split(':')[0] + "'}", vStateObjects[ID], false);
}
else
{
vStateIDS.Remove(ID);
}
}
}
Send("{CMD:'LOGOUT', DATA:'" + r + "',STAT:'User Disconnected - " +
CurrentState.WorkSocket.RemoteEndPoint.ToString().Split
(':')[0] + "'}", CurrentState, true);
break;
case "USERS" :
foreach (Guid ID in CurrentIDS)
{
if (vStateObjects.ContainsKey(ID))
{
if (first) { r += ","; } else { first = true; }
r += vStateObjects[ID].WorkSocket.RemoteEndPoint.ToString().Split(':')[0];
}
else
{
vStateIDS.Remove(ID);
}
}
foreach (Guid ID in CurrentIDS)
{
if (ID != CurrentState.UniqueID)
{
if (vStateObjects.ContainsKey(ID))
{
Send("{CMD:'USERLIST', DATA:'" + r + "', STAT:'Welcome User - " +
CurrentState.WorkSocket.RemoteEndPoint.ToString().Split(':')[0] + "'}", vStateObjects[ID], false);
}
else
{
vStateIDS.Remove(ID);
}
}
}
Send("{CMD:'USERLIST', DATA:'" + r + "',STAT:'Welcome User - "
+ CurrentState.WorkSocket.RemoteEndPoint.ToString().Split
(':')[0] + "'}", CurrentState, false);
break;
}
break;
}
try
{
//Get more data from socket-----------------
CurrentState.WorkSocket.BeginReceive(CurrentState.Buffer, 0, CurrentState.BufferSize,
0, new AsyncCallback(ReadCallback), CurrentState);
//------------------------------------------
}
catch { CloseSocket(CurrentState); return; }
}
else
{
//Close the connection and remove the object-----
CloseSocket(CurrentState);
//-----------------------------------------------
}
}
/// <summary>Closes the socket and disposes of the state object and removes it from
the generic dictonary.</summary>
/// <param name="_StateObject">The stateobject to remove.</param>
private void CloseSocket(StateObject _StateObject)
{
//Declare Variables---------------
Guid UniqueID = _StateObject.UniqueID;
//--------------------------------
//Close Connection----------------
if (_StateObject.WorkSocket != null)
{
try
{
_StateObject.WorkSocket.Shutdown(SocketShutdown.Both);
_StateObject.WorkSocket.Close();
}
catch { }
finally
{
_StateObject.WorkSocket = null;
_StateObject = null;
}
}
//--------------------------------
//Remove object from dictonary----
vStateIDS.Remove(UniqueID);
vStateObjects.Remove(UniqueID);
//--------------------------------
}
/// <summary>Send string data to the current socket.</summary>
/// <param name="_StringData">The string to send.</param>
/// <param name="_StateObject">The stateobject to send the string to.</param>
/// <param name="_CloseConnection">Closes the connection.</param>
public void Send(string _StringData, StateObject _StateObject, bool _CloseConnection)
{
Send(Encoding.Default.GetBytes(_StringData), _StateObject, _CloseConnection);
}
/// <summary>Send string data to the current socket.</summary>
/// <param name="_ByteData">The byte data to send.</param>
/// <param name="_StateObject">The stateobject to send the data to.</param>
/// <param name="_CloseConnection">Closes the connection.</param>
public void Send(byte[] _ByteData, StateObject _StateObject, bool _CloseConnection)
{
_StateObject.Terminate = _CloseConnection;
try
{
_StateObject.WorkSocket.BeginSend(_ByteData, 0, _ByteData.Length, 0,
new AsyncCallback(SendCallback), _StateObject);
}
catch { CloseSocket(_StateObject); return; }
}
/// <summary>Handles the send callback.</summary>
/// <param name="ar">The async result.</param>
private void SendCallback(IAsyncResult _AR)
{
//Declare Variables-----------
StateObject CurrentState = null;
int BytesSent = 0;
//----------------------------
//Set StateObject-------------
CurrentState = (StateObject)_AR.AsyncState;
//----------------------------
try
{
BytesSent = CurrentState.WorkSocket.EndSend(_AR);
}
catch { CloseSocket(CurrentState); return; }
//Check to see if terminated---
if (CurrentState.Terminate) { CloseSocket(CurrentState); }
//-----------------------------
}
#endregion Server Methods
}
The full code can be found in the source files. You can create a socket server however you desire with whatever language. As long as it handles requests. You can even choose to use an HTTP Web Server if you want. All depends on what you want to code for. ConclusionWell that concludes my FreeDOM tutorial. Please check back for updates as I create more apps using this technique. Have Fun! Enjoy! History
External Links
Terms and Conditions For Use, Copy, Distribution, and ModificationTHIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS CODE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
| |||||||||||||||||||||||||||||||||||||||||||||||||||