⬆️ ⬇️

Multithreaded web server for 1C: Enterprise using .Net Framework

In the process of automating an enterprise using 1C: Enterprise often

there are problems of integration and exchange with equipment and other third-party information

systems, for example, banks, websites, partner information systems.

Traditionally, 1C: Enterprise acts as a consumer of services, and less often - as

provider. Up to this point, the developers of popular technologies in obtaining

Information from 1C was COM and web services, which appeared only in version 8.1.



Both technologies (COM and web services) have their drawbacks. The main disadvantages are

in the following. COM technology allows you to perform only one at a time.

request. Circulation is possible only within your local network. Simultaneous processing

queries for COM is possible, but requires the costs of connection pooling and debugging

multi-threaded application. Web services are complex and inflexible to program:

tightly bound to SOAP standards. Connecting devices sharing simple

packages that use the http protocol are not possible.



The new idea of ​​organizing a web server within 1C, proposed in the article, is based on

time-tested rich functionality. Net Framework. Solution based on

ideas are free from the disadvantages of COM and web services 1C. Compared to the COM http server you can

use outside the local network; simultaneous processing of several

requests. Compared to web services 1C solution based on http-server has

more flexibility, because the programmer is free to choose the server response format

(including HTML, JSON, graphics, RSS, etc.), as well as control

when answering the URL, user identification, error codes, cookies, encoding,

implement caching. Setting the same http-server inside 1C is reduced to a simple

launching external processing.

')





Example Description





The example attached to the article consists of two files: http-server (external processing

1C 8.2 HttpServer82) and a test application emulating simultaneous requests to the server

(external processing 1C 8.2 TestHttpServer82). Both treatments are based on managed

forms. By default, both applications are configured to work with port 8082.



Server and test application developed on 1C: Enterprise 8.2 and use .Net

Framework 4.0 and the Elisy .Net Bridge 4 component. Accordingly, for the example to work

Requires installed .Net Framework 4.0 and version of the Elisy library .Net Bridge

v.4.0.2.0 and higher. Elisy .Net Bridge allows harmonious use of classes and technologies.

.Net Framework on 1C, the leading role leaving 1C.



To check the work, it is enough to launch external processing of HttpServer82.epf from 1C: Enterprise

8.2. If you have Windows with UAC enabled, then you need to run 1C: Enterprise

under the administrator, otherwise the application will not have enough rights to listen

requests.



External processing allows you to specify the port on which to listen

and the number of threads created to handle simultaneous requests. Default set

port 8082 and 50 streams.



After pressing the Start button, the server goes to a working state and carries out

processing requests to a given port. For example, you can now refer from your

browser at localhost : 8082 and open

page returned by the server. In the request, you can pass parameters, for example,

like this: localhost : 8082 / test? x = 1



To test the server in multi-threaded mode, an external processing was created TestHttpServer82.epf,

which executes simultaneous queries in a loop. The basis of processing for

organization of parallel work put a great technology PLINQ (Parallel

LINQ) of .Net framework 4.



Test processing of TestHttpServer82.epf should be started from a separate server.

of 1C: Enterprise session, otherwise simultaneous launching of two treatments in one session

will cause a hang. The test case parameters are the request address,

the number of simultaneous requests and the number of cycles. By default, running the algorithm will result in

to 3 cycles of visits to the address localhost : 8082

with 20 simultaneous requests (it should be noted that the number of simultaneous requests is limited

number of processor cores).



Principle of operation





The .Net framework offers to its developers the HttpListener class, which is responsible for listening to the http protocol. Using HttpListener,

You can create an HTTP traffic listener that responds to http requests.

You can use this class only on Windows XP SP2 operating systems.

or Windows Server 2003 and up. Attempt to use class on earlier systems

will cause an exception.



Below is a sample code for 1C, which initializes an object of type HttpListener,

configuring it to listen on all URLs on port 8082. When running in 1C, work

the program pauses until a request is made for a port, for example, from a browser.

As soon as you send a request from the browser, for example, 127.0.0.1 : 8082 / 1C will return the html-string described in the program.



What each piece of code is responsible for can be understood from the comments provided

inside the source code.



("Elisy.NetBridge4"); AddIn = New("AddIn.ElisyNetBridge4"); net = AddIn.GetNet();   net.GetStatic("System.Net.HttpListener","IsSupported")  ("  HttpListener   Windows XP SP2/2003  "); ; ; listener = net.New("System.Net.HttpListener"); listener.Prefixes.Add("http://*:8082/"); listener.Start(); ("..."); // GetContext      . context = listener.GetContext(); request = context.Request; //    response = context.Response; //   - HTML- responseString = "  HttpListener"; buffer = net.GetStatic("System.Text.Encoding", "UTF8").GetBytes(responseString); //        . response.ContentLength64 = buffer.Length; output = response.OutputStream; output.Write(buffer,0,buffer.Length); //        output.Close(); listener.Stop(); 




This is the simplest example. The main point of the simplest example is that 1C turns

into a full-featured http-server, and 1C-programmer gets a tool for flexible

response settings from the server. He can return it in any format (html, drawing

or JSON), request user identification, or return an error altogether. But

however, there are drawbacks: blocking the entire application, processing only one

request. The example for the article contains more complex code, due to which disadvantages are eliminated

the simplest example from listing.



From simple to complex





The finished example included a modified code for working with HttpListener, in which the call

the listener.GetContext () method has been replaced by a call to asynchronous analogs listener.BeginGetContext ()

and listener.EndGetContext (). In addition, N separate threads are created and laid.

synchronization between threads with a call to the request-code-processing request on the 1C: Enterprise side.



The advantage of the proposed implementation of the http-server is the possibility of simultaneous

processing N requests in different threads with transfer of processing logic to the form method

1C: Enterprise. The example at each request returns html with the description of the source

and the request URL. The solution is very flexible, since all improvements can be made directly from

configurator 1C. No additional projects (for example, C # or VB.Net) are involved.



The example can be divided into 2 parts: the code that runs on the 1C: Enterprise side

and code that runs on the .Net framework side. At the same time, the .Net framework took

everything that cannot be implemented using 1C: Enterprise, for example, creating

and thread synchronization.



Http server is designed as a managed form. Pressing the Start button occurs.

creating objects of the HttpServer and Helper classes. Both classes are described in C # in the layout.

Processing Source Code and compiled "on the fly" in the handler of the Open Form.

The Helper class is responsible for redirecting .Net events to the Edit Request function.

on the form 1C and the formation of an error message.



Omitting non-subject initialization tasks of the form and auxiliary classes,

it is necessary to dwell on the Process Request method, which is responsible for returning the result

http client The handler from the class Helper is called, takes as a parameter

context object may return an error message that will be returned

to the client.



The context object of the HttpListenerContext type, passed to the ProcessEquery method

contains two important properties: Request and Response, responsible for information about the request

and answer accordingly.







The Request property allows you to get the parameters and contents passed by the client.

upon request. Request information placed in the Request property contains such

Basic properties like:



AcceptTypes - client-supported MIME types

ContentEncoding - encoding information in response

Headers - a set of headers

HttpMethod - client-defined HTTP method

InputStream - a stream containing body data from the client

IsAuthenticated - a boolean value indicating whether the user is identified

IsLocal - value indicating whether the request is local (via localhost)

QueryString - query string from query

RawUrl - URL information without a host and port

UrlReferrer - resource URL - source of the transition

UserAgent - information about the user's browser agent



Through the Response property, content is returned to the client, information is transferred

error or redirection. All can be accompanied by exhibiting the necessary

headers. Many properties of the response (Response) are similar to the properties of the request. Significant

among them are the following:



ContentEncoding - encoding information in response

Headers - a set of headers

OutputStream - the stream to which the response will be written (for example, the text Html, XML or

image byte array)

RedirectLocation - the property is responsible for the HTTP Location header and allows you to redirect

call

StatusCode - status code when returning to the client, for example: 200 (OK), 404 (the resource is not

found)

StatusDescription - status description when returning to the client







The following method code, Process, Request, converts the generated string Result to HTML

with the html code in the byte set and writes this byte set to the output stream, which

will be returned to the customer. The link to the output stream is obtained through the method parameter.



  = context.Response;  = net.GetStatic("System.Text.Encoding", "UTF8").GetBytes(HTML); .ContentLength64 = .Length;  = .OutputStream; .Write(, 0, .Length); .Close(); 




The processing is based on the HttpServer class, which creates an HttpListener object.

and the required number of threads to process. When you call the Start method, it starts

all handler threads and a separate thread for HttpListener to work. Thanks

you can continue to work with 1C while the http server is running. Upon enrolment

the HttpListener request puts the request in a queue, where each request is sequentially

processes the first free stream. When processing a thread, a call chain is triggered:

event HttpServer.ProcessRequest, Helper event handler. HttpServer_ProcessRequest,

1C-function Form. Edit Request. C # code class HttpServer when running 1C from the layout

Source Code is compiled on the fly.



 _listener.AuthenticationSchemes = authenticationScheme; _listener.Prefixes.Add(String.Format(@"http://+:{0}/", port)); _listener.Start(); _listenerThread.Start(); for (int i = 0; i < _workers.Length; i++) { _workers[i] = new Thread(Worker); _workers[i].Start(); } 




The start of receiving requests occurs in the HandleRequests method until processing

will not be terminated by the user. When a request is received, the request is passed to the method

ContextReady and the listening process continues.



 private void HandleRequests() { while (_listener.IsListening) { var context = _listener.BeginGetContext(ContextReady, null); if (0 == WaitHandle.WaitAny(new[] { _stop, context.AsyncWaitHandle })) return; } } private void Worker() { WaitHandle[] wait = new[] { _ready, _stop }; while (0 == WaitHandle.WaitAny(wait)) { HttpListenerContext context; lock (_queue) { if (_queue.Count > 0) context = _queue.Dequeue(); else { _ready.Reset(); continue; } } try { ProcessRequest(context); } catch (Exception e) { Console.Error.WriteLine(e); } } } 




Conclusion





Multithreaded server, described in the article, for ease of configuration and functionality

surpasses the traditional methods of access from the outside to the information databases of 1C: Enterprise

8.x. This is a simple start-up method that allows you to simultaneously process several

requests. At the same time, the 1C application is not blocked, and the user can continue

work after starting the server.



The main advantage of the proposed approach is complete control of the programmer.

process from receiving a request to form a response. For example, at the stage of obtaining

request, you can parse the URL, get information on how to identify yourself

user, as well as complete customer information (supported languages, recorded

cookies, headers, access method). The answer can be returned to almost anyone, starting

error 404 Not found, ending with different graphic formats, Word formats,

Excel and popular XML based formats (JSON, HTML, RSS).



The example attached to the article is designed so that its functionality can be

easy to expand. For example, to organize the cache, use System.Web.Caching.Cache

class from .Net framework. When parsing a URL, try working with the RouteCollection class.

from Asp.Net MVC. When creating an RSS feed, the System.ServiceModel.Syndication class will help you.

.SyndicationFeed. And with Json serialization, notice the System.Runtime.Serialization.Json.DataContractJsonSerializer class.



Specifically for the proposed approach at the moment there are no obvious shortcomings.

There is a possibility that, due to its limitations, 1C: Enterprise will not be able to provide

on its side, proper parallelization and a significant increase in performance.

Nevertheless, experiments conducted earlier for 1C: Enterprise 8.2 showed that in similar

the use of 1C achieved an increase in productivity, and 1C works at the same time

stable



It is necessary to draw the attention of developers for a few moments. Any publication

Information on the Internet is associated with the risk of hacking, regardless of the method of publication.

But in the proposed method due to the flexibility there are more opportunities to resist

threats from the outside. For example, in the request, the client’s IP address is now available;

block by some rules (by searching the blacklist locally or

in specialized services). Query parameters are available as strings and can be

analyze on the side of 1C or .Net framework and block dangerous content.

In addition, there are several specialized .Net libraries available to solve.

This problem that can be brought into 1C, for example AntiXSS.



The second point is that the well-known methods, including this one, of providing

1C services are not intended for mass calls and will always be inferior

from this point of view, professional servers such as IIS.



Examples for the article:



HttpServer82.epf (11.50 kb)



TestHttpServer82.epf (8.30 kb)

Source: https://habr.com/ru/post/163859/



All Articles