Automatic transmission function for realizing voting results using Windows service

xiaoxiao2021-03-06  63

Abstract: When using the Microsoft Visual Studio .Net 2003 design voting system, we hope that the voting system can provide some extension features. . This article discusses the design, implementation, and problems that the voting results automatically send function, and problems needed during this process

Keywords: Microsoft Visual Studio .NET 2003, Borland C Builder, Windows Service, Voting System, Automatic Send

First, the overall analysis

Let's take a look at the work scene of the voting system to answer the design and implementation issues. Suppose there is a web page-based voting system developed by Microsoft Visual Studio .NET 2003, a company should vote on the year-end evaluation, and each employee can vote after logging in to the vote. Administrators specify the title and content of the vote when creating the voting project, optional items, deadline, and administrator's email address. After the server time arrives at the shutdown time of the voting item specified by the administrator, the employee will not vote via the web page, while the server sends the voting result in the form of an email to the administrator.

Based on the above-mentioned working scenarios, we can understand that the basic processing logic of the use of web applications [1] is not difficult, but to implement the automatic transmission function of the result, it cannot just rely on the web application. From the work of the voting system, handle the addition, deletion, modification, and voting of the new voting project. You can directly hand it over to the B / S mode web application through the page view voting results through the page. The Web Server makes the request to complete the corresponding processing. After completing the client's request, the server feeds the processing results to the client; however, the auto-send function of the voting result is different, it needs such a way to work: Long time Keep memory, always monitor whether the system time has arrived at the voting project deadline specified by the administrator. If the condition is eligible, the results of the vote are automatically sent to the specified mailbox address.

Obviously, the web application is unable to win such a way of working, we choose a Windows service to implement such functions. Windows services can be automatically started when the computer is started, and standing in the latter execution, the administrator can also suspend or stop Windows services when necessary. MMC's service management unit provides a central location for managing Windows services.

Second, detailed analysis and design

For the convenience of describe, here we divide the design into two parts: internal design and external design.

If the Windows service that automatically sends a function of the voting result is called the voting result processing server, the web application used to implement the basic logic of the voting system is called the vote system, then internal design means the design of the voting result processing server internal processing logic. And the main task of external design is to complete communication design between the voting result processing server and the voting subsystem.

1, internal design

We should clearly see the way the voting result is working inside the server: When the server is started, the information of the voting project will be automatically read into memory, then enter the loop, read every other time (such as 5 seconds) If the voting project is judged, if the voting item expires, the results of the voting result are statistically sent out.

The first thing to solve is the data storage problem, that is, the data structure problem. The voting project is saved in the form of database records, then should it be stored in one of the data structures? Solving this problem requires a way from the server. Obviously, the voting item in the database is more than one, because the administrator has different options for the processing of the voting result (you can choose to automatically send the result function, you can do not choose this), this is determined in more There may only be part of the voting project to be sent to the results. In addition, each voting project records multiple fields, such as the ID number, voting content, deadline, etc. of the voting project, which constitute the entity of the voting result, is the main component of the required sends information. We can consider using structural arrays to store these voting project records, such as: typedef struct t_voteItemInfo {

INT ID; // Vote ID domain

String Title; // Title domain of the voting project

String name; // Voting project name domain

//.

TDATETIME VOTEDEADLINE; / / The deadline for the voting project

} Voteiteminfo;

Typedef voteiteminfo voteiteminfoarray [max_size];

However, we cannot determine how much the voting project in a certain minute is, and it is not possible to determine how much records are sent to the results in all voting project records, which makes it difficult to determine the max_size in the above code. Value, if the value of max_size defines too small, it may cause the voting project to read the memory one-time. If necessary, there is a need for a special exchange-replacement algorithm to replace the data in the array, which is very troublesome If max_size defines too much, it may cause waste of storage space, and the voting result processing server is a resident memory Windows service, and a large amount of space is built will affect the performance of the server.

As can be seen from the above analysis, the array is not the best way to store the voting project record, where we introduce the queue, use a one-way queue (that is, a one-way linked list) to store vote project records. C STL library provides good opportunities for us to define such data structures, the following code is easy to implement such definitions:

#include

Using namespace std;

Typedef struct t_vi {

INT ID; // Vote ID domain

String Title; // Title domain of the voting project

String name; // Voting project name domain

//.

TDATETIME VOTEDEADLINE; / / The deadline for the voting project

} Voteinfonode;

TypeDef Queue voteinfoqueue;

Second, let's specifically analyze the way of judgment of the interior of the server on the voting project. Since the information provided and the selection of the administrator is required to save, the shutoff of the voting item (or the expiration time) is saved in the database in the form of the record field. When the server reads the voting project queue, the deadline of the voting project will become a domain of the queue node and load memory so that if a certain time server discovery queue has an expired time, then it can be easily It is very easy to determine other voting items, organizations, and generated and send voting projects associated with the expiration time.

Suppose that there is N nodes in a certain time voting project queue (N of the values ​​are enough), then it is necessary to judge which node that has expired is a fee, such as we can traverse each node in the queue to judge, but This will occupy a certain processing time because a loop is required (this algorithm complexity is O (N)). On the other hand, the server program needs time to observe the data in the queue in order to find an expired node in time, which determines the traversal cycle of the server program can't be too long. Now, the server program traverses the queue every 0.5 seconds. If the traversal queue has time consuming more than 0.5 seconds, it is possible to find an expired project, because in the case of a travers, the server program has entered it. A traversal cycle. Obviously, there is a contradiction, on the one hand, the server needs time to scan the voting project queue. This determines that the scanning process cannot be too hot; on the other hand, if the number of nodes is large enough (for example, it is more than 1000000), this has decided that the scanning process will be very consumed. Time. Since the voting result processing server is a resident memory Windows service, this determines that the server cannot occupy too much processing time, otherwise it will affect the performance of the entire server even the entire computer system. Solving such contradictions need to start from the attributes of the queue itself. The queue is the data structure of the FIFO. If the node D expires at T, then the information can be transmitted to the information, and then the D is set, so that it can save space or save time. Further, we can sort all records before building a voting project queue, ranking projects with small shutdown time in front, with such a queue created: the earliest expired project The most in front. This is very important because if the front guide node in the queue has not expired, then the subsequent node is certainly not expired.

Figure 1 has no expiration, and its subsequent node is certainly not expired.

After using such a processing method, the server program can complete the processing as long as the first node of the queue is periodically, if the first node expires, then processes the first node, then the first node is out of the team, and its subsequent node is the first node, and enter Judgment of the next round (this algorithm complexity is O (1)).

The following pseudo code describes this process in detail:

/ / This function is executed every time interval (Timer Interval)

Void __fastcall processtimer_ontimer (TOBJECT * SENDER)

{

IF (queue is not empty)

{

TmpNode = Queue .front (); // Get the queue head node

IF (TmpNode. Expired

{

Queue.POP (); // node out of the team

Return;

}

Else IF (TmpNode. Expiration time = Current time) // How to expire

{

Send TMPNODE information in the form of mail;

Queue.POP (); // node out of the team

}

}

}

In addition, since the voting project information is saved in the database, the sorting of the data can be used using the SQL query statement before constructing the voting project queue, for example:

Select * from t_voteItems Order by votedeadline ASC

The design of two core parts of the voting result processing server is described above: data structure and expired judgment processing. Now discuss the characteristics of the server program itself and its related design.

a, log

The server program is running in the background, which cannot display instant information on the screen, so you need to use the log. The log is such a file that records the entire process and output information of the server run, and the write time and state of the information, so that the time and cause of the error occurred when the server program is not working properly. When multiple server programs share the same log file, a message must be recorded in a log file to which server is written; if the server program has its own independent log file, such information can be omitted. A.1 write to the log file

Usually use the variable paragraph function of "INT WRITELOG (INT LEVEL, CHAR * FMT,....) To implement the write to the log file. The variable paragraph function is mainly implemented va_list variables and related VA_START, VFPRINTF, and VA_END functions associated therewith, and the specific content can be referred to the MSDN-related documentation. It should be noted that: 1 Implementation of the variable paragraph function in the UNIX system is slightly different from the Windows system; 2 log files need to be opened with "A " (add), otherwise it is possible to write only a recently generated log information.

When writing a server program, you should call the WRITELOG function in a reasonable place to complete the write to the log, for example, using the WRITELOG function in TRY.. .Catch block:

Try

{

//.

}

Catch (Exception & E)

{

Writelog (Loglev_err, "Error Information =% S / N", E.MESSAGE.C_STR ());

}

A.2 management of log files

The log file records the entire details of the server. Each time a server program is running, there will be a large amount of information written to the log file. After a while, the size of the log file will reach several tens of megaby, and even the entire hard disk space, resulting in server system Crash. Therefore, when designing server programs, the log file should be processed according to the server's mission. For example, quickly and accurately locate an error message in a log file to find an error source, which is very important for the mission-critical server system, which generally needs to back up the log file, and this can also be implemented by design additional log management systems. For a general server program, in the case where the stability requirements are not very high, we can choose to directly rewrite the log files. When the design voting result is handled, we have selected such a log processing.

The backup of the log file can be implemented with a separate module or directly in the WRITELOG function. Before writing logs, first determine the size of the log file, if it is greater than the specified size, copy the log file and open the log file with "W" (overwriting) and write the log; otherwise use "a " directly. (Add) Open the log file.

b, configuration file

For server programs, profiles are very important. The configuration file saves many server programs running, and the server program reads the configuration file and applies the corresponding parameters at the specified time (typically starting). The configuration file in the server system will make the server program more flexible, so that the server program can better adapt to different demand environments. For example, if you write a mail server address to a configuration file, we only need to modify the configuration file and let the server program to apply the latest settings without modifying the server program code.

The configuration file of the Windows service is generally used in INI, which makes it easy to read and write profiles. In the design of the voting result processing server, we write the code of the configuration file parameters in the service startup function, so that the latest configuration parameters are applied each time the server is started. Similarly, if a certain time changes to the configuration file, you must restart the service if the server is applied to the latest configuration parameters. C, communication

In general, server programs need to communicate with external functions to provide services to the external function, which is often referred to as clients. There are a variety of communication between processes, such as shared memory, pipelines, signals, and sockets. In the voting system, we use Socket Communications to implement information notifications to the server program for web applications. .NET Framework's System.Net.Sockets Namespace provides classes for Socket communication, which makes communication between the voting subsystem and the voting result processing server. The following C # code implements information notifications for the voting result processing server:

Using system.net.sockets;

Using system.text;

Public Class VotingNotifier

{

Private int votingnotifierServerPort = 9023;

Private string votingnotifierSerRRHOSTNAME = "127.0.0.1";

Private string plain_text = "- = byteartvotingNotifier = -";

Public votingNotifier ()

{

//

// Todo: Add Construction Code Here

//

}

Public void sendnotifyMessage ()

{

Try

{

TcpClient Client = New TcpClient (VotingNotifierServerHostname, VotingNotifierServerport);

NetWorkstream ns = client.getStream ();

Byte [] bytes = new byte [1024];

Bytes = Encoding.ASCII.GetBytes (Plain_Text);

ns.write (bytes, 0, bytes.length);

Client.Close ();

}

Catch (Exception)

{

Return;

}

}

}

In the external design of the voting result, we will specifically discuss why the server needs such a communication function.

2, external design

The external design is mainly discussed with communication design between the voting subsystem and the voting result. The question we need to solve is why the voting subsystem is to communicate with the voting result.

In the internal design of the server program, we discussed the problem of data structure and expired judgment, and the method of solving the problem is to use an orderly queue. Obviously, the data in an orderly queue is not once loaded. It is likely that the data in the database has changed after completing the queue. Therefore, if the administrator uses the vote system to change Voting project data (such as increased or deleted), the server program should also rebuild an orderly queue accordingly. It can be seen that the server program needs to re-build an ordered queue in the following cases: 1 When the service is started, 2 When the voting project information is increased, 3 to delete the voting project information. For the latter two cases, the server program cannot know when the voting project information in the database changes. Considering the performance of the integrated server, we will not design a dedicated module for monitoring the voting project information in the server program, so it needs The voting subsystem to notify the voting result processing server. Figure 2 Vote subsystem and voting result processing server communication

The design of the communication function in the voting result is very simple. Borland C Builder provides powerful components for designing the Socket communication program. We don't discuss it. The pseudo code for implementing this feature is given:

Void __fastcall serversocket_clientread (TOBJECT * SENDER,

Tcustomwinsocket * Socket)

{

String txt;

// Get the received text

TXT = Socket-> ReceiveText ();

/ / If the text is obtained is Plain_Text

IF (txt == plain_text)

{

Rebuild an orderly queue;

}

}

It should be noted that the above PLAIN_TEXT is a notification information string that the vote subsystem and the voting result processing server.

Third, realize

We use Borland C Builder 5 to implement the voting result processing server. This part of the content includes: Developing a Windows Server using Borland C Builder 5 and transmits email using Borland C Builder 5.

1. Develop a Windows Server using Borland C Builder 5

Borland C Builder 5 provides convenience to developing a Windows service program. To develop a Windows service program using Borland C Builder 5, you can do it below:

l Start Borland C Builder 5

l Select New in the File menu

l Select the Service Application option under the New Items dialog box, then click OK

Figure 3 Borland C Builder 5 New Items dialog

The following is a brief introduction to the main properties and events of the TService class.

Ø DisplayName Property: Used to display the name of the service in the [Service] management unit

Ø StartType Properties: Setting up the service startup

Ø Password property: Set the password at the time of service startup

Ø AfterInstall event: call the event processing process after the service is registered

Ø AfterUnStall event: call the event processing after removal service

Ø BeforeInstall event: call the event processing before the first registration

Ø BeforeunInstall event: Call the event process before removing the service Ø onContinue event: After the service is paused in the [Service] Management unit, click Continue button to make the service continue to run, call the event processing process.

Ø Oncreate event: Call the event processing during the service instant data module, for example, you can initialize the database connection here.

Ø OnDestroy Event: Call the event processing process when the service release data module

Ø OnPause Event: When the service is suspended in the [Service] management unit, call the event processing process.

Ø OnShutDown event: call the event processing before the service is closed

Ø OnStart Event: When the service is started in the [Service] Management unit, call the event process process.

Ø OnStop Event: When the service is stopped in the [Service] Management unit, call the event processing process.

The designer should design the above incidents according to different needs. In the voting result processing server, ONCONTINUE, ONPAUSE, ONSHUTDOWN, ONSTOP and other events are mainly used.

2, use Borland C Builder 5 to implement email send

TNMSMTP components are provided in Borland C Builder 5 that can easily implement email transmission functions. The following code demonstrates the method of using TNMSMTP to implement email transmission, and the code is relatively simple, and the detailed comment is made, so there is not much notes.

Void __fastcall tform1 :: button1click (Tobject * Sender)

{

TNMSMTP * SMTP = New TNMSMTP (this);

SMTP-> Charset = "GB

2312 "

; // Set the character set

SMTP-> Host = "192.168.

100.200 "

; // mail server address

SMTP-> Subtype = mthtml; // Send in HTML

/ / Specify the sender address

SMTP-> PostMessagea-> fromaddress = "acqy@163.com";

SMTP-> PostMessagea-> fromName = "acqy"; // sender name

/ / Specify the recipient address

SMTP-> PostMessagea-> toaddress-> add ("acqy@hotmail.com");

SMTP-> PostMessagea-> Subject = "Subject"; // Specify the topic

/ / Specify the content of the mail

SMTP-> PostMessagea-> Body-> Add ("

HelloWorld! ");

Try

{

SMTP-> Connect (); // Connect the mail server

SMTP-> sendmail (); // Send a message

SMTP-> disconnect (); // Disconnect connection

}

__finally

{

DELETE SMTP;

}

}

Fourth, summary

This paper introduces the design of the voting system in the voting system, detailing the data structure, voting project expired judgment method used by the server program, and what should be considered when designing server programs. The article also introduces a brief introduction to the use of Borland C Builder 5 to implement Windows service, Socket communications, and email. Need to remind the reader to note that the general application is different, because the server program is a stand-up program of the resident memory, there should be more considerations to the overall performance and operability of the program, otherwise it is possible to cause The server does not work properly, and even directly affect the operation of the entire software system. [1] Voting system includes voting subsystems and voting results processing servers

转载请注明原文地址:https://www.9cbs.com/read-111506.html

New Post(0)