ASP. NET implements HTTP long connection push

Source: Internet
Author: User
Tags log4net

Say the latest help a friend to make smart home things, do a cloud platform. The main function of the mobile phone in the external environment of the mobile phone client and the Intelligent Gateway command forwarding each other.

There is now a stable socket version, but considering the future expansion and performance indicators to change to the HTTP long connection form, this is really a very interesting scenario.

The following is the concept of a long-term HTTP connection, so-called long-term HTTP connection is not the same as the socket to establish a connection between the client side and the server to pass data back and forth. An HTTP long connection means that the HTTP request sent to the server by the client does not immediately get a response from the server, but that the server "proactively" returns the data to the client when certain conditions are met, when an HTTP request is completed. In practice, the client often has to establish a long connection after the end of a long connection, that is, the client-to-server side always maintains an open downstream HTTP channel.

The students who have done the socket know that the socket communication in addition to their own protocol to have a heartbeat command, in order to ensure that the client and server-side connection status. This article does not go into the drill, mainly the long connection of this small framework.

The code is our best companion, and below we combine the code to say this simple thing.

Many asynchronous features are added to the asp.net4.0, and IHttpAsyncHandler with IAsyncResult can be a good solution to the requirements of this article. First we define a class implementation IAsyncResult this interface

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingsystem.web;usinglog4net;namespacesm.bizkeepalivehttp{/// <summary>    ///an asynchronous session, the session is temporarily cached/// </summary>     Public classHkasyncrequest:iasyncresult {Private Static ReadOnlyILog logger = Logmanager.getlogger (typeof(hkasyncrequest));  PublicHkasyncrequest (HttpContext context, AsyncCallback CB,Objectextradata) {             This. Context =context;  This. CallBack =CB;  This. Extradata =Extradata; }         PublicHttpContext Context {Get; Set; }         Public ObjectExtradata {Get; Set; }         PublicAsyncCallback CallBack {Get; Set; }         Public BOOLiscompleted {Get; Set; }         Public Objectasyncstate {Get; Set; }         PublicSystem.Threading.WaitHandle AsyncWaitHandle {Get; Set; }         Public BOOLcompletedsynchronously {Get{return false; } }         Public voidSend (stringresponse) {            if(String.IsNullOrEmpty (response))return; Try            {                 This. Context.Response.ContentType ="Text/plain";  This.                Context.Response.Write (Response); if( This. CallBack! =NULL)                {                     This. CallBack ( This); }            }            Catch(Exception ex) {logger. Error ("An error occurred in the output to the client:"+Ex.            Message); }            finally{iscompleted=true; }        }         Public voidSend (byte[] B,intOffsetintlength) {            stringstr =func.bytearraytohexstring (b);  This.        Send (str); }    }}

This class is not difficult, mainly to save the external HttpContext, AsyncCallback and Extradata,httpcontext used to write responses to the response, AsyncCallback used to end the current HTTP long connection request, extradata What to do I didn't use it. It is important to note that the CompletedSynchronously property in this class returns false, otherwise the client cannot receive the data. Also, do not return null for each property, otherwise the error of the null pointer will be reported when writing response.

Let's look at the implementation of the other interface. Create a new generic handler (. ashx) file in your project. Implement the Iasynchandler interface:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingsystem.web;usinglog4net;usingNewtonsoft.Json.Linq;namespacesm.bizkeepalivehttp{ Public classData:ihttpasynchandler { Public Static ReadOnly stringDATAFIELD ="Data"; Private Static ReadOnlyILog logger = Logmanager.getlogger (typeof(Data));  PublicIAsyncResult BeginProcessRequest (HttpContext context, AsyncCallback CB,Objectextradata) {context.            Response.Cache.SetCacheability (Httpcacheability.nocache); stringValue =context.            Request.Params.Get (DATAFIELD); //Here's the SessionID, not the data, the data don't repeat the parse//use SessionID to find the corresponding session in the cache and populate the asynchronous AsyncResultHkasyncrequest result =Newhkasyncrequest (Context, CB, Extradata); stringError =NULL; if(String.IsNullOrEmpty (value)) {Error="SessionId is null"; Context. Response.statuscode= -; Logger.                Error (Error); Result.                Send (Error); returnresult; } List<AliveClient> ACS = AsyncManager.Sessions.FindAll (x =x.sessionid.equals (value)); if(ACS = =NULL|| Acs. Count = =0) {Error="404 SessionId:"+ Value +"has no connection."; Context. Response.statuscode=404; Logger.                Debug (Error); Result.                Send (Error); returnresult; } aliveclient AC=ACS.            First (); Ac. Result=result; //Execute CommandCommondfactory.executecommond (AC); returnresult; }         Public voidendprocessrequest (IAsyncResult result) {} Public voidProcessRequest (HttpContext context) {} Public BOOLisreusable {Get            {                return false; }        }    }}

One of the main implementations of this class is the BeginProcessRequest, which is the other way to write no code. The main function of this method is to set up a IAsyncResult instance and save it, so that the data will be returned to the client after the server side has the data or satisfies the specific situation. So I built a static list cache in the code to save these IAsyncResult implementations. This is, of course, the core of the HTTP long-connect implementation of ASP.
Others do not say more, we can see the source code, When you look at the code, you will find that I actually set up two. ashx files, which is related to the logic of my project, because the protocol specifies that the client sends a data message immediately after the server responds, so I respond with a traditional ashx and respond to this traditional ashx ( CONNECTION.ASHX) First analyze the data to save the analyzed data model, and give the client a SessionID. After the client receives the response and uses this SessionID to initiate a long connection request, the server side will not repeat the analysis of the data, but the previous data from the cache to use, for debugging convenience I wrote this SessionID dead. At the same time I used quartz.net to build two tasks, a CleanJob.cs is actually as a cleanup task, scheduled to clean out the cache of invalid or completed requests 5 minutes to run once. Another task is that HeartJob.cs is primarily used to simulate server-side push logic, running once in 30 seconds.

The use of quartz.net is because I personally think that the way to start BackgroundWorker directly in ASP is not very good or that the scheduling engine's threading model is more reliable. The code to start the dispatch engine specifically is in Global.asax.

The attachment is I stripped out of the code, removed the business section only for testing purposes. The test interface for Index.aspx, write something in the text box point to submit, first received a response from the server after each 30 seconds received the response of the Server Popup alert window. The point here is that the client JS code after receiving a long connection feedback immediately after the establishment of a long connection, this is the key.

Source

ASP. NET implements HTTP long connection push

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.