A beginner's introduction to poe

xiaoxiao2021-03-06  60

What is poe, and why shop i use it? Review our daily written programs, you can find that most of these programs have basic structures: start, perform a series of actions, then exit. Such programs can work very well for applications where users and their data do not need many interactions. Then, if you have encountered a complex task, I think you need a better program framework to understand the complexity of the task, complete this task. So the PoE (Perl object environment) came into being. PoE is a framework for building a Perl program to more naturally done tasks that need to be reactive to external data, such as network communication or user interface. The programs written by PoE are completely non-linear; you only need to create some small subroutines, and define how they call each other, then PoE will automatically switch between them according to the input output of the program. Speaking of now, you may have dizzy. If you are used to seeing the code to understand, then after reading a small example below, you will suddenly realize. Poe Design said that PoE is a small operating system is not exaggerated, it has its own kernel, process, inter-process communication (IPC), drive, etc. In fact, it is a simple system that constructs a series of status information. The following pairs of a simple description of each part of the PoE: The basic block of States PoE is state, it is some code that triggers execution when the event occurs. For example, the input data arrives, a session expire, a session passes a message to another session. Each thing in PoE is based on receiving and processing a wide variety of events. The kernel poe's kernel is very like the kernel of the operating system: it protects all your processes and data in the background, arrange your code trigger. You can use the PoE core to set alert to your process, control your status queue and other low-level services, of course, most of the time you don't have to interact with the kernel. Session in Sessions PoE is equivalent to a process in a real operating system. A session is a PoE program that is switched between states when it is running. It can create sub-sessions, pass information to other sessions, and so on. Each session can be used by calling the HEAP storage session unique data, which are available in each state in the session. PoE has a simple collaborative multitasking module; each session is executed in the same OS process and does not require any threads and processes. For such a session, you should pay special attention to the use of modular system calls in the PoE program. These are the most basic part of PoE, but you need a slight IE to explain some advanced PoE before we start the actual code. Drivers drives the PoE lowest level I / O layer. Currently, only one driver includes in the PoE installation - PoE :: Driver :: SYSRW, it reads and writes the data in the file handle. In any case, we don't need to use the driver directly. Filters filters, it is very useful in a certain aspect. The filter is a simple interface that converts data blocks from one format to another format. For example, PoE :: Filter :: HTTPD can transform each other between HTTP 1.0 Requests http :: Request object. PoE :: Filter :: Line can see the data stream to convert into serialized data lines. Wheels W Heels contains a reusable advanced logical part of the daily task. They are a method of PoE encapsulation useful code. In PoE you need to process the Wheels including event-driven input and output data and network connection creation. W Heels often uses filters and drivers to process and deliver data.

This description is too vague, the following code will give an example to illustrate this concept. The Components component is a session that is designed to be controlled to other sessions. Your session can handle commands and accept events there from them, this is very similar to the IPC communication through the real operating system. An example of a component is PoE :: Component :: IRC, an HTTP user agent implemented by a PoE-based IPC client interface, or PoE :: Component :: Client :: HTTP, an event-driven Perl implemented HTTP user agent. Components are also a very useful part of PoE. A Simple Example In this example, we will establish a daemon server that accepts TCP connections while printing an answer from the arithmetic problem submitted by its client. When someone connects its port 31008, it will print "Hello, Client". The client can submit an arithmetic expression that is submitted in a new line, and the server will return the answer to the expression. It's simple enough. There is no big difference between a traditional method of writing such a PoE program to write a daemon under a UNIX. We will have a server session to monitor TCP connections at port 31008. Whenever the arrival is connected, it will create a sub-session to process the connection. Each sub-session can interact with the user, and then dead after the connection is disconnected. All of this simply implements only a modular 72-line code is available. This program simply starts with the following code: 1 #! / Usr / bin / perl -w 2 Use strict; 3 Use socket QW (inet_ntoa); 4 Use PoE QW (Wheel :: SockeetFactory Wheel :: READWRITE 5 Filter :: Line driver :: sysrw; 6 Use constant port => 31008; This section we import the modules and functions required for scripts and define the constant values ​​of the listening port. The QW () statement behind "Use PoE" is imported into a lot of PoE :: modules. Now, this article is the coolest part: 7 new poe :: session (8 _Start => / & server_start, 9 _stop => / & server_stop, 10); 11 $ PoE_kernel-> run (); 12 exit; this is already a complete The program is! I established a server session and telling the PoE kernel to start the event and exits after the end of the event. (When there is no session that needs to be managed, the PoE kernel thinks that things are finished, but since we have intended to put the server session in an infinite loop, it will not withdraw from this hairstyle) PoE After "use poe;" H, automatically output the variable $ PoE_kernel to your name space. New poe :: session method call needs to explain. When you create a session, you will receive a list of events to the kernel. In the above code, this new session will be handled by calling & Server_Start, & Server_Stop events, and _stop events. Any event that is not received, but will be ignored by the session. _Start and _stop events are a special event for a PoE session. _Start event is the first thing to do when a session is created, when the session will be destroyed, the kernel notifies this session into the _stop state. Now, we have written a complete program, we also want to write status code to be executed when session runtime. Next, let's start with & server_start.

When the primary server session is created, it will be called when the program is started. 13 Sub Server_Start {14 $ _ [HEAP] -> {listener} = new poe :: Wheel :: SocketFactory 15 (Bindport => Port, 16 Reuse => 'YES', 17 SUCCESSTATE => / & access_new_client, 18 failureTate => / & access_failed 19); 20 Print "Server: Started Listening On Port", Port, "./N"; 21} This is a good example of the PoE state. First of all: See the variable $ _ [HEAP]? PoE has a special method to deliver parameters. The @_ array is packaged by many external parameters. External parameters include a reference to the current core, session, and status names, stack references, and others. We can use the special constants of PoE as this array index, such as HEAP, Session, Kernel, State, and Arg0 ~ Arg9 (parameters provided by the user). As with most of PoE's design, this arrangement can maximize the back compatibility and no sacrificial speed. The above example stores a socketFactory Wheel under the key value listen. PoE :: Wheel :: SocketFactory Wheel is one of the cooules in PoE. You can use it to create any stream socket (udp socket is not available) without having to worry about details. The above code will create a SocketFactory to monitor a new connection for a special TCP port. When the connection is established, it will call & accept_new_client to pass a new client, if there is an error in this, it will call & accept_failed, not let us handle the error. This is almost the same as PoE to do in the network. We store a WHEEL in the stack to prevent the finally elimination of the garbage collection mechanism in the status of Perl, - this method exists everywhere in each state of the session. Now let's look at the code of & server_stop status: 22 SUB Server_Stop {

23 Print "Server: stopped./N";

This paragraph does not need to be explained. The next thing we create a new session to handle each new connection. 25 sub accept_new_client {

26 My ($ Socket, $ Peeraddr, $ Peerport) = @_ [arg0 .. arg2];

27 $ peeraddr = inet_ntoa ($ peeraddr);

28 new poe :: session

29 _Start => / & child_start,

30 _Stop => / & child_stop,

31 main => ['Child_Input', 'Child_Done', 'Child_Error'],

32 [$ Socket, $ Peeraddr, $ Peerport]

33);

34 Print "Server: Got Connection from $ Peeraddr: $ peerport. / N"; 35} When the client successfully established a connection with the server, our PoE :: Wheel :: SocketFactory will call this subroutine. We convert the socket address to an adult readable IP address and build a new session to communicate with the client. This is very similar to the previous PoE :: session constructor, but there are a few points to explain. @_ [arg0 .. arg2] is a shortcut to $ _ [arg0], $ _ [arg1], $ _ [arg2]). You will see a lot of such array slices in the PoE program. Look 31 lines: It seems a bit strange, in fact, this is a very smart abbreviation. It can be rewritten with the next relatively long method: New PoE :: session

...

Child_Input => & main :: Child_Input,

Child_done => & main :: child_done,

Child_ERROR => & main :: child_error,

...

); This is a convenient approach to write a lot of status names, these names are the same as the name of the event. - You can pass the package or object as a key, or an array reference to any subroutine, method name. You can get more information about PoE :: session. Finally, in the PoE :: session constructor parameter list The last array reference is the list of parameters we have to pass to the _start status. If PoE :: Wheel :: SocketFactory creates a problem when creating a listening port or accepts a connection, the following occurs: 36 sub accept_failed {

37 my ($ function, $ error) = @_ [arg0, arg2];

38 delete $ _ [HEAP] -> {listener};

39 Print "Server: Call to $ function () failed: $ error. / N";

40} The print error message is a normal processing method, but why should we remove SocketFactory Wheel from the stack? The answer is the way PoE management session resources. As long as the session can produce and accept events, it is considered to be active. If there is no Wheel, the PoE core will consider the session is dead and collect resources for sessions. The only way to get the event is from SocketFactory Wheel, if it is eliminated, the PoE core will wait until all its sub-sessions end, collect all occupied resources. At this point, since there is no remaining session needs to be executed, the PoE kernel will end and exit. So, basically, this is the most common way to end the PoE session: End all session resources, let the kernel's rest. Now let's talk about the details of the child session. 41 SUB Child_Start {

42 My ($ HEAP, $ Socket) = @_ [Heap, Arg0];

43 $ HEAP -> {readwrite} = new poe :: wheel :: readwrite

44 (Handle => $ Socket,

45 Driver => New PoE :: Driver :: sysrw (),

46 Filter => New PoE :: Filter :: line (),

47 InputState => 'CHILD_INPUT', 48 ERRORSTATE => 'Child_ERROR',

49);

50 $ HEAP -> {readwrite} -> Put ("Hello, Client!");

51 $ Heap -> {peername} = join ':', @_ [arg1, arg2];

52 Print "Child: Connected to $ HEAP -> {peername} ./ n";

53} Whenever the new sub-session is created to handle the latest connection client, the code above is called. Here we have to introduce a new PoE Wheel: Readwrite Wheel, which is a Wheel that drives the I / O task by an event. We pass it to the file handle, a driver, a filter, and more. Next, whenever the new data arrives at the file handle, the WHEEL will send a child_input event to the session. If any error occurs, a child_ERROR event will be sent. We understand this new WHEEL to output strings "Hello, Client" to Socket. Finally, we store the client addresses and ports in the stack, and print successful information. We omit the status discussion of Child_Stop. It only has a line of length. Now we look directly at the main Child_INPUT program. 57 SUB CHILD_INPUT {

58 My $ DATA = $ _ [arg0];

59 $ DATA = ~ Tr {0-9 * / () -} {} cd;

60 Return Unless Length $ DATA;

61 My $ Result = Eval $ DATA;

62 kHomp $ @;

63 $ _ [HEAP] -> {readwrite} -> PUT ($ @ || $ result);

64 Print "Child: Got Input from Peer: /" $ DATA / "= $ Result. / N";

65} When the client is sent to us, we get simple arithmetic expressions and EVAL it, then send the results or error messages to the client. Typically, the untrustful data sent by the client is very dangerous, so we must ensure that all non-numerical characters in the string are filtered out before EVAL. The sub-session will keep the data until the client is disconnected. All event-driven applications are a great place to use PoE. Source code: http://www.perl.com/2001/01/poE-math3.pl

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

New Post(0)