Home Products Download Events Support Registration

Home
Up

Send Instant Web or Window Messages through SocketPro HTTP Server Push

        UDAParts
        support@udaparts.com
        Updated on 11/28/2008

Contents

  1. Introduction
  2. SocketPro Implementation to HTTP Server Push
  3. Pre-requirements and Preparation
  4. The First Step to SocketPro HTTP/Binary Push
  5. Coding for HTTP Push on Server Side
  6. SocketPro Adapter for Web Browser
  7. Integration HTTP Server Push with Devices and Normal Desktop/Server Applications
  8. Separating HTTP Server from Comet Server
  9. FAQs

Introduction

    Browser-based instant message is a HTTP advance topic. It is particularly useful to get a team of people or web clients through browsers for cooperation in real-time fashion. There are many such examples like stock market data distribution, online web chat, online auction, online betting, online gaming, and so on. All these samples require data pushed from a HTTP server onto browsers in a very short time. However, it is considerably difficult to get web instant messages through HTTP protocol because the protocol is not designed with server push in mind at all. Therefore, you can not easily see real-time web notification with a publish/subscribe mode. Recently, we have upgraded our SocketPro with not only basic HTTP service but also HTTP server push support, and wish HTTP server push become much easier for you.

    This short article guides you to quickly develop a message push system through SocketPro, which enables you to send messages among web browsers, devices, window desktop and server applications.

SocketPro Implementation to HTTP Server Push

    After having investigated many technologies, UDAParts selects long-time polling approach to implement SocketPro HTTP server push. With long polling, a client initially sends a request to a SocketPro server enabled with HTTP service in a similar way to a normal polling. However, the server wait until an available message or a long time timeout. Once a message or time out comes from a SocketPro server, a client will re-send a new request until the next message or timeout. By this way, a SocketPro server will almost always have an available waiting request so that it can immediately deliver a message from server to client in response to an event. Using this way is also able to make a callback from a SocketPro server to a client through HTTP service.

    SocketPro supports both the same-domain and cross-domain HTTP server pushes. SocketPro is relied on AJAX for the same-domain HTTP server push and JavaScript tag for cross-domain server push. For details, you can use the tutorial sample code and step through the code inside the file ujsonxml.js (UDAParts SocketPro adapter for JavaScript) using the debug tool FireBug in the browser FireFox. On server side, the core library (usktpror.dll) has implemented a set of HTTP functions for HTTP server push.

   UDAParts has successfully integrated HTTP server push with our original built-in chat service so that you can send a message from a desktop or device application to a web application, and vice versa. We'll use some old sample applications to show you this integration.

Pre-requirements and Preparation

    As described in the previous tutorial, you should have a basic knowledge about HTTP although you are not required to know all of HTTP details. If you don't know HTTP, please use Google or Yahoo search engine to search for key words like 'HTTP protocol tutorial'.

    This tutorial (chat) tells you how to use SocketPro HTTP server push. After compiling one of the tutorial samples inside the directories ..\udaparts\socketpro\tutorial\csharp\chat\server\ and ..\udaparts\socketpro\tutorial\vb.net\chat\server\ for C# and vb.net respectively, you need to copy the files inside the directory ..\udaparts\socketpro\tutorial\HTTPChatSampleFiles into this directory of your compiled exe application. These files are used for testing. Note that there is no client sample application provided for this HTTP tutorial, but the client test application is your browser, FireFox, IE, Safari, Opera, Flock or else. 

    We would like you to use FireFox plus free plug-in FireBug. FireBug is the best free web browser debug tool available at this writing time. You can use the tool to debug HTTP transaction between browser and sample SocketPro on client side so that you can see how UDAParts SocketPro adapter (ujsonxml.js) works. It may require you to have some basic knowledge about JavaScript.

    This tutorial requires you a simple understanding about JSON. In case you don't know JSON, please go to the site www.json.org. By default, SocketPro adapter for JavaScript uses JSON for serialization. The site contains all of free open source JSON parsers for all types of development language. In this tutorial, we'll use Newtonsoft json parser. You can use your own parser or others to replace the tutorial json parser.

    After successfully compiling the tutorial and running the SocketPro server, you can play it from a browser. See the below sample picture. You should put debug break points everywhere on both JavaScript and .NET server codes and see how codes execute.

The First Step to SocketPro HTTP/Binary Push

    To enable SocketPro HTTP/binary push is to make a few calls for configuration so that SocketPro knows how to handle various chat requests. First of all, you need to create a set of chat groups. Within SocketPro, you can push a message onto one or multiple groups of clients. To do so, create a few chat groups using the below code snippet.

            bool bSuc;

            bSuc = AddAChatGroup(1, "Group for SOne");

            bSuc = AddAChatGroup(2, "DB Service");

            bSuc = AddAChatGroup(4, "Management Department");

            bSuc = AddAChatGroup(8, "IT Department");

            bSuc = AddAChatGroup(16, "Sales Department");

    The above code snippet creates five chat groups with group identification numbers, 1, 2, 4, 8, and 16. You can create 32 groups at most. The next two calls is to tell SocketPro how to deal with the situation when a client joins or exits one or more chat groups. See the below code.

            //Other clients will be notified when a new client join the groups 1, 4, 8

            GroupsNotifiedWhenEntering = 13;
        

            //Other clients will be notified when a new client leave the group 1, 4, 8

            GroupsNotifiedWhenExiting = 13;
        

            //-1 means all of 32 groups

    An existing client will get a message whenever another client joins or exists the three groups 1, 4, or 8. If you set the above values to -1, an existing client will get a message whenever another client joins or exists.

    After you complete the above calls, it is ready for SocketPro to handle various chat calls from either client or server side without using HTTP or independent chat service. Note that all of other services internally inherits the chat service. You can think the chat service as a base class. However, we'll use both the chat and HTTP services in this tutorial so that we have to enable them in SocketPro. Note that the two services are SocketPro built-in services. To enable them, you'd make below calls:

            private CSocketProService<CHttpPeer> m_HttpSvs = new CSocketProService<CHttpPeer>();

            private CNotificationService m_ChatSvs = new CNotificationService();
        

            // ......
        

            //sidHTTP = 266

            bSuc = m_HttpSvs.AddMe((int)USOCKETLib.tagServiceID.sidHTTP, 0, tagThreadApartment.taNone); //enable HTTP service

            bSuc = m_HttpSvs.AddSlowRequest((short)USOCKETLib.tagHttpRequestID.idGet);

            bSuc = m_HttpSvs.AddSlowRequest((short)USOCKETLib.tagHttpRequestID.idPost);
        

            //sidChat = 257

            bSuc = m_ChatSvs.AddMe((int)USOCKETLib.tagServiceID.sidChat, 0, tagThreadApartment.taNone); //enable independent chat  service

    In the above we create two instances of services first, one for HTTP service and the other for independent chat service. Afterwards, we enable HTTP service, and use a worker thread in pool to process HTTP GET and POST commands. Finally, we make a call to enable independent chat service.

Coding for HTTP Push on Server Side

    HTTP push code on server side:    You don't have to make any code for independent chat service, but you do need to deal with HTTP chat-related methods on both web browser and server sides. We are going to do server side first.

            case "/UCHAT":

            {    

                    CRet ret;

                    string strMethod = null;

                    SetResponseHeader("Connection", "close");
        

                    //UJS_DATA comes from UDAParts JavaScript SocketPro adapter for json and XML RPC library (ujsonxml.js)

                    string str = this.Params["UJS_DATA"];

                    try

                    {

                            JavaScriptObject json;

                            JavaScriptObject parameters;

                            json = (JavaScriptObject)JavaScriptConvert.DeserializeObject(str);

                            strMethod = (string)(json["method"]);

                            parameters = (JavaScriptObject)(json["params"]);

                            ret = HandleJSCall(strMethod, parameters);

                    }

                    catch (Exception err)

                    {

                            ret = new CRet();

                            ret.method = strMethod;

                            ret.ret = 0;

                    }
            

                    if (strMethod != "listen")

                    {

                            int result = 0;

                            string strJSCallback = null;

                            //UJS_CB comes from UDAParts JavaScript SocketPro adapter for json and XML RPC library (ujsonxml.js)

                            if (Params.ContainsKey("UJS_CB")) //cross-domain callback

                                    strJSCallback = Params["UJS_CB"];

                            str = JavaScriptConvert.SerializeObject(ret);

                            m_UQueue.SetSize(0);

                            if (strJSCallback != null)

                                    m_UQueue.Push(enc.GetBytes(strJSCallback));

                            m_UQueue.Push(enc.GetBytes(str));

                            if (strJSCallback != null)

                                    m_UQueue.Push(enc.GetBytes(");"));

                            result = SendReturnData(sRequestID, m_UQueue);

                    }

            }

            break;

        

            private CRet HandleJSCall(string strRequest, JavaScriptObject jsoParameters)

            {

                    CRet ret = new CRet();

                    ret.method = strRequest;

                    string strAgent = "";
        

                    //UJS_CB comes from UDAParts JavaScript SocketPro adapter for json and XML RPC library (ujsonxml.js)

                    bool bCrossSite = Params.ContainsKey("UJS_CB");

                    if (bCrossSite && Headers.ContainsKey("User-Agent"))

                            strAgent = Headers["User-Agent"].ToLower();

                    bool bSelfMessage = (strAgent.IndexOf("firefox") != -1 || strAgent.IndexOf("opera") != -1);

 

                    switch (strRequest)

                    {

                    case "enter":

                            {

                                    object obj = jsoParameters["groups"];

                                    long nGroups = (long)obj;

                                    string strUserId = (string)(jsoParameters["userId"]);
        

                                    //it returns a unique push session id

                                    ret.ret = Enter((int)nGroups, strUserId, 100000); //100 seconds for lease time

                            }

                            break;

                    case "exit":

                            {

                                    string strSession = (string)(jsoParameters["chatId"]);

                                    ret.ret = Exit(strSession);

                            }

                            break;

                    case "speak":

                            {

                                    string strSession = (string)(jsoParameters["chatId"]);

                                    string strGroups = (string)(jsoParameters["groups"]);

                                    object msg = jsoParameters["message"];

                                    if (bSelfMessage) //cross-domain, and browsers firefox, flock and opera

                                            SendSelfMessage(strSession);

                                    ret.ret = Speak(strSession, msg, int.Parse(strGroups));

                            }

                            break;

                    case "sendUserMessage":

                            {

                                    string strSession = (string)(jsoParameters["chatId"]);

                                    string strUID = (string)(jsoParameters["userId"]);

                                    object msg = jsoParameters["message"];

                                    if (bSelfMessage) //cross-domain, and browsers firefox, flock and opera

                                            SendSelfMessage(strSession);

                                    ret.ret = SendUserMessage(strSession, strUID, msg);

                            }

                            break;

                    case "listen":

                            {

                                    bool bSuc;

                                    string strSession = (string)(jsoParameters["chatId"]);

                                    string strJSCallback = null;

                                    if (bCrossSite)

                                            strJSCallback = Params["UJS_CB"];
            

                                    //60 seconds for timeout; and 0 for polling

                                    bSuc = HTTPSubscribe(strSession, 60000, strJSCallback);

                                    ret.ret = bSuc;

                                    if (!bSuc)

                                    {

                                            //if failed, we need to tell the browser

                                            Encoding enc = System.Text.UTF8Encoding.UTF8;

                                            string str = JavaScriptConvert.SerializeObject(ret);

                                            m_UQueue.SetSize(0);

                                            if (strJSCallback != null)

                                                    m_UQueue.Push(enc.GetBytes(strJSCallback));

                                            m_UQueue.Push(enc.GetBytes(str));

                                            if (strJSCallback != null)

                                                    m_UQueue.Push(enc.GetBytes(");"));

                                            int result = SendReturnData((short)USOCKETLib.tagHttpRequestID.idGet, m_UQueue);

                                            result = 0;

                                    }

                            }

                    break;

                            default:

                            break;

                    }

                    return ret;

            }

    After looking through the above two snippets of code, you may get lost if you don't have any background with AJAX and JavaScript tag remoting on browser side. In short, the above two pieces of code are able to handle all of requests by either AJAX or JavaScript tag for all of major browsers. In regards to JavaScript tag requests, browser implementations are different. Therefore, we must process them differently, especially if there are two requests in pending. To understand the above HTTP transaction between browser and SocketPro server, you'd start the browser FireFox, and use the debug tool FireBug as shown in the below picture.

    Referring from the above first piece of code, we de-serialize a UJS_DATA string into json object, which contains a request name and an array of parameters. Afterwards, we pass the two data into the function HandleJSCall (see the above 2nd piece of data). The function returns a simple structure. If the method does not have the name listen, we'll return HTTP response immediately after serializing the structure into a json string.

    Two key HTTP methods:    There are two key methods you have to call for HTTP push. The first one is the method Enter, which returns a unique chat (or push) session id. Later, We use the id to make various notification or other method calls from the same machine. Note that the chat id is not valid on different machines. Calling this method with a specified lease time is to join one or a set of chat groups as we do for chat service. If there is no message for a chat session more than lease time, the chat session will be removed from SocketPro server automatically.

    The second call is the method HTTPSubscribe. When calling this method, you subscribe messages from either a web browser or a normal desktop application through chat service. It is important to point out that you can not use your code to return any data back to a browser if the method returns successfully. SocketPro will return either an available message or a timeout message for you. However, you must return a message if the method HTTPScribe returns false as shown in the above second piece of code.

    Other chat methods supported for HTTP:    At this writing, HTTP service fully supports three other chat methods, Exit, Speak and SendUserMessage in addition to the methods Enter and HTTPSubscribe as shown in this tutorial sample. Whenever you call them, you need to pass in a unique chat session id from the method Enter. Also, you need to return an HTTP response from your code. See the above first piece of code.

    You are able to call other chat service methods to notify messages onto non-HTTP client as usual, but you can not use them to notify an HTTP client. They are not fully supported.

    One hack for cross-domain HTTP push on FireFox, Flock and Opera:    As you may know, AJAX does not support cross-domain HTTP requests from a browser for the sake of security at this time, although there is a strong proposal to add support of cross-domain request through AJAX. The real situation is that there is no browser fully supporting cross-domain request from AJAX at this writing time yet. Therefore, we use JavaScript tag for cross-domain HTTP push on a browser instead. It works across all of browsers with some pitfalls for some browsers. It seems to us that FireFox, Flock and Opera do not allow two or more cross-domain requests in pending at any time, possibly for the sake of security. The others browsers look fine with two cross-domain requests in pending through JavaScript tag. To get HTTP push for cross-domain for these browsers, we need an extra call SendSelfMessage first if there are two requests in pending. See the below picture and code snippet.

            private bool SendSelfMessage(string strChatId)

            {

                    string strUserID = null;

                    string strIpAddr = null;

                    int nLeaseTimeOut = 0;

                    int nMessages = 0;

                    int nGroupIds = 0;

                    int nTimeout = 0;

                    if(!CSocketProServer.GetHTTPChatContext(strChatId, ref strUserID,

                            ref strIpAddr, ref nLeaseTimeOut, ref nGroupIds, ref nTimeout, ref nMessages))

                            return false;

                    string strSelfMessage = "CrossSite Self-activation Message for FireFox, Flock and Opera!";

                    return SendUserMessage(strChatId, strUserID, strSelfMessage);

            }

    The above function simply send its self a message so that a previous listening HTTP request is finished for the next cycle. By this way, the coming HTTP request can be processed and its HTTP response can be returned. Again, this is an work around for browsers FireFox, Flock and Opera.

    HTTP callback:    We like callback. It does make our application more elegant and smarter. However, it is considerably difficult to get callback to work for HTTP. As you may know, many popular communication frameworks can not have such a basic feature for HTTP! It is really simple to make a callback from SocketPro server to a browser or other applications using HTTP protocol.

    To do so, simply use the above code snippet, and send a client self a message exactly like the above piece of code. Note that you can pass 0 for no chat group to the method Enter. It is purely for callback.

SocketPro Adapter for Web Browser

    To make HTTP push easier on web browser side, we provide an adapter for web browsers through JavaScript. At this time, it well supports JSON and simple XML remoting procedure calls through HTTP protocol. By default, it uses json format. It supports both same- and cross-domain requests.

    Now, it is time to have a close look at the sample html file httppush.htm, and see how UDAParts uses two HTTP requests to complete HTTP push on client side.

    Configuration for pointing to HTTP server for processing:    The first step on web browser side is to point to a HTTP server for processing requests by configuring a JavaScript object. See the below code from the file httppush.htm.

            //set an address pointer for processing requests

            UHTTP.defaultConfig.pathname = '/UCHAT';

            UHTTP.defaultConfig.protocol = 'http'; //https, or other

            UHTTP.defaultConfig.port = 20901; //80, 443 or other

            UHTTP.defaultConfig.hostname = 'localhost'; //'www.somedomain.com', '111.222.212.121', or 'some_host_name';

    Look at a typical HTTP request:    SocketPro adapter for web browsers makes your HTTP requests simpler. Here is a sample code.

            function myCallback(req, data){

                    var ctrl = document.getElementById('txtMsgIn');

                    var obj = data;

                    if (typeof data == 'string')

                        obj = JSON.parse(data);

                    switch(obj.method)

                    {

                    case 'exit':

                            document.getElementById("btnSendUserMessage").disabled = 'disabled';

                            document.getElementById("btnSpeak").disabled = 'disabled';

                            chatId = '';

                            ctrl.value = 'exit: ' + obj.ret;

                            document.getElementById("btnSubscribe").disabled = '';

                            break;

                    case 'enter':

                            chatId = obj.ret;

                            if (chatId) {

                                    document.getElementById("btnSendUserMessage").disabled = '';

                                    document.getElementById("btnSpeak").disabled = '';

                            }

                            ctrl.value = 'enter: ' + obj.ret;

                            listen();

                            break;

                    case 'speak':

                            ctrl.value = 'speak: ' + obj.ret;

                            break;

                    case 'sendUserMessage':

                            ctrl.value = 'sendUserMessage: ' + obj.ret;

                            break;

                    default:

                            break;

                    }

                    obj = null;

            }

        

            function btnSpeak_onclick() {

                    var req = UHTTP.createRequest(    'speak',     //required, request name

                                                                                    0);             //optional, 0, false (default) json, 1 -- xml

                    var ctrl = document.getElementById('txtGroups');

 

                    //add the 1st parameter and its value

                    req.add('groups', ctrl.value);

 

                    ctrl = document.getElementById('txtMsgOut');

 

                    //add the 2nd parameter and its value

                    req.add("message", ctrl.value);

 

                    //add the 3rd parameter and its value

                    req.add("chatId", chatId);

 

                    req.invoke(     myCallback,     //required, a callback function to handle returning data

                                            1,                         //optional, 0, false (default) POST, 1 -- GET

                                            0                          //optional, 0, false (default) async, 1 -- sync

                                        );

            }

     When you click the button Speak, it causes the above second piece of code called. Inside the function, we create a HTTP request for the method speak. Afterwards, we add three input parameters for groups, message and chatId, respectively. Keep in mind that the chatId is chat session id from the method Enter on server side. At the end, we send the request by calling its method invoke with setting a callback. We process HTTP response using the callback as shown in the above first piece of code. All of the requests are processed under the same pattern. As you can see, we normally process HTTP requests asynchronously from a browser. In some cases, you are able to process requests synchronously through AJAX call for the same-domain only, but not for cross-domain.

    SocketPro adapter processes in the same way for both same- and cross-domain requests. If finding a request is same-domain one, it will use AJAX internally. Otherwise, it will select JavaScript tag to complete a cross-domain request.

    The second request for incoming message:    As described previously, SocketPro uses the second long-time request for messages from other clients. To do so, simply uses the below code.

            function onMessage(req, messages) {

                    var ctrl = document.getElementById('txtMsgIn');

                    var obj = messages;

                    if (typeof messages == 'string')

                    {

                            if(messages.length == 0)

                                    return;

                            obj = JSON.parse(messages);

                    }

                    else if(typeof messages == 'object')

                    {

                            var str = JSON.stringify(obj);

                            messages = str;

                    }

                    if(!obj)

                            return;

                    ctrl.value = messages;

 

                    if(chatId.length == 0)

                            return;

                    listen();

            }

            

            function listen() {

                    var req = UHTTP.createRequest('listen');

                    req.add("chatId", chatId);

                    req.invoke(onMessage, 1);

            }

    After having glanced the above two pieces of code, it is really simple. All you need to do is to create a new request listen with a chat session id, and send it by calling the method invoke with a new callback onMessage. When a message comes from itself or others, the callback will be invoked. Again, SocketPro adapter hides cross-domain callback for you.

    Note that you need to call the method listen again for the next cycle right after one or message messages come.

    Explicitly turn off HTTP server push from browser:    At the end,  it is better to explicitly turn off HTTP server push by calling the method exit as shown in the below.

            function btnUnsubscribe_onclick() {

                    var req = UHTTP.createRequest(    'exit'

                                                                                    0);                 //optional, 0, false (default) json, 1 -- xml

 

                    //add the 1st parameter and its value

                    req.add("chatId", chatId);

 

                    req.invoke(     myCallback,                 //required, a callback function to handle returning data

                                            1,                                     //optional, 0, false (default) POST, 1 -- GET

                                            0                                     //optional, 0, false (default) async, 1 -- sync

                                        );

            }

            function onMyUnload() //close socket connection

            {

                    if(chatId.length > 0)

                    {

                            //tell the server to unsubscribe listening

                            btnUnsubscribe_onclick();

                    }

            }

            <body onunload="return onMyUnload()">

    This step is not required, but highly preferred for fast cleaning chat session contexts on SocketPro server side and fast notification of exit onto other clients.

    SocketPro adapter HTTP request object:    See the below picture for SocketPro HTTP request object.

    As shown from the picture, SocketPro adapter HTTP request object clearly has two properties, method and config. The method abort is used for aborting for a HTTP response. The method add, as shown previously, is used for constructing an object dynamically. In case you like to re-use an existing request object, you can call the method clear to remove previous parameters and their values. The method getCallIndex is used to retrieve a unique integer call index. The method getCallback is used to retrieve callback set previously. The method getScript is used to retrieve either an AJAX object for same-domain or a JavaScript tag object for cross-domain.

    The method invoke is used to send a real HTTP request onto a SocketPro server enabled with HTTP service. See the below code from the file ujsonxml.js.

            /*

            invoke a request from browser to a web server.

 

            1.     cb -- required callback handler.

            2.     isGet -- default to POST. 1 or true for GET

            3.     sync -- default to asynchronous processing, and 1 or true for synchronous processing.

            */

            me.invoke = function(cb, isGet, sync) {

                    if (!me.method && typeof (me.method) != 'string')

                            throw new Error(500, "HTTP: request name not specified properly!");

                    if (typeof (cb) != 'function')

                            throw new Error(500, "HTTP: callback function not specified properly!");

                    if (!me.isCompleted())

                            throw new Error(500, "HTTP: previous request not completed yet!");

                    cIndex = ++callIndex;

                    callback = cb;

                    doCall(isGet, sync);

                    return callIndex;

            };

    The method isCompleted is used to check if a request is processed and its HTTP response has come. The method isCrossSite is used to check if a request is cross-domain one.

    All of these methods should not be too difficult for you to understand and use. We have tested libraries against multiple browsers and should work with all of major browsers on cross platforms.

Integration HTTP Server Push with Devices and Normal Desktop/Server Applications

    We have integrated HTTP server push with device and normal desktop/server applications. See the below picture for device from the project DevTest inside the directory of ..\udaparts\SocketPro\samples\device\samplesCE\DevTest, which is written from Visual C++ 4 for smart devices.

    It is also simple to communicate with other desktop or server application using push through SocketPro chat service. See the below sample application which was written from old VB6 long long time ago, which can be found inside the directory of ..\udaparts\SocketPro\samples\others\client\vb6\chatTest.

    You can use the tutorial two to test integration with HTTP server push.

Separating HTTP Server from Comet Server

    The tutorial sample server is not only a simple HTTP server but also a comet server. In many cases, you may like to separate a HTTP server from a comet sever. For example, you may use MS IIS or apache as a HTTP server on a machine, and our SocketPro comet server on another machine for push only. Therefore, we provide an extra sample to support such an architecture. You could find the sample HTTP push at the directory ..\udaparts\socketpro\samples\HTTPChat. The sample is almost the same as this tutorial. Once understanding this tutorial sample, you are expected to understand this sample without any problem at all. SocketPro Comet server is located at the directory of ..\UDAParts\SocketPro\tutorial\CSharp\Chat\Server and .\UDAParts\SocketPro\tutorial\vbnet\Chat\Server for C# and VB.NET respectively.

FAQs

  1. Your tutorial sample is written for HTTP. Does SocketPro HTTP push support secured transaction through SSL or TLS?
    Yes! It should not give you any problem at all.
            
  2. Can I write my own code from my own applications instead of browsers to subscribe for SocketPro HTTP push events?
    Of course! As described from this tutorial, you need to create two instances of HTTP requests. One is for sending request, and the other for waiting for available messages or a timeout.
            
  3. I saw this site. Should I use this HTTP server push technology or that one?
    That technology is dependent on plug-in for Mozilla browsers and activeX control for IE. It is completely dependent on the client core library npUSocket.dll. Therefore, you probably do not like that approach because it lacks probabilities of integration with other platforms or development languages. Also, you can distribute that dll with your applications on MS window platforms only. Therefore, its usage is limited. If you use our HTTP server push, there are no such problems. However, HTTP server push technology is slower with a limited number of features because of HTTP restrictions. If you use plug-in approach, it will be much faster with many more powerful features like requests batching, online compression/de-compression, and both asynchronous and synchronous computation as well as others.
            
  4. SocketPro HTTP service support multipart and server-sent event as described at the previous tutorial. Why don't you use them as a foundation for HTTP push implementation?
    These approaches are very dependent on browsers. For example, server-sent event is implemented with Opera only. Multipart approach can work with FireFox, Flock and Netscape only. The two approaches do not work with MS IE, Safari and AOL browsers at all. Therefore, we can not use the two approaches.
            
  5. As you have already known, AJAX may support cross-domain request. Don't we just use AJAX only?
    The approach is implemented with FireFox version 3 only. However, Mozilla recently removed the feature because its document specification is not stable yet. Therefore, we can not use it at this time.
            
  6. HTML 5 will support a set of HTTP server push technologies. SocketPro will use them to replace the current implementation?
    We know it, but we have to wait until major browsers support HTML 5. We may wait another five or ten years before major browsers implement HTML 5.
            
  7. How do you protect my SocketPro server from situations that my browsers crash, my client computers suddenly power off, or networks are dead for some unknown reasons?
    SocketPro core server library usktpror.dll has ways to transparently prevent these bad situations internally. You don't have to code for dealing with these bad situations at all.