![]() |
Welcome to SIMPL Programming for Python
|
| Course content | Enter chat room | Send email
to mailing list |
Check calendar |
Lesson Overview |
This lesson is about using SIMPL within a CGI program.
We are going do things a little differently than we have in the previous lessons. We will still be sending various possible messages to a C receiver, just as in lessons #3, #4, and #6 however, the user front end will be provided for by a web browser running a small piece of HTML code. This HTML file contains a form which is processed to retrieve the type of message to be sent. This form processing is performed by a CGI script written in Python. When the value of the appropriate form key is determined, the corresponding message is then sent to the C receiver program for processing.
In short, we will be using the same C receiver program that we used in lessons #3, #4, and #6. Accordingly, the messages will also be the same. The HTML code will provide the user input capability and the CGI script will process that input and send the corresponding message to the C receiver. It is interesting to note that where the SIMPL messages originate is of no concern to the receiver program. So far it has received messages from a local Python program (lesson #4), via the tclSurrogate (lesson #6) and now via a CGI script (lesson #7).
Again, we recommend that you read the document readme.python which is located in the docs directory below the SIMPL root directory. Pay particular attention to the final section called "SIMPL in CGI Programs".
Note:Like lesson #6, we are going to run all of the programs on one host for convenience. This would not normally be the case. A more usual scenario would be that the browser would be running in some other location than the server. Moreover, the server would likely be sending its message via the CGI script to some other remote host running the receiver program. |
With this algorithm, we hope to demonstrate the following:
Note:Do NOT cut and paste the following code pieces. The scripts are available in the .../www directory for you to run directly. |
Let's quickly examine the HTML code. |
The following code can be found in the ../www/lesson7_cgi.html file.
| 1.<html>
2.<head> 3.<title>Python SIMPL CGI</title> 4.</head> 5.<body> 6.<H1><center>Python SIMPL CGI</center></H1> 7.<form name="tokens" method="post" action="http://localhost/cgi-bin/lesson7_cgi.py"> 8.<center> 9. <select name="tokens" size="3"> 10. <option selected>send message token type 10</option> 11. <option>send message token type 20</option> 12. <option>send message token type 30</option> 13. </select> 14. <br/> 15. <p> 16. <input type="submit" value="send message"/> 17. </p> 18.</center> 19.</form> 20.</body> 21.</html> |
| Lines 1-6 | are the usual HTML start code. |
| Line 7 | defines the form required and the CGI program that will process it. Notice the URL for the action to be taken upon submission of the form. It is http://localhost/cgi-bin/lesson7_cgi.py. The http is such that the server port will located. The localhost is such that the host that the browser is running on is selected. The cgi-bin is the directory where the server will find the CGI script to be run. Finally, the CGI script to be called is named lesson7_cgi.py. |
| Lines 8-18 | produce the required user front end. |
Now, let's examine the Python CGI script. |
The following code can be found in the ../www/lesson7_cgi.py file.
| 1. #! /usr/bin/python
2. 3. # required modules 4. import cgi 5. #cgi.test() 6. import wcsimpl 7. 8. def sendToReceiver(value): 9. sName = "SENDER" 10. rName = "RECEIVER" 11. 12. # attach a simpl name 13. retVal = wcsimpl.nameAttach(sName, 1024) 14. if retVal == -1: 15. toBrowser("name attach error " + wcsimpl.whatsMyError()) 16. return 17. 18. # name locate the receiver 19. receiverId = wcsimpl.nameLocate(rName) 20. if receiverId == -1: 21. toBrowser("name locate error " + wcsimpl.whatsMyError()) 22. return 23. 24. if value == "send message token type 10": 25. wcsimpl.packInt(10, wcsimpl.BIN) 26. wcsimpl.packInt(99, wcsimpl.BIN) 27. wcsimpl.packInt(999, wcsimpl.BIN) 28. wcsimpl.packInt(9999, wcsimpl.BIN) 29. elif value == "send message token type 20": 30. wcsimpl.packInt(20, wcsimpl.BIN) 31. wcsimpl.packFloat(3.1415, wcsimpl.BIN) 32. elif value == "send message token type 30": 33. wcsimpl.packInt(30, wcsimpl.BIN) 34. s = "We are the knights who say Neee." 35. l = len(s) 36. wcsimpl.packInt(l, wcsimpl.BIN) 37. wcsimpl.packString(s, wcsimpl.BIN) 38. else: 39. toBrowser("unknown choice") 40. return 41. 42. # send the message to the receiver 43. retVal = wcsimpl.send(receiverId) 44. if retVal == -1: 45. toBrowser("send error " + wcsimpl.whatsMyError()) 46. 47. #*************************************************************************** 48. 49. def toBrowser(str): 50. print "Content-type: text/html\n" 51. print "<HTML>\n" 52. print "<HEAD>\n" 53. print "<TITLE>%s</TITLE>\n" %("Python SIMPL CGI") 54. print "</HEAD>\n" 55. print "<BODY>\n" 56. print "<H1><center>%s</center></H1>\n" %str 57. print "</BODY>\n" 58. print "</HTML>\n" 59. 60. #*************************************************************************** 61. # operational part of the program 62. 63. # get the form parameters 64. form = cgi.FieldStorage() 65. 66. # check for a form 67. if not form: 68. # no form available 69. toBrowser("no form available") 70. else: 71. # process form parameter 72. key = "tokens" 73. if form.has_key(key): 74. value = form.getvalue(key) 75. # SIMPL send the chosen message to the receiver 76. sendToReceiver(value) 77. else: 78. toBrowser("no message type") 79. 80. # detach SIMPL name 81. wcsimpl.nameDetach() |
| Lines 4-6 | import the required modules. Note line 5; it is commented out but when it is uncommented it will dump information to the browser regarding the server being used. It can be very useful for debugging. |
| Lines 8-45 | define a function used to build the message and perform the SIMPL send to the C receiver. |
| Lines 9-10 | define the SIMPL names of the sender and the receiver. |
| Lines 13-16 | attach unique SIMPL name. |
| Lines 19-22 | SIMPL name locate the receiver program. |
| Lines 24-40 | build the message to be sent to the receiver. |
| Lines 43-45 | perform the SIMPL send to the receiver. |
| Lines 49-58 | define a function to send messages back to the browser. |
| Lines 64-81 | define an HTML form, retrieve the form key that determines the type of message to be sent to the receiver, and finally perform a SIMPL name detach. |
Let's examine the receiving program. Note: this is exactly the same receiving program used in Lessons #3, #4, and #6. |
The following code can be found in the ../src/receiver.c file.
| 1. /*
2. FILE: receiver.c 3. DESCRIPTION: This is a C simpl receiver. 4. Refer to lessons 3, 4, 6, 7. 5. USAGE: receiver 6. */ 7. 8. // include required headers 9. #include <stdio.h> 10. #include <stdlib.h> 11. #include <simpl.h> 12. 13. // define possible message structures 14. typedef struct 15. { 16. int token; 17. int var1; 18. int var2; 19. int var3; 20. } MSG1; 21. 22. typedef struct 23. { 24. int token; 25. float var1; 26. } MSG2; 27. 28. typedef struct 29. { 30. int token; 31. int var1; 32. char var2[34]; 33. } MSG3; 34. 35. int main() 36. { 37. char *me = "RECEIVER"; 38. char *sender; 39. char mem[1024]; 40. int n; 41. MSG1 *in1; 42. MSG2 *in2; 43. MSG3 *in3; 44. int *token; 45. 46. // perform simpl name attach 47. if (name_attach(me, NULL) == -1) 48. { 49. printf("%s: cannot attach name-%s\n", me whatsMyError()); 50. exit(-1); 51. } 52. 53. while (1) 54. { 55. // receive incoming messages 56. n = Receive(&sender, mem, 1024); 57. if (n == -1) 58. { 59. printf("%s: Receive error-%s\n", me, whatsMyError()); 60. continue; 61. } 62. 63. // set a pointer to the value of the message token 64. token = (int *)mem; 65. 66. // decide course of action based on the value of the token 67. switch (*token) 68. { 69. case 10: 70. in1 = (MSG1 *)mem; 71. Printf("token=%d var1=%d var2=%d var3=%d\n", 72. & nbsp; in1->token, 73. & nbsp; in1->var1, 74. & nbsp; in1->var2, 75. & nbsp; in1->var3); 76. break; 77. 78. case 20: 79. in2 = (MSG2 *)mem; 80. printf("token=%d var1=%d\n", 81. & nbsp; in2->token, 82. & nbsp; in2->var1); 83. break; 84. 85. case 30: 86. in3 = (MSG3 *)mem; 87. printf("token=%d var1=%d var2=%.*s\n", 88. in3->token, 89. & nbsp; in3->var1, 90. & nbsp; in3->var1, 91. & nbsp; in3->var2); 92. break; 93. 94. default: 95. printf("%s: unknown message token=%d\n", me. token); 96. } 97. 98. // reply to sender 99. Reply(sender, NULL, 0); 100. } 101. 102. return(0); 103. } |
| Lines 9-11 | include the required C header files. Note the inclusion of the simpl.h header file. |
|
Lines 14-20 | define the binary message that corresponds to token value 10. |
|
Lines 22-26 | define the binary message that corresponds to token value 20. |
|
Lines 28-33 | define the binary message that corresponds to token value 30. |
|
Line 35 | is the start of the program. |
|
Lines 37-44 | declare necessary local variables. |
|
Lines 47-51 | handle the simpl name attach. |
|
Line 53 | starts an infinite loop which awaits incoming messages. |
|
Lines 56-61 | receive the incoming messages. |
|
Line 64 | sets a pointer to the incoming message token. |
|
Lines 67-96 | deal with each message type based on the token by printing the various message components to the screen. |
| Line 99 | replies a null message to the blocked sender. This reply message could be anything at all but in the interests of simplicity, the reply message has been made null. |
The Makefile for the C receiver program. |
The receiver program must be compiled and linked before it can be of any use. Go to ../src and at the command prompt type:
make cleanThen type:
make installThis makes a new executable of receiver.c called receiver and puts it in ../bin .
Note:In order to run this Makefile, the shell variable SIMPL_HOME must be set so that the make can find the SIMPL header files and library. |
The Web Server. |
In order to continue with this lesson and be able to run the programs, the web server needs to be checked for certain configuration issues. Again, we recommend that you read the document readme.python which is located in the docs directory below the SIMPL root directory. Pay particular attention to the subsection called "Web Server".
As previously stated we are going to use the Apache web server. In order for Apache to perform as required, it may be necessary for Apache's configuration file to be modified. Let us say that that file is /etc/httpd/conf/httpd.conf. Let us also say that the html, cgi, etc. files accessed and used by Apache are located in subdirectories below /var/www. The following are some of the things that have to be set for the Apache server to be able to function correctly:
Let's run the programs. |
In order to run this lesson's programs do the following:
Summary |
Let's summarize what you should have observed in this lesson: